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
25 #define WIN32_NO_STATUS
27 #include "wine/server.h"
28 #include "kernel_private.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
;
55 WARN( "%s\n", debugstr_a(str
) );
57 /* raise exception, WaitForDebugEvent() will generate a corresponding debug event */
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
;
70 if (caught_by_dbg
) return;
72 /* send string to a system-wide monitor */
75 /* first call to OutputDebugString, initialize mutex handle */
76 HANDLE mutex
= CreateMutexExW( NULL
, L
"DBWinMutex", 0, SYNCHRONIZE
);
79 if (InterlockedCompareExchangePointer( &DBWinMutex
, mutex
, 0 ) != 0)
80 /* someone beat us here... */
90 mapping
= OpenFileMappingW( FILE_MAP_WRITE
, FALSE
, L
"DBWIN_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
);
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.
142 * hProc [I] Process to break into.
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
161 * kill [I] If set to true then kill the process on exit.
164 * True if successful, false otherwise.
166 BOOL WINAPI
DebugSetProcessKillOnExit(BOOL kill
)
170 SERVER_START_REQ( set_debugger_kill_on_exit
)
172 req
->kill_on_exit
= kill
;
173 ret
= !wine_server_call_err( req
);