Fixed DEBUG_ONLY_THIS_PROCESS again (thanks to Ulrich Weigand).
[wine/multimedia.git] / scheduler / debugger.c
blobab5091da50f5890eb230de777d776e958e5d47ac
1 /*
2 * Win32 debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
5 */
7 #include <string.h>
9 #include "process.h"
10 #include "thread.h"
11 #include "server.h"
12 #include "debugtools.h"
14 DECLARE_DEBUG_CHANNEL(debugstr)
16 /**********************************************************************
17 * DEBUG_SendEvent
19 * Internal helper to send a debug event request to the server.
21 static DWORD DEBUG_SendEvent( int code, void *data, int size )
23 DWORD ret = 0;
24 struct send_debug_event_request *req = get_req_buffer();
25 req->code = code;
26 memcpy( req + 1, data, size );
27 if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status;
28 return ret;
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, CONTEXT *context )
39 int i;
40 DWORD ret = 0;
41 struct send_debug_event_request *req = get_req_buffer();
42 struct debug_event_exception *event = (struct debug_event_exception *)(req + 1);
44 req->code = EXCEPTION_DEBUG_EVENT;
45 event->code = rec->ExceptionCode;
46 event->flags = rec->ExceptionFlags;
47 event->record = rec->ExceptionRecord;
48 event->addr = rec->ExceptionAddress;
49 event->nb_params = rec->NumberParameters;
50 for (i = 0; i < event->nb_params; i++) event->params[i] = rec->ExceptionInformation[i];
51 event->first_chance = first_chance;
52 event->context = *context;
53 if (!server_call( REQ_SEND_DEBUG_EVENT ))
55 ret = req->status;
56 *context = event->context;
58 return ret;
62 /**********************************************************************
63 * DEBUG_SendCreateProcessEvent
65 * Send an CREATE_PROCESS_DEBUG_EVENT event to the current process debugger.
66 * Must be called from the context of the new process.
68 DWORD DEBUG_SendCreateProcessEvent( HFILE file, HMODULE module, void *entry )
70 struct debug_event_create_process event;
72 event.file = file;
73 event.process = 0; /* will be filled by server */
74 event.thread = 0; /* will be filled by server */
75 event.base = (void *)module;
76 event.dbg_offset = 0; /* FIXME */
77 event.dbg_size = 0; /* FIXME */
78 event.teb = NtCurrentTeb();
79 event.start = entry;
80 event.name = 0; /* FIXME */
81 event.unicode = 0; /* FIXME */
82 return DEBUG_SendEvent( CREATE_PROCESS_DEBUG_EVENT, &event, sizeof(event) );
86 /**********************************************************************
87 * DEBUG_SendCreateThreadEvent
89 * Send an CREATE_THREAD_DEBUG_EVENT event to the current process debugger.
90 * Must be called from the context of the new thread.
92 DWORD DEBUG_SendCreateThreadEvent( void *entry )
94 struct debug_event_create_thread event;
96 event.handle = 0; /* will be filled by server */
97 event.teb = NtCurrentTeb();
98 event.start = entry;
99 return DEBUG_SendEvent( CREATE_THREAD_DEBUG_EVENT, &event, sizeof(event) );
103 /**********************************************************************
104 * DEBUG_SendLoadDLLEvent
106 * Send an LOAD_DLL_DEBUG_EVENT event to the current process debugger.
108 DWORD DEBUG_SendLoadDLLEvent( HFILE file, HMODULE module, LPSTR *name )
110 struct debug_event_load_dll event;
112 event.handle = file;
113 event.base = (void *)module;
114 event.dbg_offset = 0; /* FIXME */
115 event.dbg_size = 0; /* FIXME */
116 event.name = name;
117 event.unicode = 0;
118 return DEBUG_SendEvent( LOAD_DLL_DEBUG_EVENT, &event, sizeof(event) );
122 /**********************************************************************
123 * DEBUG_SendUnloadDLLEvent
125 * Send an UNLOAD_DLL_DEBUG_EVENT event to the current process debugger.
127 DWORD DEBUG_SendUnloadDLLEvent( HMODULE module )
129 struct debug_event_unload_dll event;
131 event.base = (void *)module;
132 return DEBUG_SendEvent( UNLOAD_DLL_DEBUG_EVENT, &event, sizeof(event) );
136 /******************************************************************************
137 * WaitForDebugEvent (KERNEL32.720)
139 * Waits for a debugging event to occur in a process being debugged
141 * PARAMS
142 * event [I] Address of structure for event information
143 * timeout [I] Number of milliseconds to wait for event
145 * RETURNS STD
147 BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout )
149 struct wait_debug_event_request *req = get_req_buffer();
150 union debug_event_data *data = (union debug_event_data *)(req + 1);
151 int i;
153 req->timeout = timeout;
154 if (server_call( REQ_WAIT_DEBUG_EVENT )) return FALSE;
155 if ((req->code < 0) || (req->code > RIP_EVENT))
156 server_protocol_error( "WaitForDebugEvent: bad code %d\n", req->code );
158 event->dwDebugEventCode = req->code;
159 event->dwProcessId = (DWORD)req->pid;
160 event->dwThreadId = (DWORD)req->tid;
161 switch(req->code)
163 case EXCEPTION_DEBUG_EVENT:
164 event->u.Exception.ExceptionRecord.ExceptionCode = data->exception.code;
165 event->u.Exception.ExceptionRecord.ExceptionFlags = data->exception.flags;
166 event->u.Exception.ExceptionRecord.ExceptionRecord = data->exception.record;
167 event->u.Exception.ExceptionRecord.ExceptionAddress = data->exception.addr;
168 event->u.Exception.ExceptionRecord.NumberParameters = data->exception.nb_params;
169 for (i = 0; i < data->exception.nb_params; i++)
170 event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data->exception.params[i];
171 event->u.Exception.dwFirstChance = data->exception.first_chance;
172 break;
173 case CREATE_THREAD_DEBUG_EVENT:
174 event->u.CreateThread.hThread = data->create_thread.handle;
175 event->u.CreateThread.lpThreadLocalBase = data->create_thread.teb;
176 event->u.CreateThread.lpStartAddress = data->create_thread.start;
177 break;
178 case CREATE_PROCESS_DEBUG_EVENT:
179 event->u.CreateProcessInfo.hFile = data->create_process.file;
180 event->u.CreateProcessInfo.hProcess = data->create_process.process;
181 event->u.CreateProcessInfo.hThread = data->create_process.thread;
182 event->u.CreateProcessInfo.lpBaseOfImage = data->create_process.base;
183 event->u.CreateProcessInfo.dwDebugInfoFileOffset = data->create_process.dbg_offset;
184 event->u.CreateProcessInfo.nDebugInfoSize = data->create_process.dbg_size;
185 event->u.CreateProcessInfo.lpThreadLocalBase = data->create_process.teb;
186 event->u.CreateProcessInfo.lpStartAddress = data->create_process.start;
187 event->u.CreateProcessInfo.lpImageName = data->create_process.name;
188 event->u.CreateProcessInfo.fUnicode = data->create_process.unicode;
189 if (data->create_process.file == -1) event->u.CreateProcessInfo.hFile = 0;
190 break;
191 case EXIT_THREAD_DEBUG_EVENT:
192 event->u.ExitThread.dwExitCode = data->exit.exit_code;
193 break;
194 case EXIT_PROCESS_DEBUG_EVENT:
195 event->u.ExitProcess.dwExitCode = data->exit.exit_code;
196 break;
197 case LOAD_DLL_DEBUG_EVENT:
198 event->u.LoadDll.hFile = data->load_dll.handle;
199 event->u.LoadDll.lpBaseOfDll = data->load_dll.base;
200 event->u.LoadDll.dwDebugInfoFileOffset = data->load_dll.dbg_offset;
201 event->u.LoadDll.nDebugInfoSize = data->load_dll.dbg_size;
202 event->u.LoadDll.lpImageName = data->load_dll.name;
203 event->u.LoadDll.fUnicode = data->load_dll.unicode;
204 if (data->load_dll.handle == -1) event->u.LoadDll.hFile = 0;
205 break;
206 case UNLOAD_DLL_DEBUG_EVENT:
207 event->u.UnloadDll.lpBaseOfDll = data->unload_dll.base;
208 break;
209 case OUTPUT_DEBUG_STRING_EVENT:
210 event->u.DebugString.lpDebugStringData = data->output_string.string;
211 event->u.DebugString.fUnicode = data->output_string.unicode;
212 event->u.DebugString.nDebugStringLength = data->output_string.length;
213 break;
214 case RIP_EVENT:
215 event->u.RipInfo.dwError = data->rip_info.error;
216 event->u.RipInfo.dwType = data->rip_info.type;
217 break;
219 return TRUE;
223 /**********************************************************************
224 * ContinueDebugEvent (KERNEL32.146)
226 BOOL WINAPI ContinueDebugEvent( DWORD pid, DWORD tid, DWORD status )
228 struct continue_debug_event_request *req = get_req_buffer();
229 req->pid = (void *)pid;
230 req->tid = (void *)tid;
231 req->status = status;
232 return !server_call( REQ_CONTINUE_DEBUG_EVENT );
236 /**********************************************************************
237 * DebugActiveProcess (KERNEL32.180)
239 BOOL WINAPI DebugActiveProcess( DWORD pid )
241 struct debug_process_request *req = get_req_buffer();
242 req->pid = (void *)pid;
243 return !server_call( REQ_DEBUG_PROCESS );
247 /***********************************************************************
248 * OutputDebugStringA (KERNEL32.548)
250 void WINAPI OutputDebugStringA( LPCSTR str )
252 if (PROCESS_Current()->flags & PDB32_DEBUGGED)
254 struct debug_event_output_string event;
255 event.string = (void *)str;
256 event.unicode = 0;
257 event.length = strlen(str) + 1;
258 DEBUG_SendEvent( OUTPUT_DEBUG_STRING_EVENT, &event, sizeof(event) );
261 TRACE_(debugstr)("%s\n", str);
265 /***********************************************************************
266 * OutputDebugStringW (KERNEL32.549)
268 void WINAPI OutputDebugStringW( LPCWSTR str )
270 if (PROCESS_Current()->flags & PDB32_DEBUGGED)
272 struct debug_event_output_string event;
273 event.string = (void *)str;
274 event.unicode = 1;
275 event.length = (lstrlenW(str) + 1) * sizeof(WCHAR);
276 DEBUG_SendEvent( OUTPUT_DEBUG_STRING_EVENT, &event, sizeof(event) );
279 TRACE_(debugstr)("%s\n", debugstr_w(str));
283 /***********************************************************************
284 * OutputDebugString16 (KERNEL.115)
286 void WINAPI OutputDebugString16( LPCSTR str )
288 OutputDebugStringA( str );