2 * Win32 debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
10 #include "debugtools.h"
13 /**********************************************************************
16 * Internal helper to send a debug event request to the server.
18 static DWORD DEBUG_SendEvent( int code, void *data, int size )
21 struct send_debug_event_request *req = get_req_buffer();
23 memcpy( req + 1, data, size );
24 if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status;
29 /**********************************************************************
30 * DEBUG_SendExceptionEvent
32 * Send an EXCEPTION_DEBUG_EVENT event to the current process debugger.
34 DWORD DEBUG_SendExceptionEvent( EXCEPTION_RECORD *rec, BOOL first_chance )
36 struct debug_event_exception event;
39 event.code = rec->ExceptionCode;
40 event.flags = rec->ExceptionFlags;
41 event.record = rec->ExceptionRecord;
42 event.addr = rec->ExceptionAddress;
43 event.nb_params = rec->NumberParameters;
44 for (i = 0; i < event.nb_params; i++) event.params[i] = rec->ExceptionInformation[i];
45 event.first_chance = first_chance;
46 return DEBUG_SendEvent( EXCEPTION_DEBUG_EVENT, &event, sizeof(event) );
50 /**********************************************************************
51 * DEBUG_SendCreateProcessEvent
53 * Send an CREATE_PROCESS_DEBUG_EVENT event to the current process debugger.
54 * Must be called from the context of the new process.
56 DWORD DEBUG_SendCreateProcessEvent( HFILE file, HMODULE module, void *entry )
58 struct debug_event_create_process event;
61 event.process = 0; /* will be filled by server */
62 event.thread = 0; /* will be filled by server */
63 event.base = (void *)module;
64 event.dbg_offset = 0; /* FIXME */
65 event.dbg_size = 0; /* FIXME */
66 event.teb = NtCurrentTeb();
68 event.name = 0; /* FIXME */
69 event.unicode = 0; /* FIXME */
70 return DEBUG_SendEvent( CREATE_PROCESS_DEBUG_EVENT, &event, sizeof(event) );
74 /**********************************************************************
75 * DEBUG_SendCreateThreadEvent
77 * Send an CREATE_THREAD_DEBUG_EVENT event to the current process debugger.
78 * Must be called from the context of the new thread.
80 DWORD DEBUG_SendCreateThreadEvent( void *entry )
82 struct debug_event_create_thread event;
84 event.handle = 0; /* will be filled by server */
85 event.teb = NtCurrentTeb();
87 return DEBUG_SendEvent( CREATE_THREAD_DEBUG_EVENT, &event, sizeof(event) );
91 /**********************************************************************
92 * DEBUG_SendLoadDLLEvent
94 * Send an LOAD_DLL_DEBUG_EVENT event to the current process debugger.
96 DWORD DEBUG_SendLoadDLLEvent( HFILE file, HMODULE module, LPSTR name )
98 struct debug_event_load_dll event;
101 event.base = (void *)module;
102 event.dbg_offset = 0; /* FIXME */
103 event.dbg_size = 0; /* FIXME */
106 return DEBUG_SendEvent( LOAD_DLL_DEBUG_EVENT, &event, sizeof(event) );
110 /**********************************************************************
111 * DEBUG_SendUnloadDLLEvent
113 * Send an UNLOAD_DLL_DEBUG_EVENT event to the current process debugger.
115 DWORD DEBUG_SendUnloadDLLEvent( HMODULE module )
117 struct debug_event_unload_dll event;
119 event.base = (void *)module;
120 return DEBUG_SendEvent( UNLOAD_DLL_DEBUG_EVENT, &event, sizeof(event) );
124 /******************************************************************************
125 * WaitForDebugEvent (KERNEL32.720)
127 * Waits for a debugging event to occur in a process being debugged
130 * event [I] Address of structure for event information
131 * timeout [I] Number of milliseconds to wait for event
135 BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout )
137 struct wait_debug_event_request *req = get_req_buffer();
138 union debug_event_data *data = (union debug_event_data *)(req + 1);
141 req->timeout = timeout;
142 if (server_call( REQ_WAIT_DEBUG_EVENT )) return FALSE;
143 if ((req->code < 0) || (req->code > RIP_EVENT))
144 server_protocol_error( "WaitForDebugEvent: bad code %d\n", req->code );
146 event->dwDebugEventCode = req->code;
147 event->dwProcessId = (DWORD)req->pid;
148 event->dwThreadId = (DWORD)req->tid;
151 case EXCEPTION_DEBUG_EVENT:
152 event->u.Exception.ExceptionRecord.ExceptionCode = data->exception.code;
153 event->u.Exception.ExceptionRecord.ExceptionFlags = data->exception.flags;
154 event->u.Exception.ExceptionRecord.ExceptionRecord = data->exception.record;
155 event->u.Exception.ExceptionRecord.ExceptionAddress = data->exception.addr;
156 event->u.Exception.ExceptionRecord.NumberParameters = data->exception.nb_params;
157 for (i = 0; i < data->exception.nb_params; i++)
158 event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data->exception.params[i];
159 event->u.Exception.dwFirstChance = data->exception.first_chance;
161 case CREATE_THREAD_DEBUG_EVENT:
162 event->u.CreateThread.hThread = data->create_thread.handle;
163 event->u.CreateThread.lpThreadLocalBase = data->create_thread.teb;
164 event->u.CreateThread.lpStartAddress = data->create_thread.start;
166 case CREATE_PROCESS_DEBUG_EVENT:
167 event->u.CreateProcessInfo.hFile = data->create_process.file;
168 event->u.CreateProcessInfo.hProcess = data->create_process.process;
169 event->u.CreateProcessInfo.hThread = data->create_process.thread;
170 event->u.CreateProcessInfo.lpBaseOfImage = data->create_process.base;
171 event->u.CreateProcessInfo.dwDebugInfoFileOffset = data->create_process.dbg_offset;
172 event->u.CreateProcessInfo.nDebugInfoSize = data->create_process.dbg_size;
173 event->u.CreateProcessInfo.lpThreadLocalBase = data->create_process.teb;
174 event->u.CreateProcessInfo.lpStartAddress = data->create_process.start;
175 event->u.CreateProcessInfo.lpImageName = data->create_process.name;
176 event->u.CreateProcessInfo.fUnicode = data->create_process.unicode;
177 if (data->create_process.file == -1) event->u.CreateProcessInfo.hFile = 0;
179 case EXIT_THREAD_DEBUG_EVENT:
180 event->u.ExitThread.dwExitCode = data->exit.exit_code;
182 case EXIT_PROCESS_DEBUG_EVENT:
183 event->u.ExitProcess.dwExitCode = data->exit.exit_code;
185 case LOAD_DLL_DEBUG_EVENT:
186 event->u.LoadDll.hFile = data->load_dll.handle;
187 event->u.LoadDll.lpBaseOfDll = data->load_dll.base;
188 event->u.LoadDll.dwDebugInfoFileOffset = data->load_dll.dbg_offset;
189 event->u.LoadDll.nDebugInfoSize = data->load_dll.dbg_size;
190 event->u.LoadDll.lpImageName = data->load_dll.name;
191 event->u.LoadDll.fUnicode = data->load_dll.unicode;
192 if (data->load_dll.handle == -1) event->u.LoadDll.hFile = 0;
194 case UNLOAD_DLL_DEBUG_EVENT:
195 event->u.UnloadDll.lpBaseOfDll = data->unload_dll.base;
197 case OUTPUT_DEBUG_STRING_EVENT:
198 event->u.DebugString.lpDebugStringData = data->output_string.string;
199 event->u.DebugString.fUnicode = data->output_string.unicode;
200 event->u.DebugString.nDebugStringLength = data->output_string.length;
203 event->u.RipInfo.dwError = data->rip_info.error;
204 event->u.RipInfo.dwType = data->rip_info.type;
211 /**********************************************************************
212 * ContinueDebugEvent (KERNEL32.146)
214 BOOL WINAPI ContinueDebugEvent( DWORD pid, DWORD tid, DWORD status )
216 struct continue_debug_event_request *req = get_req_buffer();
217 req->pid = (void *)pid;
218 req->tid = (void *)tid;
219 req->status = status;
220 return !server_call( REQ_CONTINUE_DEBUG_EVENT );
224 /**********************************************************************
225 * DebugActiveProcess (KERNEL32.180)
227 BOOL WINAPI DebugActiveProcess( DWORD pid )
229 struct debug_process_request *req = get_req_buffer();
230 req->pid = (void *)pid;
231 return !server_call( REQ_DEBUG_PROCESS );
235 /***********************************************************************
236 * OutputDebugStringA (KERNEL32.548)
238 void WINAPI OutputDebugStringA( LPCSTR str )
240 if (PROCESS_Current()->flags & PDB32_DEBUGGED)
242 struct debug_event_output_string event;
243 event.string = (void *)str;
245 event.length = strlen(str) + 1;
246 DEBUG_SendEvent( OUTPUT_DEBUG_STRING_EVENT, &event, sizeof(event) );
248 else DPRINTF("OutputDebugStringA: %s\n", debugstr_a(str) );
252 /***********************************************************************
253 * OutputDebugStringW (KERNEL32.549)
255 void WINAPI OutputDebugStringW( LPCWSTR str )
257 if (PROCESS_Current()->flags & PDB32_DEBUGGED)
259 struct debug_event_output_string event;
260 event.string = (void *)str;
262 event.length = (lstrlenW(str) + 1) * sizeof(WCHAR);
263 DEBUG_SendEvent( OUTPUT_DEBUG_STRING_EVENT, &event, sizeof(event) );
265 else DPRINTF("OutputDebugStringW: %s\n", debugstr_w(str) );
269 /***********************************************************************
270 * OutputDebugString16 (KERNEL.115)
272 void WINAPI OutputDebugString16( LPCSTR str )
274 OutputDebugStringA( str );