makefiles: Don't use standard libs for programs that specify -nodefaultlibs.
[wine/zf.git] / dlls / kernel32 / debugger.c
blobf9d398fd351f7a1b27f65c9b57af6fb42ca9100b
1 /*
2 * Win32 debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include <stdio.h>
23 #include <string.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "winerror.h"
28 #include "wine/server.h"
29 #include "kernel_private.h"
30 #include "wine/asm.h"
31 #include "wine/debug.h"
32 #include "wine/exception.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(debugstr);
36 static LONG WINAPI debug_exception_handler( EXCEPTION_POINTERS *eptr )
38 EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
39 return (rec->ExceptionCode == DBG_PRINTEXCEPTION_C) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
42 /***********************************************************************
43 * OutputDebugStringA (KERNEL32.@)
45 * Duplicate since IMVU doesn't like it if we call kernelbase.OutputDebugStringA.
47 void WINAPI DECLSPEC_HOTPATCH OutputDebugStringA( LPCSTR str )
49 static HANDLE DBWinMutex = NULL;
50 static BOOL mutex_inited = FALSE;
51 BOOL caught_by_dbg = TRUE;
53 if (!str) str = "";
54 WARN( "%s\n", debugstr_a(str) );
56 /* raise exception, WaitForDebugEvent() will generate a corresponding debug event */
57 __TRY
59 ULONG_PTR args[2];
60 args[0] = strlen(str) + 1;
61 args[1] = (ULONG_PTR)str;
62 RaiseException( DBG_PRINTEXCEPTION_C, 0, 2, args );
64 __EXCEPT(debug_exception_handler)
66 caught_by_dbg = FALSE;
68 __ENDTRY
69 if (caught_by_dbg) return;
71 /* send string to a system-wide monitor */
72 if (!mutex_inited)
74 /* first call to OutputDebugString, initialize mutex handle */
75 static const WCHAR mutexname[] = {'D','B','W','i','n','M','u','t','e','x',0};
76 HANDLE mutex = CreateMutexExW( NULL, mutexname, 0, SYNCHRONIZE );
77 if (mutex)
79 if (InterlockedCompareExchangePointer( &DBWinMutex, mutex, 0 ) != 0)
80 /* someone beat us here... */
81 CloseHandle( mutex );
83 mutex_inited = TRUE;
86 if (DBWinMutex)
88 static const WCHAR shmname[] = {'D','B','W','I','N','_','B','U','F','F','E','R',0};
89 static const WCHAR eventbuffername[] = {'D','B','W','I','N','_','B','U','F','F','E','R','_','R','E','A','D','Y',0};
90 static const WCHAR eventdataname[] = {'D','B','W','I','N','_','D','A','T','A','_','R','E','A','D','Y',0};
91 HANDLE mapping;
93 mapping = OpenFileMappingW( FILE_MAP_WRITE, FALSE, shmname );
94 if (mapping)
96 LPVOID buffer;
97 HANDLE eventbuffer, eventdata;
99 buffer = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
100 eventbuffer = OpenEventW( SYNCHRONIZE, FALSE, eventbuffername );
101 eventdata = OpenEventW( EVENT_MODIFY_STATE, FALSE, eventdataname );
103 if (buffer && eventbuffer && eventdata)
105 /* monitor is present, synchronize with other OutputDebugString invocations */
106 WaitForSingleObject( DBWinMutex, INFINITE );
108 /* acquire control over the buffer */
109 if (WaitForSingleObject( eventbuffer, 10000 ) == WAIT_OBJECT_0)
111 int str_len = strlen( str );
112 struct _mon_buffer_t
114 DWORD pid;
115 char buffer[1];
116 } *mon_buffer = (struct _mon_buffer_t*) buffer;
118 if (str_len > (4096 - sizeof(DWORD) - 1)) str_len = 4096 - sizeof(DWORD) - 1;
119 mon_buffer->pid = GetCurrentProcessId();
120 memcpy( mon_buffer->buffer, str, str_len );
121 mon_buffer->buffer[str_len] = 0;
123 /* signal data ready */
124 SetEvent( eventdata );
126 ReleaseMutex( DBWinMutex );
129 if (buffer) UnmapViewOfFile( buffer );
130 if (eventbuffer) CloseHandle( eventbuffer );
131 if (eventdata) CloseHandle( eventdata );
132 CloseHandle( mapping );
138 /***********************************************************************
139 * DebugBreakProcess (KERNEL32.@)
141 * Raises an exception so that a debugger (if attached)
142 * can take some action. Same as DebugBreak, but applies to any process.
144 * PARAMS
145 * hProc [I] Process to break into.
147 * RETURNS
149 * True if successful.
151 BOOL WINAPI DebugBreakProcess(HANDLE process)
153 NTSTATUS status;
155 TRACE("(%p)\n", process);
157 status = DbgUiIssueRemoteBreakin(process);
158 if (status) SetLastError(RtlNtStatusToDosError(status));
159 return !status;
163 /***********************************************************************
164 * DebugSetProcessKillOnExit (KERNEL32.@)
166 * Let a debugger decide whether a debuggee will be killed upon debugger
167 * termination.
169 * PARAMS
170 * kill [I] If set to true then kill the process on exit.
172 * RETURNS
173 * True if successful, false otherwise.
175 BOOL WINAPI DebugSetProcessKillOnExit(BOOL kill)
177 BOOL ret = FALSE;
179 SERVER_START_REQ( set_debugger_kill_on_exit )
181 req->kill_on_exit = kill;
182 ret = !wine_server_call_err( req );
184 SERVER_END_REQ;
185 return ret;