2 * Win32 debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
12 #include "debugtools.h"
14 DECLARE_DEBUG_CHANNEL(debugstr
)
16 /**********************************************************************
19 * Internal helper to send a debug event request to the server.
21 static DWORD
DEBUG_SendEvent( int code
, void *data
, int size
)
24 struct send_debug_event_request
*req
= get_req_buffer();
26 memcpy( req
+ 1, data
, size
);
27 if (!server_call( REQ_SEND_DEBUG_EVENT
)) ret
= req
->status
;
32 /**********************************************************************
33 * DEBUG_SendExceptionEvent
35 * Send an EXCEPTION_DEBUG_EVENT event to the current process debugger.
37 DWORD
DEBUG_SendExceptionEvent( EXCEPTION_RECORD
*rec
, BOOL first_chance
)
39 struct debug_event_exception event
;
42 event
.code
= rec
->ExceptionCode
;
43 event
.flags
= rec
->ExceptionFlags
;
44 event
.record
= rec
->ExceptionRecord
;
45 event
.addr
= rec
->ExceptionAddress
;
46 event
.nb_params
= rec
->NumberParameters
;
47 for (i
= 0; i
< event
.nb_params
; i
++) event
.params
[i
] = rec
->ExceptionInformation
[i
];
48 event
.first_chance
= first_chance
;
49 return DEBUG_SendEvent( EXCEPTION_DEBUG_EVENT
, &event
, sizeof(event
) );
53 /**********************************************************************
54 * DEBUG_SendCreateProcessEvent
56 * Send an CREATE_PROCESS_DEBUG_EVENT event to the current process debugger.
57 * Must be called from the context of the new process.
59 DWORD
DEBUG_SendCreateProcessEvent( HFILE file
, HMODULE module
, void *entry
)
61 struct debug_event_create_process event
;
64 event
.process
= 0; /* will be filled by server */
65 event
.thread
= 0; /* will be filled by server */
66 event
.base
= (void *)module
;
67 event
.dbg_offset
= 0; /* FIXME */
68 event
.dbg_size
= 0; /* FIXME */
69 event
.teb
= NtCurrentTeb();
71 event
.name
= 0; /* FIXME */
72 event
.unicode
= 0; /* FIXME */
73 return DEBUG_SendEvent( CREATE_PROCESS_DEBUG_EVENT
, &event
, sizeof(event
) );
77 /**********************************************************************
78 * DEBUG_SendCreateThreadEvent
80 * Send an CREATE_THREAD_DEBUG_EVENT event to the current process debugger.
81 * Must be called from the context of the new thread.
83 DWORD
DEBUG_SendCreateThreadEvent( void *entry
)
85 struct debug_event_create_thread event
;
87 event
.handle
= 0; /* will be filled by server */
88 event
.teb
= NtCurrentTeb();
90 return DEBUG_SendEvent( CREATE_THREAD_DEBUG_EVENT
, &event
, sizeof(event
) );
94 /**********************************************************************
95 * DEBUG_SendLoadDLLEvent
97 * Send an LOAD_DLL_DEBUG_EVENT event to the current process debugger.
99 DWORD
DEBUG_SendLoadDLLEvent( HFILE file
, HMODULE module
, LPSTR name
)
101 struct debug_event_load_dll event
;
104 event
.base
= (void *)module
;
105 event
.dbg_offset
= 0; /* FIXME */
106 event
.dbg_size
= 0; /* FIXME */
109 return DEBUG_SendEvent( LOAD_DLL_DEBUG_EVENT
, &event
, sizeof(event
) );
113 /**********************************************************************
114 * DEBUG_SendUnloadDLLEvent
116 * Send an UNLOAD_DLL_DEBUG_EVENT event to the current process debugger.
118 DWORD
DEBUG_SendUnloadDLLEvent( HMODULE module
)
120 struct debug_event_unload_dll event
;
122 event
.base
= (void *)module
;
123 return DEBUG_SendEvent( UNLOAD_DLL_DEBUG_EVENT
, &event
, sizeof(event
) );
127 /******************************************************************************
128 * WaitForDebugEvent (KERNEL32.720)
130 * Waits for a debugging event to occur in a process being debugged
133 * event [I] Address of structure for event information
134 * timeout [I] Number of milliseconds to wait for event
138 BOOL WINAPI
WaitForDebugEvent( LPDEBUG_EVENT event
, DWORD timeout
)
140 struct wait_debug_event_request
*req
= get_req_buffer();
141 union debug_event_data
*data
= (union debug_event_data
*)(req
+ 1);
144 req
->timeout
= timeout
;
145 if (server_call( REQ_WAIT_DEBUG_EVENT
)) return FALSE
;
146 if ((req
->code
< 0) || (req
->code
> RIP_EVENT
))
147 server_protocol_error( "WaitForDebugEvent: bad code %d\n", req
->code
);
149 event
->dwDebugEventCode
= req
->code
;
150 event
->dwProcessId
= (DWORD
)req
->pid
;
151 event
->dwThreadId
= (DWORD
)req
->tid
;
154 case EXCEPTION_DEBUG_EVENT
:
155 event
->u
.Exception
.ExceptionRecord
.ExceptionCode
= data
->exception
.code
;
156 event
->u
.Exception
.ExceptionRecord
.ExceptionFlags
= data
->exception
.flags
;
157 event
->u
.Exception
.ExceptionRecord
.ExceptionRecord
= data
->exception
.record
;
158 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
= data
->exception
.addr
;
159 event
->u
.Exception
.ExceptionRecord
.NumberParameters
= data
->exception
.nb_params
;
160 for (i
= 0; i
< data
->exception
.nb_params
; i
++)
161 event
->u
.Exception
.ExceptionRecord
.ExceptionInformation
[i
] = data
->exception
.params
[i
];
162 event
->u
.Exception
.dwFirstChance
= data
->exception
.first_chance
;
164 case CREATE_THREAD_DEBUG_EVENT
:
165 event
->u
.CreateThread
.hThread
= data
->create_thread
.handle
;
166 event
->u
.CreateThread
.lpThreadLocalBase
= data
->create_thread
.teb
;
167 event
->u
.CreateThread
.lpStartAddress
= data
->create_thread
.start
;
169 case CREATE_PROCESS_DEBUG_EVENT
:
170 event
->u
.CreateProcessInfo
.hFile
= data
->create_process
.file
;
171 event
->u
.CreateProcessInfo
.hProcess
= data
->create_process
.process
;
172 event
->u
.CreateProcessInfo
.hThread
= data
->create_process
.thread
;
173 event
->u
.CreateProcessInfo
.lpBaseOfImage
= data
->create_process
.base
;
174 event
->u
.CreateProcessInfo
.dwDebugInfoFileOffset
= data
->create_process
.dbg_offset
;
175 event
->u
.CreateProcessInfo
.nDebugInfoSize
= data
->create_process
.dbg_size
;
176 event
->u
.CreateProcessInfo
.lpThreadLocalBase
= data
->create_process
.teb
;
177 event
->u
.CreateProcessInfo
.lpStartAddress
= data
->create_process
.start
;
178 event
->u
.CreateProcessInfo
.lpImageName
= data
->create_process
.name
;
179 event
->u
.CreateProcessInfo
.fUnicode
= data
->create_process
.unicode
;
180 if (data
->create_process
.file
== -1) event
->u
.CreateProcessInfo
.hFile
= 0;
182 case EXIT_THREAD_DEBUG_EVENT
:
183 event
->u
.ExitThread
.dwExitCode
= data
->exit
.exit_code
;
185 case EXIT_PROCESS_DEBUG_EVENT
:
186 event
->u
.ExitProcess
.dwExitCode
= data
->exit
.exit_code
;
188 case LOAD_DLL_DEBUG_EVENT
:
189 event
->u
.LoadDll
.hFile
= data
->load_dll
.handle
;
190 event
->u
.LoadDll
.lpBaseOfDll
= data
->load_dll
.base
;
191 event
->u
.LoadDll
.dwDebugInfoFileOffset
= data
->load_dll
.dbg_offset
;
192 event
->u
.LoadDll
.nDebugInfoSize
= data
->load_dll
.dbg_size
;
193 event
->u
.LoadDll
.lpImageName
= data
->load_dll
.name
;
194 event
->u
.LoadDll
.fUnicode
= data
->load_dll
.unicode
;
195 if (data
->load_dll
.handle
== -1) event
->u
.LoadDll
.hFile
= 0;
197 case UNLOAD_DLL_DEBUG_EVENT
:
198 event
->u
.UnloadDll
.lpBaseOfDll
= data
->unload_dll
.base
;
200 case OUTPUT_DEBUG_STRING_EVENT
:
201 event
->u
.DebugString
.lpDebugStringData
= data
->output_string
.string
;
202 event
->u
.DebugString
.fUnicode
= data
->output_string
.unicode
;
203 event
->u
.DebugString
.nDebugStringLength
= data
->output_string
.length
;
206 event
->u
.RipInfo
.dwError
= data
->rip_info
.error
;
207 event
->u
.RipInfo
.dwType
= data
->rip_info
.type
;
214 /**********************************************************************
215 * ContinueDebugEvent (KERNEL32.146)
217 BOOL WINAPI
ContinueDebugEvent( DWORD pid
, DWORD tid
, DWORD status
)
219 struct continue_debug_event_request
*req
= get_req_buffer();
220 req
->pid
= (void *)pid
;
221 req
->tid
= (void *)tid
;
222 req
->status
= status
;
223 return !server_call( REQ_CONTINUE_DEBUG_EVENT
);
227 /**********************************************************************
228 * DebugActiveProcess (KERNEL32.180)
230 BOOL WINAPI
DebugActiveProcess( DWORD pid
)
232 struct debug_process_request
*req
= get_req_buffer();
233 req
->pid
= (void *)pid
;
234 return !server_call( REQ_DEBUG_PROCESS
);
238 /***********************************************************************
239 * OutputDebugStringA (KERNEL32.548)
241 void WINAPI
OutputDebugStringA( LPCSTR str
)
243 if (PROCESS_Current()->flags
& PDB32_DEBUGGED
)
245 struct debug_event_output_string event
;
246 event
.string
= (void *)str
;
248 event
.length
= strlen(str
) + 1;
249 DEBUG_SendEvent( OUTPUT_DEBUG_STRING_EVENT
, &event
, sizeof(event
) );
252 TRACE_(debugstr
)("%s\n", str
);
256 /***********************************************************************
257 * OutputDebugStringW (KERNEL32.549)
259 void WINAPI
OutputDebugStringW( LPCWSTR str
)
261 if (PROCESS_Current()->flags
& PDB32_DEBUGGED
)
263 struct debug_event_output_string event
;
264 event
.string
= (void *)str
;
266 event
.length
= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
267 DEBUG_SendEvent( OUTPUT_DEBUG_STRING_EVENT
, &event
, sizeof(event
) );
270 TRACE_(debugstr
)("%s\n", debugstr_w(str
));
274 /***********************************************************************
275 * OutputDebugString16 (KERNEL.115)
277 void WINAPI
OutputDebugString16( LPCSTR str
)
279 OutputDebugStringA( str
);