Moved all signal support to a new platform-specific file.
[wine] / scheduler / debugger.c
1 /*
2  * Win32 debugger functions
3  *
4  * Copyright (C) 1999 Alexandre Julliard
5  */
6
7 #include <string.h>
8
9 #include "process.h"
10 #include "thread.h"
11 #include "server.h"
12 #include "debugtools.h"
13
14
15 /**********************************************************************
16  *           DEBUG_SendEvent
17  *
18  * Internal helper to send a debug event request to the server.
19  */
20 static DWORD DEBUG_SendEvent( int code, void *data, int size )
21 {
22     DWORD ret = 0;
23     struct send_debug_event_request *req = get_req_buffer();
24     req->code = code;
25     memcpy( req + 1, data, size );
26     if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status;
27     return ret;
28 }
29
30
31 /**********************************************************************
32  *           DEBUG_SendExceptionEvent
33  *
34  * Send an EXCEPTION_DEBUG_EVENT event to the current process debugger.
35  */
36 DWORD DEBUG_SendExceptionEvent( EXCEPTION_RECORD *rec, BOOL first_chance )
37 {
38     struct debug_event_exception event;
39     int i;
40
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) );
49 }
50
51
52 /**********************************************************************
53  *           DEBUG_SendCreateProcessEvent
54  *
55  * Send an CREATE_PROCESS_DEBUG_EVENT event to the current process debugger.
56  * Must be called from the context of the new process.
57  */
58 DWORD DEBUG_SendCreateProcessEvent( HFILE file, HMODULE module, void *entry )
59 {
60     struct debug_event_create_process event;
61
62     event.file       = file;
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();
69     event.start      = entry;
70     event.name       = 0; /* FIXME */
71     event.unicode    = 0; /* FIXME */
72     return DEBUG_SendEvent( CREATE_PROCESS_DEBUG_EVENT, &event, sizeof(event) );
73 }
74
75
76 /**********************************************************************
77  *           DEBUG_SendCreateThreadEvent
78  *
79  * Send an CREATE_THREAD_DEBUG_EVENT event to the current process debugger.
80  * Must be called from the context of the new thread.
81  */
82 DWORD DEBUG_SendCreateThreadEvent( void *entry )
83 {
84     struct debug_event_create_thread event;
85
86     event.handle = 0; /* will be filled by server */
87     event.teb    = NtCurrentTeb();
88     event.start  = entry;
89     return DEBUG_SendEvent( CREATE_THREAD_DEBUG_EVENT, &event, sizeof(event) );
90 }
91
92
93 /**********************************************************************
94  *           DEBUG_SendLoadDLLEvent
95  *
96  * Send an LOAD_DLL_DEBUG_EVENT event to the current process debugger.
97  */
98 DWORD DEBUG_SendLoadDLLEvent( HFILE file, HMODULE module, LPSTR name )
99 {
100     struct debug_event_load_dll event;
101
102     event.handle     = file;
103     event.base       = (void *)module;
104     event.dbg_offset = 0;  /* FIXME */
105     event.dbg_size   = 0;  /* FIXME */
106     event.name       = name;
107     event.unicode    = 0;
108     return DEBUG_SendEvent( LOAD_DLL_DEBUG_EVENT, &event, sizeof(event) );
109 }
110
111
112 /**********************************************************************
113  *           DEBUG_SendUnloadDLLEvent
114  *
115  * Send an UNLOAD_DLL_DEBUG_EVENT event to the current process debugger.
116  */
117 DWORD DEBUG_SendUnloadDLLEvent( HMODULE module )
118 {
119     struct debug_event_unload_dll event;
120
121     event.base = (void *)module;
122     return DEBUG_SendEvent( UNLOAD_DLL_DEBUG_EVENT, &event, sizeof(event) );
123 }
124
125
126 /******************************************************************************
127  *           WaitForDebugEvent   (KERNEL32.720)
128  *
129  * Waits for a debugging event to occur in a process being debugged
130  *
131  * PARAMS
132  *    event   [I] Address of structure for event information
133  *    timeout [I] Number of milliseconds to wait for event
134  *
135  * RETURNS STD
136  */
137 BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout )
138 {
139     struct wait_debug_event_request *req = get_req_buffer();
140     union debug_event_data *data = (union debug_event_data *)(req + 1);
141     int i;
142
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 );
147
148     event->dwDebugEventCode = req->code;
149     event->dwProcessId      = (DWORD)req->pid;
150     event->dwThreadId       = (DWORD)req->tid;
151     switch(req->code)
152     {
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;
162         break;
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;
167         break;
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;
180         break;
181     case EXIT_THREAD_DEBUG_EVENT:
182         event->u.ExitThread.dwExitCode = data->exit.exit_code;
183         break;
184     case EXIT_PROCESS_DEBUG_EVENT:
185         event->u.ExitProcess.dwExitCode = data->exit.exit_code;
186         break;
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;
195         break;
196     case UNLOAD_DLL_DEBUG_EVENT:
197         event->u.UnloadDll.lpBaseOfDll = data->unload_dll.base;
198         break;
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;
203         break;
204     case RIP_EVENT:
205         event->u.RipInfo.dwError = data->rip_info.error;
206         event->u.RipInfo.dwType  = data->rip_info.type;
207         break;
208     }
209     return TRUE;
210 }
211
212
213 /**********************************************************************
214  *           ContinueDebugEvent   (KERNEL32.146)
215  */
216 BOOL WINAPI ContinueDebugEvent( DWORD pid, DWORD tid, DWORD status )
217 {
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 );
223 }
224
225
226 /**********************************************************************
227  *           DebugActiveProcess   (KERNEL32.180)
228  */
229 BOOL WINAPI DebugActiveProcess( DWORD pid )
230 {
231     struct debug_process_request *req = get_req_buffer();
232     req->pid = (void *)pid;
233     return !server_call( REQ_DEBUG_PROCESS );
234 }
235
236
237 /***********************************************************************
238  *           OutputDebugStringA   (KERNEL32.548)
239  */
240 void WINAPI OutputDebugStringA( LPCSTR str )
241 {
242     if (PROCESS_Current()->flags & PDB32_DEBUGGED)
243     {
244         struct debug_event_output_string event;
245         event.string  = (void *)str;
246         event.unicode = 0;
247         event.length  = strlen(str) + 1;
248         DEBUG_SendEvent( OUTPUT_DEBUG_STRING_EVENT, &event, sizeof(event) );
249     }
250 }
251
252
253 /***********************************************************************
254  *           OutputDebugStringW   (KERNEL32.549)
255  */
256 void WINAPI OutputDebugStringW( LPCWSTR str )
257 {
258     if (PROCESS_Current()->flags & PDB32_DEBUGGED)
259     {
260         struct debug_event_output_string event;
261         event.string  = (void *)str;
262         event.unicode = 1;
263         event.length  = (lstrlenW(str) + 1) * sizeof(WCHAR);
264         DEBUG_SendEvent( OUTPUT_DEBUG_STRING_EVENT, &event, sizeof(event) );
265     }
266 }
267
268
269 /***********************************************************************
270  *           OutputDebugString16   (KERNEL.115)
271  */
272 void WINAPI OutputDebugString16( LPCSTR str )
273 {
274     OutputDebugStringA( str );
275 }