include: Make sure __int64 is correctly defined on PPC64.
[wine.git] / dlls / kernel32 / debugger.c
blob6ccce02a8f3ff641c0009cdda44ee3a39d55e105
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 "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "winternl.h"
30 #include "kernel_private.h"
31 #include "wine/asm.h"
32 #include "wine/debug.h"
33 #include "wine/exception.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(debugstr);
37 void *dummy = RtlUnwind; /* force importing RtlUnwind from ntdll */
39 static LONG WINAPI debug_exception_handler( EXCEPTION_POINTERS *eptr )
41 EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
42 return (rec->ExceptionCode == DBG_PRINTEXCEPTION_C) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
45 /***********************************************************************
46 * OutputDebugStringA (KERNEL32.@)
48 * Duplicate since IMVU doesn't like it if we call kernelbase.OutputDebugStringA.
50 void WINAPI DECLSPEC_HOTPATCH OutputDebugStringA( LPCSTR str )
52 static HANDLE DBWinMutex = NULL;
53 static BOOL mutex_inited = FALSE;
54 BOOL caught_by_dbg = TRUE;
56 if (!str) str = "";
57 WARN( "%s\n", debugstr_a(str) );
59 /* raise exception, WaitForDebugEvent() will generate a corresponding debug event */
60 __TRY
62 ULONG_PTR args[2];
63 args[0] = strlen(str) + 1;
64 args[1] = (ULONG_PTR)str;
65 RaiseException( DBG_PRINTEXCEPTION_C, 0, 2, args );
67 __EXCEPT(debug_exception_handler)
69 caught_by_dbg = FALSE;
71 __ENDTRY
72 if (caught_by_dbg) return;
74 /* send string to a system-wide monitor */
75 if (!mutex_inited)
77 /* first call to OutputDebugString, initialize mutex handle */
78 HANDLE mutex = CreateMutexExW( NULL, L"DBWinMutex", 0, SYNCHRONIZE );
79 if (mutex)
81 if (InterlockedCompareExchangePointer( &DBWinMutex, mutex, 0 ) != 0)
82 /* someone beat us here... */
83 CloseHandle( mutex );
85 mutex_inited = TRUE;
88 if (DBWinMutex)
90 HANDLE mapping;
92 mapping = OpenFileMappingW( FILE_MAP_WRITE, FALSE, L"DBWIN_BUFFER" );
93 if (mapping)
95 LPVOID buffer;
96 HANDLE eventbuffer, eventdata;
98 buffer = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
99 eventbuffer = OpenEventW( SYNCHRONIZE, FALSE, L"DBWIN_BUFFER_READY" );
100 eventdata = OpenEventW( EVENT_MODIFY_STATE, FALSE, L"DBWIN_DATA_READY" );
102 if (buffer && eventbuffer && eventdata)
104 /* monitor is present, synchronize with other OutputDebugString invocations */
105 WaitForSingleObject( DBWinMutex, INFINITE );
107 /* acquire control over the buffer */
108 if (WaitForSingleObject( eventbuffer, 10000 ) == WAIT_OBJECT_0)
110 int str_len = strlen( str );
111 struct _mon_buffer_t
113 DWORD pid;
114 char buffer[1];
115 } *mon_buffer = (struct _mon_buffer_t*) buffer;
117 if (str_len > (4096 - sizeof(DWORD) - 1)) str_len = 4096 - sizeof(DWORD) - 1;
118 mon_buffer->pid = GetCurrentProcessId();
119 memcpy( mon_buffer->buffer, str, str_len );
120 mon_buffer->buffer[str_len] = 0;
122 /* signal data ready */
123 SetEvent( eventdata );
125 ReleaseMutex( DBWinMutex );
128 if (buffer) UnmapViewOfFile( buffer );
129 if (eventbuffer) CloseHandle( eventbuffer );
130 if (eventdata) CloseHandle( eventdata );
131 CloseHandle( mapping );
137 /***********************************************************************
138 * DebugBreakProcess (KERNEL32.@)
140 * Raises an exception so that a debugger (if attached)
141 * can take some action. Same as DebugBreak, but applies to any process.
143 * PARAMS
144 * hProc [I] Process to break into.
146 * RETURNS
148 * True if successful.
150 BOOL WINAPI DebugBreakProcess(HANDLE process)
152 return set_ntstatus( DbgUiIssueRemoteBreakin( process ));
156 /***********************************************************************
157 * DebugSetProcessKillOnExit (KERNEL32.@)
159 * Let a debugger decide whether a debuggee will be killed upon debugger
160 * termination.
162 * PARAMS
163 * kill [I] If set to true then kill the process on exit.
165 * RETURNS
166 * True if successful, false otherwise.
168 BOOL WINAPI DebugSetProcessKillOnExit(BOOL kill)
170 ULONG flag = kill ? DEBUG_KILL_ON_CLOSE : 0;
172 return set_ntstatus( NtSetInformationDebugObject( DbgUiGetThreadDebugObject(),
173 DebugObjectKillProcessOnExitInformation,
174 &flag, sizeof(flag), NULL ));