2 * Win32 debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
12 #include "debugtools.h"
15 /**********************************************************************
18 * Internal helper to send a debug event request to the server.
20 static DWORD
DEBUG_SendEvent( int code
, void *data
, int size
)
23 struct send_debug_event_request
*req
= get_req_buffer();
25 memcpy( req
+ 1, data
, size
);
26 if (!server_call( REQ_SEND_DEBUG_EVENT
)) ret
= req
->status
;
31 /**********************************************************************
32 * DEBUG_SendExceptionEvent
34 * Send an EXCEPTION_DEBUG_EVENT event to the current process debugger.
36 DWORD
DEBUG_SendExceptionEvent( EXCEPTION_RECORD
*rec
, BOOL first_chance
)
38 struct debug_event_exception event
;
41 event
.code
= rec
->ExceptionCode
;
42 event
.flags
= rec
->ExceptionFlags
;
43 event
.record
= rec
->ExceptionRecord
;
44 event
.addr
= rec
->ExceptionAddress
;
45 event
.nb_params
= rec
->NumberParameters
;
46 for (i
= 0; i
< event
.nb_params
; i
++) event
.params
[i
] = rec
->ExceptionInformation
[i
];
47 event
.first_chance
= first_chance
;
48 return DEBUG_SendEvent( EXCEPTION_DEBUG_EVENT
, &event
, sizeof(event
) );
52 /**********************************************************************
53 * DEBUG_SendCreateProcessEvent
55 * Send an CREATE_PROCESS_DEBUG_EVENT event to the current process debugger.
56 * Must be called from the context of the new process.
58 DWORD
DEBUG_SendCreateProcessEvent( HFILE file
, HMODULE module
, void *entry
)
60 struct debug_event_create_process event
;
63 event
.process
= 0; /* will be filled by server */
64 event
.thread
= 0; /* will be filled by server */
65 event
.base
= (void *)module
;
66 event
.dbg_offset
= 0; /* FIXME */
67 event
.dbg_size
= 0; /* FIXME */
68 event
.teb
= NtCurrentTeb();
70 event
.name
= 0; /* FIXME */
71 event
.unicode
= 0; /* FIXME */
72 return DEBUG_SendEvent( CREATE_PROCESS_DEBUG_EVENT
, &event
, sizeof(event
) );
76 /**********************************************************************
77 * DEBUG_SendCreateThreadEvent
79 * Send an CREATE_THREAD_DEBUG_EVENT event to the current process debugger.
80 * Must be called from the context of the new thread.
82 DWORD
DEBUG_SendCreateThreadEvent( void *entry
)
84 struct debug_event_create_thread event
;
86 event
.handle
= 0; /* will be filled by server */
87 event
.teb
= NtCurrentTeb();
89 return DEBUG_SendEvent( CREATE_THREAD_DEBUG_EVENT
, &event
, sizeof(event
) );
93 /**********************************************************************
94 * DEBUG_SendLoadDLLEvent
96 * Send an LOAD_DLL_DEBUG_EVENT event to the current process debugger.
98 DWORD
DEBUG_SendLoadDLLEvent( HFILE file
, HMODULE module
, LPSTR name
)
100 struct debug_event_load_dll event
;
103 event
.base
= (void *)module
;
104 event
.dbg_offset
= 0; /* FIXME */
105 event
.dbg_size
= 0; /* FIXME */
108 return DEBUG_SendEvent( LOAD_DLL_DEBUG_EVENT
, &event
, sizeof(event
) );
112 /**********************************************************************
113 * DEBUG_SendUnloadDLLEvent
115 * Send an UNLOAD_DLL_DEBUG_EVENT event to the current process debugger.
117 DWORD
DEBUG_SendUnloadDLLEvent( HMODULE module
)
119 struct debug_event_unload_dll event
;
121 event
.base
= (void *)module
;
122 return DEBUG_SendEvent( UNLOAD_DLL_DEBUG_EVENT
, &event
, sizeof(event
) );
126 /******************************************************************************
127 * WaitForDebugEvent (KERNEL32.720)
129 * Waits for a debugging event to occur in a process being debugged
132 * event [I] Address of structure for event information
133 * timeout [I] Number of milliseconds to wait for event
137 BOOL WINAPI
WaitForDebugEvent( LPDEBUG_EVENT event
, DWORD timeout
)
139 struct wait_debug_event_request
*req
= get_req_buffer();
140 union debug_event_data
*data
= (union debug_event_data
*)(req
+ 1);
143 req
->timeout
= timeout
;
144 if (server_call( REQ_WAIT_DEBUG_EVENT
)) return FALSE
;
145 if ((req
->code
< 0) || (req
->code
> RIP_EVENT
))
146 server_protocol_error( "WaitForDebugEvent: bad code %d\n", req
->code
);
148 event
->dwDebugEventCode
= req
->code
;
149 event
->dwProcessId
= (DWORD
)req
->pid
;
150 event
->dwThreadId
= (DWORD
)req
->tid
;
153 case EXCEPTION_DEBUG_EVENT
:
154 event
->u
.Exception
.ExceptionRecord
.ExceptionCode
= data
->exception
.code
;
155 event
->u
.Exception
.ExceptionRecord
.ExceptionFlags
= data
->exception
.flags
;
156 event
->u
.Exception
.ExceptionRecord
.ExceptionRecord
= data
->exception
.record
;
157 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
= data
->exception
.addr
;
158 event
->u
.Exception
.ExceptionRecord
.NumberParameters
= data
->exception
.nb_params
;
159 for (i
= 0; i
< data
->exception
.nb_params
; i
++)
160 event
->u
.Exception
.ExceptionRecord
.ExceptionInformation
[i
] = data
->exception
.params
[i
];
161 event
->u
.Exception
.dwFirstChance
= data
->exception
.first_chance
;
163 case CREATE_THREAD_DEBUG_EVENT
:
164 event
->u
.CreateThread
.hThread
= data
->create_thread
.handle
;
165 event
->u
.CreateThread
.lpThreadLocalBase
= data
->create_thread
.teb
;
166 event
->u
.CreateThread
.lpStartAddress
= data
->create_thread
.start
;
168 case CREATE_PROCESS_DEBUG_EVENT
:
169 event
->u
.CreateProcessInfo
.hFile
= data
->create_process
.file
;
170 event
->u
.CreateProcessInfo
.hProcess
= data
->create_process
.process
;
171 event
->u
.CreateProcessInfo
.hThread
= data
->create_process
.thread
;
172 event
->u
.CreateProcessInfo
.lpBaseOfImage
= data
->create_process
.base
;
173 event
->u
.CreateProcessInfo
.dwDebugInfoFileOffset
= data
->create_process
.dbg_offset
;
174 event
->u
.CreateProcessInfo
.nDebugInfoSize
= data
->create_process
.dbg_size
;
175 event
->u
.CreateProcessInfo
.lpThreadLocalBase
= data
->create_process
.teb
;
176 event
->u
.CreateProcessInfo
.lpStartAddress
= data
->create_process
.start
;
177 event
->u
.CreateProcessInfo
.lpImageName
= data
->create_process
.name
;
178 event
->u
.CreateProcessInfo
.fUnicode
= data
->create_process
.unicode
;
179 if (data
->create_process
.file
== -1) event
->u
.CreateProcessInfo
.hFile
= 0;
181 case EXIT_THREAD_DEBUG_EVENT
:
182 event
->u
.ExitThread
.dwExitCode
= data
->exit
.exit_code
;
184 case EXIT_PROCESS_DEBUG_EVENT
:
185 event
->u
.ExitProcess
.dwExitCode
= data
->exit
.exit_code
;
187 case LOAD_DLL_DEBUG_EVENT
:
188 event
->u
.LoadDll
.hFile
= data
->load_dll
.handle
;
189 event
->u
.LoadDll
.lpBaseOfDll
= data
->load_dll
.base
;
190 event
->u
.LoadDll
.dwDebugInfoFileOffset
= data
->load_dll
.dbg_offset
;
191 event
->u
.LoadDll
.nDebugInfoSize
= data
->load_dll
.dbg_size
;
192 event
->u
.LoadDll
.lpImageName
= data
->load_dll
.name
;
193 event
->u
.LoadDll
.fUnicode
= data
->load_dll
.unicode
;
194 if (data
->load_dll
.handle
== -1) event
->u
.LoadDll
.hFile
= 0;
196 case UNLOAD_DLL_DEBUG_EVENT
:
197 event
->u
.UnloadDll
.lpBaseOfDll
= data
->unload_dll
.base
;
199 case OUTPUT_DEBUG_STRING_EVENT
:
200 event
->u
.DebugString
.lpDebugStringData
= data
->output_string
.string
;
201 event
->u
.DebugString
.fUnicode
= data
->output_string
.unicode
;
202 event
->u
.DebugString
.nDebugStringLength
= data
->output_string
.length
;
205 event
->u
.RipInfo
.dwError
= data
->rip_info
.error
;
206 event
->u
.RipInfo
.dwType
= data
->rip_info
.type
;
213 /**********************************************************************
214 * ContinueDebugEvent (KERNEL32.146)
216 BOOL WINAPI
ContinueDebugEvent( DWORD pid
, DWORD tid
, DWORD status
)
218 struct continue_debug_event_request
*req
= get_req_buffer();
219 req
->pid
= (void *)pid
;
220 req
->tid
= (void *)tid
;
221 req
->status
= status
;
222 return !server_call( REQ_CONTINUE_DEBUG_EVENT
);
226 /**********************************************************************
227 * DebugActiveProcess (KERNEL32.180)
229 BOOL WINAPI
DebugActiveProcess( DWORD pid
)
231 struct debug_process_request
*req
= get_req_buffer();
232 req
->pid
= (void *)pid
;
233 return !server_call( REQ_DEBUG_PROCESS
);
237 /***********************************************************************
238 * OutputDebugStringA (KERNEL32.548)
240 void WINAPI
OutputDebugStringA( LPCSTR str
)
242 if (PROCESS_Current()->flags
& PDB32_DEBUGGED
)
244 struct debug_event_output_string event
;
245 event
.string
= (void *)str
;
247 event
.length
= strlen(str
) + 1;
248 DEBUG_SendEvent( OUTPUT_DEBUG_STRING_EVENT
, &event
, sizeof(event
) );
253 /***********************************************************************
254 * OutputDebugStringW (KERNEL32.549)
256 void WINAPI
OutputDebugStringW( LPCWSTR str
)
258 if (PROCESS_Current()->flags
& PDB32_DEBUGGED
)
260 struct debug_event_output_string event
;
261 event
.string
= (void *)str
;
263 event
.length
= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
264 DEBUG_SendEvent( OUTPUT_DEBUG_STRING_EVENT
, &event
, sizeof(event
) );
269 /***********************************************************************
270 * OutputDebugString16 (KERNEL.115)
272 void WINAPI
OutputDebugString16( LPCSTR str
)
274 OutputDebugStringA( str
);