kernel32: Use wide-char string literals.
[wine.git] / dlls / kernel32 / debugger.c
blobb80b0f0afd1fdc8d95d6a494c1c68b460e1dccbe
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 <stdio.h>
22 #include <string.h>
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "winerror.h"
27 #include "wine/server.h"
28 #include "kernel_private.h"
29 #include "wine/asm.h"
30 #include "wine/debug.h"
31 #include "wine/exception.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(debugstr);
35 void *dummy = RtlUnwind; /* force importing RtlUnwind from ntdll */
37 static LONG WINAPI debug_exception_handler( EXCEPTION_POINTERS *eptr )
39 EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
40 return (rec->ExceptionCode == DBG_PRINTEXCEPTION_C) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
43 /***********************************************************************
44 * OutputDebugStringA (KERNEL32.@)
46 * Duplicate since IMVU doesn't like it if we call kernelbase.OutputDebugStringA.
48 void WINAPI DECLSPEC_HOTPATCH OutputDebugStringA( LPCSTR str )
50 static HANDLE DBWinMutex = NULL;
51 static BOOL mutex_inited = FALSE;
52 BOOL caught_by_dbg = TRUE;
54 if (!str) str = "";
55 WARN( "%s\n", debugstr_a(str) );
57 /* raise exception, WaitForDebugEvent() will generate a corresponding debug event */
58 __TRY
60 ULONG_PTR args[2];
61 args[0] = strlen(str) + 1;
62 args[1] = (ULONG_PTR)str;
63 RaiseException( DBG_PRINTEXCEPTION_C, 0, 2, args );
65 __EXCEPT(debug_exception_handler)
67 caught_by_dbg = FALSE;
69 __ENDTRY
70 if (caught_by_dbg) return;
72 /* send string to a system-wide monitor */
73 if (!mutex_inited)
75 /* first call to OutputDebugString, initialize mutex handle */
76 HANDLE mutex = CreateMutexExW( NULL, L"DBWinMutex", 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 HANDLE mapping;
90 mapping = OpenFileMappingW( FILE_MAP_WRITE, FALSE, L"DBWIN_BUFFER" );
91 if (mapping)
93 LPVOID buffer;
94 HANDLE eventbuffer, eventdata;
96 buffer = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
97 eventbuffer = OpenEventW( SYNCHRONIZE, FALSE, L"DBWIN_BUFFER_READY" );
98 eventdata = OpenEventW( EVENT_MODIFY_STATE, FALSE, L"DBWIN_DATA_READY" );
100 if (buffer && eventbuffer && eventdata)
102 /* monitor is present, synchronize with other OutputDebugString invocations */
103 WaitForSingleObject( DBWinMutex, INFINITE );
105 /* acquire control over the buffer */
106 if (WaitForSingleObject( eventbuffer, 10000 ) == WAIT_OBJECT_0)
108 int str_len = strlen( str );
109 struct _mon_buffer_t
111 DWORD pid;
112 char buffer[1];
113 } *mon_buffer = (struct _mon_buffer_t*) buffer;
115 if (str_len > (4096 - sizeof(DWORD) - 1)) str_len = 4096 - sizeof(DWORD) - 1;
116 mon_buffer->pid = GetCurrentProcessId();
117 memcpy( mon_buffer->buffer, str, str_len );
118 mon_buffer->buffer[str_len] = 0;
120 /* signal data ready */
121 SetEvent( eventdata );
123 ReleaseMutex( DBWinMutex );
126 if (buffer) UnmapViewOfFile( buffer );
127 if (eventbuffer) CloseHandle( eventbuffer );
128 if (eventdata) CloseHandle( eventdata );
129 CloseHandle( mapping );
135 /***********************************************************************
136 * DebugBreakProcess (KERNEL32.@)
138 * Raises an exception so that a debugger (if attached)
139 * can take some action. Same as DebugBreak, but applies to any process.
141 * PARAMS
142 * hProc [I] Process to break into.
144 * RETURNS
146 * True if successful.
148 BOOL WINAPI DebugBreakProcess(HANDLE process)
150 return set_ntstatus( DbgUiIssueRemoteBreakin( process ));
154 /***********************************************************************
155 * DebugSetProcessKillOnExit (KERNEL32.@)
157 * Let a debugger decide whether a debuggee will be killed upon debugger
158 * termination.
160 * PARAMS
161 * kill [I] If set to true then kill the process on exit.
163 * RETURNS
164 * True if successful, false otherwise.
166 BOOL WINAPI DebugSetProcessKillOnExit(BOOL kill)
168 BOOL ret = FALSE;
170 SERVER_START_REQ( set_debugger_kill_on_exit )
172 req->kill_on_exit = kill;
173 ret = !wine_server_call_err( req );
175 SERVER_END_REQ;
176 return ret;