2 * Win32 debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
11 #include "debugtools.h"
13 DEFAULT_DEBUG_CHANNEL(debugstr
);
16 /******************************************************************************
17 * WaitForDebugEvent (KERNEL32.720)
19 * Waits for a debugging event to occur in a process being debugged
22 * event [I] Address of structure for event information
23 * timeout [I] Number of milliseconds to wait for event
27 BOOL WINAPI
WaitForDebugEvent( LPDEBUG_EVENT event
, DWORD timeout
)
29 struct wait_debug_event_request
*req
= get_req_buffer();
31 req
->timeout
= timeout
;
32 if (server_call( REQ_WAIT_DEBUG_EVENT
)) return FALSE
;
33 if ((req
->event
.code
< 0) || (req
->event
.code
> RIP_EVENT
))
34 server_protocol_error( "WaitForDebugEvent: bad code %d\n", req
->event
.code
);
36 event
->dwDebugEventCode
= req
->event
.code
;
37 event
->dwProcessId
= (DWORD
)req
->pid
;
38 event
->dwThreadId
= (DWORD
)req
->tid
;
39 switch(req
->event
.code
)
42 SetLastError( ERROR_SEM_TIMEOUT
);
44 case EXCEPTION_DEBUG_EVENT
:
45 event
->u
.Exception
.ExceptionRecord
= req
->event
.info
.exception
.record
;
46 event
->u
.Exception
.dwFirstChance
= req
->event
.info
.exception
.first
;
48 case CREATE_THREAD_DEBUG_EVENT
:
49 event
->u
.CreateThread
.hThread
= req
->event
.info
.create_thread
.handle
;
50 event
->u
.CreateThread
.lpThreadLocalBase
= req
->event
.info
.create_thread
.teb
;
51 event
->u
.CreateThread
.lpStartAddress
= req
->event
.info
.create_thread
.start
;
53 case CREATE_PROCESS_DEBUG_EVENT
:
54 event
->u
.CreateProcessInfo
.hFile
= req
->event
.info
.create_process
.file
;
55 event
->u
.CreateProcessInfo
.hProcess
= req
->event
.info
.create_process
.process
;
56 event
->u
.CreateProcessInfo
.hThread
= req
->event
.info
.create_process
.thread
;
57 event
->u
.CreateProcessInfo
.lpBaseOfImage
= req
->event
.info
.create_process
.base
;
58 event
->u
.CreateProcessInfo
.dwDebugInfoFileOffset
= req
->event
.info
.create_process
.dbg_offset
;
59 event
->u
.CreateProcessInfo
.nDebugInfoSize
= req
->event
.info
.create_process
.dbg_size
;
60 event
->u
.CreateProcessInfo
.lpThreadLocalBase
= req
->event
.info
.create_process
.teb
;
61 event
->u
.CreateProcessInfo
.lpStartAddress
= req
->event
.info
.create_process
.start
;
62 event
->u
.CreateProcessInfo
.lpImageName
= req
->event
.info
.create_process
.name
;
63 event
->u
.CreateProcessInfo
.fUnicode
= req
->event
.info
.create_process
.unicode
;
64 if (req
->event
.info
.create_process
.file
== -1) event
->u
.CreateProcessInfo
.hFile
= 0;
66 case EXIT_THREAD_DEBUG_EVENT
:
67 event
->u
.ExitThread
.dwExitCode
= req
->event
.info
.exit
.exit_code
;
69 case EXIT_PROCESS_DEBUG_EVENT
:
70 event
->u
.ExitProcess
.dwExitCode
= req
->event
.info
.exit
.exit_code
;
72 case LOAD_DLL_DEBUG_EVENT
:
73 event
->u
.LoadDll
.hFile
= req
->event
.info
.load_dll
.handle
;
74 event
->u
.LoadDll
.lpBaseOfDll
= req
->event
.info
.load_dll
.base
;
75 event
->u
.LoadDll
.dwDebugInfoFileOffset
= req
->event
.info
.load_dll
.dbg_offset
;
76 event
->u
.LoadDll
.nDebugInfoSize
= req
->event
.info
.load_dll
.dbg_size
;
77 event
->u
.LoadDll
.lpImageName
= req
->event
.info
.load_dll
.name
;
78 event
->u
.LoadDll
.fUnicode
= req
->event
.info
.load_dll
.unicode
;
79 if (req
->event
.info
.load_dll
.handle
== -1) event
->u
.LoadDll
.hFile
= 0;
81 case UNLOAD_DLL_DEBUG_EVENT
:
82 event
->u
.UnloadDll
.lpBaseOfDll
= req
->event
.info
.unload_dll
.base
;
84 case OUTPUT_DEBUG_STRING_EVENT
:
85 event
->u
.DebugString
.lpDebugStringData
= req
->event
.info
.output_string
.string
;
86 event
->u
.DebugString
.fUnicode
= req
->event
.info
.output_string
.unicode
;
87 event
->u
.DebugString
.nDebugStringLength
= req
->event
.info
.output_string
.length
;
90 event
->u
.RipInfo
.dwError
= req
->event
.info
.rip_info
.error
;
91 event
->u
.RipInfo
.dwType
= req
->event
.info
.rip_info
.type
;
98 /**********************************************************************
99 * ContinueDebugEvent (KERNEL32.146)
101 BOOL WINAPI
ContinueDebugEvent( DWORD pid
, DWORD tid
, DWORD status
)
103 struct continue_debug_event_request
*req
= get_req_buffer();
104 req
->pid
= (void *)pid
;
105 req
->tid
= (void *)tid
;
106 req
->status
= status
;
107 return !server_call( REQ_CONTINUE_DEBUG_EVENT
);
111 /**********************************************************************
112 * DebugActiveProcess (KERNEL32.180)
114 BOOL WINAPI
DebugActiveProcess( DWORD pid
)
116 struct debug_process_request
*req
= get_req_buffer();
117 req
->pid
= (void *)pid
;
118 return !server_call( REQ_DEBUG_PROCESS
);
122 /***********************************************************************
123 * OutputDebugStringA (KERNEL32.548)
125 void WINAPI
OutputDebugStringA( LPCSTR str
)
127 struct output_debug_string_request
*req
= get_req_buffer();
128 req
->string
= (void *)str
;
130 req
->length
= strlen(str
) + 1;
131 server_call_noerr( REQ_OUTPUT_DEBUG_STRING
);
136 /***********************************************************************
137 * OutputDebugStringW (KERNEL32.549)
139 void WINAPI
OutputDebugStringW( LPCWSTR str
)
141 struct output_debug_string_request
*req
= get_req_buffer();
142 req
->string
= (void *)str
;
144 req
->length
= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
145 server_call_noerr( REQ_OUTPUT_DEBUG_STRING
);
146 TRACE("%s\n", debugstr_w(str
));
150 /***********************************************************************
151 * OutputDebugString16 (KERNEL.115)
153 void WINAPI
OutputDebugString16( LPCSTR str
)
155 OutputDebugStringA( str
);
159 /***********************************************************************
160 * DebugBreak (KERNEL32.181)
162 void WINAPI
DebugBreak(void)
168 /***********************************************************************
169 * DebugBreak16 (KERNEL.203)
171 void WINAPI
DebugBreak16( CONTEXT86
*context
)
174 EXCEPTION_RECORD rec
;
176 rec
.ExceptionCode
= EXCEPTION_BREAKPOINT
;
177 rec
.ExceptionFlags
= 0;
178 rec
.ExceptionRecord
= NULL
;
179 rec
.ExceptionAddress
= GET_IP(context
);
180 rec
.NumberParameters
= 0;
181 NtRaiseException( &rec
, context
, TRUE
);
182 #endif /* defined(__i386__) */
186 /***********************************************************************
187 * IsDebuggerPresent (KERNEL32)
189 BOOL WINAPI
IsDebuggerPresent(void)
192 struct get_process_info_request
*req
= get_req_buffer();
193 req
->handle
= GetCurrentProcess();
194 if (!server_call( REQ_GET_PROCESS_INFO
)) ret
= req
->debugged
;