2 * Win32 debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
12 #include "debugtools.h"
14 DEFAULT_DEBUG_CHANNEL(debugstr
);
17 /**********************************************************************
18 * DEBUG_SendExceptionEvent
20 * Send an EXCEPTION_DEBUG_EVENT event to the current process debugger.
22 DWORD
DEBUG_SendExceptionEvent( EXCEPTION_RECORD
*rec
, BOOL first_chance
, CONTEXT
*context
)
25 struct send_debug_event_request
*req
= get_req_buffer();
27 req
->event
.code
= EXCEPTION_DEBUG_EVENT
;
28 req
->event
.info
.exception
.code
= rec
->ExceptionCode
;
29 req
->event
.info
.exception
.flags
= rec
->ExceptionFlags
;
30 req
->event
.info
.exception
.record
= rec
->ExceptionRecord
;
31 req
->event
.info
.exception
.addr
= rec
->ExceptionAddress
;
32 req
->event
.info
.exception
.nb_params
= rec
->NumberParameters
;
33 req
->event
.info
.exception
.first_chance
= first_chance
;
34 req
->event
.info
.exception
.context
= *context
;
35 for (i
= 0; i
< req
->event
.info
.exception
.nb_params
; i
++)
36 req
->event
.info
.exception
.params
[i
] = rec
->ExceptionInformation
[i
];
37 if (!server_call_noerr( REQ_SEND_DEBUG_EVENT
))
38 *context
= req
->event
.info
.exception
.context
;
43 /**********************************************************************
44 * DEBUG_SendLoadDLLEvent
46 * Send an LOAD_DLL_DEBUG_EVENT event to the current process debugger.
48 DWORD
DEBUG_SendLoadDLLEvent( HFILE file
, HMODULE module
, LPSTR
*name
)
50 struct send_debug_event_request
*req
= get_req_buffer();
52 req
->event
.code
= LOAD_DLL_DEBUG_EVENT
;
53 req
->event
.info
.load_dll
.handle
= file
;
54 req
->event
.info
.load_dll
.base
= (void *)module
;
55 req
->event
.info
.load_dll
.dbg_offset
= 0; /* FIXME */
56 req
->event
.info
.load_dll
.dbg_size
= 0; /* FIXME */
57 req
->event
.info
.load_dll
.name
= name
;
58 req
->event
.info
.load_dll
.unicode
= 0;
59 server_call_noerr( REQ_SEND_DEBUG_EVENT
);
64 /**********************************************************************
65 * DEBUG_SendUnloadDLLEvent
67 * Send an UNLOAD_DLL_DEBUG_EVENT event to the current process debugger.
69 DWORD
DEBUG_SendUnloadDLLEvent( HMODULE module
)
71 struct send_debug_event_request
*req
= get_req_buffer();
73 req
->event
.code
= UNLOAD_DLL_DEBUG_EVENT
;
74 req
->event
.info
.unload_dll
.base
= (void *)module
;
75 server_call_noerr( REQ_SEND_DEBUG_EVENT
);
80 /******************************************************************************
81 * WaitForDebugEvent (KERNEL32.720)
83 * Waits for a debugging event to occur in a process being debugged
86 * event [I] Address of structure for event information
87 * timeout [I] Number of milliseconds to wait for event
91 BOOL WINAPI
WaitForDebugEvent( LPDEBUG_EVENT event
, DWORD timeout
)
93 struct wait_debug_event_request
*req
= get_req_buffer();
96 req
->timeout
= timeout
;
97 if (server_call( REQ_WAIT_DEBUG_EVENT
)) return FALSE
;
98 if ((req
->event
.code
< 0) || (req
->event
.code
> RIP_EVENT
))
99 server_protocol_error( "WaitForDebugEvent: bad code %d\n", req
->event
.code
);
101 event
->dwDebugEventCode
= req
->event
.code
;
102 event
->dwProcessId
= (DWORD
)req
->pid
;
103 event
->dwThreadId
= (DWORD
)req
->tid
;
104 switch(req
->event
.code
)
106 case 0: /* timeout */
107 SetLastError( ERROR_SEM_TIMEOUT
);
109 case EXCEPTION_DEBUG_EVENT
:
110 event
->u
.Exception
.ExceptionRecord
.ExceptionCode
= req
->event
.info
.exception
.code
;
111 event
->u
.Exception
.ExceptionRecord
.ExceptionFlags
= req
->event
.info
.exception
.flags
;
112 event
->u
.Exception
.ExceptionRecord
.ExceptionRecord
= req
->event
.info
.exception
.record
;
113 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
= req
->event
.info
.exception
.addr
;
114 event
->u
.Exception
.ExceptionRecord
.NumberParameters
= req
->event
.info
.exception
.nb_params
;
115 for (i
= 0; i
< req
->event
.info
.exception
.nb_params
; i
++)
116 event
->u
.Exception
.ExceptionRecord
.ExceptionInformation
[i
] = req
->event
.info
.exception
.params
[i
];
117 event
->u
.Exception
.dwFirstChance
= req
->event
.info
.exception
.first_chance
;
119 case CREATE_THREAD_DEBUG_EVENT
:
120 event
->u
.CreateThread
.hThread
= req
->event
.info
.create_thread
.handle
;
121 event
->u
.CreateThread
.lpThreadLocalBase
= req
->event
.info
.create_thread
.teb
;
122 event
->u
.CreateThread
.lpStartAddress
= req
->event
.info
.create_thread
.start
;
124 case CREATE_PROCESS_DEBUG_EVENT
:
125 event
->u
.CreateProcessInfo
.hFile
= req
->event
.info
.create_process
.file
;
126 event
->u
.CreateProcessInfo
.hProcess
= req
->event
.info
.create_process
.process
;
127 event
->u
.CreateProcessInfo
.hThread
= req
->event
.info
.create_process
.thread
;
128 event
->u
.CreateProcessInfo
.lpBaseOfImage
= req
->event
.info
.create_process
.base
;
129 event
->u
.CreateProcessInfo
.dwDebugInfoFileOffset
= req
->event
.info
.create_process
.dbg_offset
;
130 event
->u
.CreateProcessInfo
.nDebugInfoSize
= req
->event
.info
.create_process
.dbg_size
;
131 event
->u
.CreateProcessInfo
.lpThreadLocalBase
= req
->event
.info
.create_process
.teb
;
132 event
->u
.CreateProcessInfo
.lpStartAddress
= req
->event
.info
.create_process
.start
;
133 event
->u
.CreateProcessInfo
.lpImageName
= req
->event
.info
.create_process
.name
;
134 event
->u
.CreateProcessInfo
.fUnicode
= req
->event
.info
.create_process
.unicode
;
135 if (req
->event
.info
.create_process
.file
== -1) event
->u
.CreateProcessInfo
.hFile
= 0;
137 case EXIT_THREAD_DEBUG_EVENT
:
138 event
->u
.ExitThread
.dwExitCode
= req
->event
.info
.exit
.exit_code
;
140 case EXIT_PROCESS_DEBUG_EVENT
:
141 event
->u
.ExitProcess
.dwExitCode
= req
->event
.info
.exit
.exit_code
;
143 case LOAD_DLL_DEBUG_EVENT
:
144 event
->u
.LoadDll
.hFile
= req
->event
.info
.load_dll
.handle
;
145 event
->u
.LoadDll
.lpBaseOfDll
= req
->event
.info
.load_dll
.base
;
146 event
->u
.LoadDll
.dwDebugInfoFileOffset
= req
->event
.info
.load_dll
.dbg_offset
;
147 event
->u
.LoadDll
.nDebugInfoSize
= req
->event
.info
.load_dll
.dbg_size
;
148 event
->u
.LoadDll
.lpImageName
= req
->event
.info
.load_dll
.name
;
149 event
->u
.LoadDll
.fUnicode
= req
->event
.info
.load_dll
.unicode
;
150 if (req
->event
.info
.load_dll
.handle
== -1) event
->u
.LoadDll
.hFile
= 0;
152 case UNLOAD_DLL_DEBUG_EVENT
:
153 event
->u
.UnloadDll
.lpBaseOfDll
= req
->event
.info
.unload_dll
.base
;
155 case OUTPUT_DEBUG_STRING_EVENT
:
156 event
->u
.DebugString
.lpDebugStringData
= req
->event
.info
.output_string
.string
;
157 event
->u
.DebugString
.fUnicode
= req
->event
.info
.output_string
.unicode
;
158 event
->u
.DebugString
.nDebugStringLength
= req
->event
.info
.output_string
.length
;
161 event
->u
.RipInfo
.dwError
= req
->event
.info
.rip_info
.error
;
162 event
->u
.RipInfo
.dwType
= req
->event
.info
.rip_info
.type
;
169 /**********************************************************************
170 * ContinueDebugEvent (KERNEL32.146)
172 BOOL WINAPI
ContinueDebugEvent( DWORD pid
, DWORD tid
, DWORD status
)
174 struct continue_debug_event_request
*req
= get_req_buffer();
175 req
->pid
= (void *)pid
;
176 req
->tid
= (void *)tid
;
177 req
->status
= status
;
178 return !server_call( REQ_CONTINUE_DEBUG_EVENT
);
182 /**********************************************************************
183 * DebugActiveProcess (KERNEL32.180)
185 BOOL WINAPI
DebugActiveProcess( DWORD pid
)
187 struct debug_process_request
*req
= get_req_buffer();
188 req
->pid
= (void *)pid
;
189 return !server_call( REQ_DEBUG_PROCESS
);
193 /***********************************************************************
194 * OutputDebugStringA (KERNEL32.548)
196 void WINAPI
OutputDebugStringA( LPCSTR str
)
198 if (PROCESS_Current()->flags
& PDB32_DEBUGGED
)
200 struct send_debug_event_request
*req
= get_req_buffer();
201 req
->event
.code
= OUTPUT_DEBUG_STRING_EVENT
;
202 req
->event
.info
.output_string
.string
= (void *)str
;
203 req
->event
.info
.output_string
.unicode
= 0;
204 req
->event
.info
.output_string
.length
= strlen(str
) + 1;
205 server_call( REQ_SEND_DEBUG_EVENT
);
212 /***********************************************************************
213 * OutputDebugStringW (KERNEL32.549)
215 void WINAPI
OutputDebugStringW( LPCWSTR str
)
217 if (PROCESS_Current()->flags
& PDB32_DEBUGGED
)
219 struct send_debug_event_request
*req
= get_req_buffer();
220 req
->event
.code
= OUTPUT_DEBUG_STRING_EVENT
;
221 req
->event
.info
.output_string
.string
= (void *)str
;
222 req
->event
.info
.output_string
.unicode
= 1;
223 req
->event
.info
.output_string
.length
= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
224 server_call( REQ_SEND_DEBUG_EVENT
);
227 TRACE("%s\n", debugstr_w(str
));
231 /***********************************************************************
232 * OutputDebugString16 (KERNEL.115)
234 void WINAPI
OutputDebugString16( LPCSTR str
)
236 OutputDebugStringA( str
);