2 * Win32 debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
11 #include "wine/winbase16.h"
13 #include "stackframe.h"
14 #include "debugtools.h"
16 DEFAULT_DEBUG_CHANNEL(debugstr
);
19 /******************************************************************************
20 * WaitForDebugEvent (KERNEL32.720)
22 * Waits for a debugging event to occur in a process being debugged
25 * event [I] Address of structure for event information
26 * timeout [I] Number of milliseconds to wait for event
30 BOOL WINAPI
WaitForDebugEvent( LPDEBUG_EVENT event
, DWORD timeout
)
36 struct wait_debug_event_request
*req
= server_alloc_req( sizeof(*req
), sizeof(*data
) );
38 req
->timeout
= timeout
;
39 if (!(ret
= !server_call( REQ_WAIT_DEBUG_EVENT
))) goto done
;
41 if (!server_data_size(req
)) /* timeout */
43 SetLastError( ERROR_SEM_TIMEOUT
);
47 data
= server_data_ptr(req
);
48 event
->dwDebugEventCode
= data
->code
;
49 event
->dwProcessId
= (DWORD
)req
->pid
;
50 event
->dwThreadId
= (DWORD
)req
->tid
;
53 case EXCEPTION_DEBUG_EVENT
:
54 event
->u
.Exception
.ExceptionRecord
= data
->info
.exception
.record
;
55 event
->u
.Exception
.dwFirstChance
= data
->info
.exception
.first
;
57 case CREATE_THREAD_DEBUG_EVENT
:
58 event
->u
.CreateThread
.hThread
= data
->info
.create_thread
.handle
;
59 event
->u
.CreateThread
.lpThreadLocalBase
= data
->info
.create_thread
.teb
;
60 event
->u
.CreateThread
.lpStartAddress
= data
->info
.create_thread
.start
;
62 case CREATE_PROCESS_DEBUG_EVENT
:
63 event
->u
.CreateProcessInfo
.hFile
= data
->info
.create_process
.file
;
64 event
->u
.CreateProcessInfo
.hProcess
= data
->info
.create_process
.process
;
65 event
->u
.CreateProcessInfo
.hThread
= data
->info
.create_process
.thread
;
66 event
->u
.CreateProcessInfo
.lpBaseOfImage
= data
->info
.create_process
.base
;
67 event
->u
.CreateProcessInfo
.dwDebugInfoFileOffset
= data
->info
.create_process
.dbg_offset
;
68 event
->u
.CreateProcessInfo
.nDebugInfoSize
= data
->info
.create_process
.dbg_size
;
69 event
->u
.CreateProcessInfo
.lpThreadLocalBase
= data
->info
.create_process
.teb
;
70 event
->u
.CreateProcessInfo
.lpStartAddress
= data
->info
.create_process
.start
;
71 event
->u
.CreateProcessInfo
.lpImageName
= data
->info
.create_process
.name
;
72 event
->u
.CreateProcessInfo
.fUnicode
= data
->info
.create_process
.unicode
;
73 if (data
->info
.create_process
.file
== -1) event
->u
.CreateProcessInfo
.hFile
= 0;
75 case EXIT_THREAD_DEBUG_EVENT
:
76 event
->u
.ExitThread
.dwExitCode
= data
->info
.exit
.exit_code
;
78 case EXIT_PROCESS_DEBUG_EVENT
:
79 event
->u
.ExitProcess
.dwExitCode
= data
->info
.exit
.exit_code
;
81 case LOAD_DLL_DEBUG_EVENT
:
82 event
->u
.LoadDll
.hFile
= data
->info
.load_dll
.handle
;
83 event
->u
.LoadDll
.lpBaseOfDll
= data
->info
.load_dll
.base
;
84 event
->u
.LoadDll
.dwDebugInfoFileOffset
= data
->info
.load_dll
.dbg_offset
;
85 event
->u
.LoadDll
.nDebugInfoSize
= data
->info
.load_dll
.dbg_size
;
86 event
->u
.LoadDll
.lpImageName
= data
->info
.load_dll
.name
;
87 event
->u
.LoadDll
.fUnicode
= data
->info
.load_dll
.unicode
;
88 if (data
->info
.load_dll
.handle
== -1) event
->u
.LoadDll
.hFile
= 0;
90 case UNLOAD_DLL_DEBUG_EVENT
:
91 event
->u
.UnloadDll
.lpBaseOfDll
= data
->info
.unload_dll
.base
;
93 case OUTPUT_DEBUG_STRING_EVENT
:
94 event
->u
.DebugString
.lpDebugStringData
= data
->info
.output_string
.string
;
95 event
->u
.DebugString
.fUnicode
= data
->info
.output_string
.unicode
;
96 event
->u
.DebugString
.nDebugStringLength
= data
->info
.output_string
.length
;
99 event
->u
.RipInfo
.dwError
= data
->info
.rip_info
.error
;
100 event
->u
.RipInfo
.dwType
= data
->info
.rip_info
.type
;
103 server_protocol_error( "WaitForDebugEvent: bad code %d\n", data
->code
);
112 /**********************************************************************
113 * ContinueDebugEvent (KERNEL32.146)
115 BOOL WINAPI
ContinueDebugEvent( DWORD pid
, DWORD tid
, DWORD status
)
120 struct continue_debug_event_request
*req
= server_alloc_req( sizeof(*req
), 0 );
121 req
->pid
= (void *)pid
;
122 req
->tid
= (void *)tid
;
123 req
->status
= status
;
124 ret
= !server_call( REQ_CONTINUE_DEBUG_EVENT
);
131 /**********************************************************************
132 * DebugActiveProcess (KERNEL32.180)
134 BOOL WINAPI
DebugActiveProcess( DWORD pid
)
139 struct debug_process_request
*req
= server_alloc_req( sizeof(*req
), 0 );
140 req
->pid
= (void *)pid
;
141 ret
= !server_call( REQ_DEBUG_PROCESS
);
148 /***********************************************************************
149 * OutputDebugStringA (KERNEL32.548)
151 void WINAPI
OutputDebugStringA( LPCSTR str
)
155 struct output_debug_string_request
*req
= server_alloc_req( sizeof(*req
), 0 );
156 req
->string
= (void *)str
;
158 req
->length
= strlen(str
) + 1;
159 server_call_noerr( REQ_OUTPUT_DEBUG_STRING
);
166 /***********************************************************************
167 * OutputDebugStringW (KERNEL32.549)
169 void WINAPI
OutputDebugStringW( LPCWSTR str
)
173 struct output_debug_string_request
*req
= server_alloc_req( sizeof(*req
), 0 );
174 req
->string
= (void *)str
;
176 req
->length
= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
177 server_call_noerr( REQ_OUTPUT_DEBUG_STRING
);
180 WARN("%s\n", debugstr_w(str
));
184 /***********************************************************************
185 * OutputDebugString16 (KERNEL.115)
187 void WINAPI
OutputDebugString16( LPCSTR str
)
189 OutputDebugStringA( str
);
193 /***********************************************************************
194 * DebugBreak (KERNEL32.181)
196 void WINAPI
DebugBreak(void)
202 /***********************************************************************
203 * DebugBreak16 (KERNEL.203)
205 void WINAPI
DebugBreak16( CONTEXT86
*context
)
208 EXCEPTION_RECORD rec
;
210 rec
.ExceptionCode
= EXCEPTION_BREAKPOINT
;
211 rec
.ExceptionFlags
= 0;
212 rec
.ExceptionRecord
= NULL
;
213 rec
.ExceptionAddress
= (LPVOID
)context
->Eip
;
214 rec
.NumberParameters
= 0;
215 NtRaiseException( &rec
, context
, TRUE
);
216 #endif /* defined(__i386__) */
220 /***********************************************************************
221 * IsDebuggerPresent (KERNEL32)
223 BOOL WINAPI
IsDebuggerPresent(void)
228 struct get_process_info_request
*req
= server_alloc_req( sizeof(*req
), 0 );
229 req
->handle
= GetCurrentProcess();
230 if (!server_call( REQ_GET_PROCESS_INFO
)) ret
= req
->debugged
;
237 /***********************************************************************
238 * _DebugOutput (KERNEL.328)
240 void WINAPIV
_DebugOutput( void )
247 /* Decode caller address */
248 if (!GetModuleName16( GetExePtr(CURRENT_STACK16
->cs
), caller
, sizeof(caller
) ))
249 sprintf( caller
, "%04X:%04X", CURRENT_STACK16
->cs
, CURRENT_STACK16
->ip
);
251 /* Build debug message string */
252 VA_START16( valist
);
253 flags
= VA_ARG16( valist
, WORD
);
254 spec
= VA_ARG16( valist
, SEGPTR
);
255 /* FIXME: cannot use wvsnprintf16 from kernel */
256 /* wvsnprintf16( temp, sizeof(temp), MapSL(spec), valist ); */
259 FIXME("%s %04x %s\n", caller
, flags
, debugstr_a(MapSL(spec
)) );