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
30 #include "kernel_private.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
;
57 WARN( "%s\n", debugstr_a(str
) );
59 /* raise exception, WaitForDebugEvent() will generate a corresponding debug event */
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
;
72 if (caught_by_dbg
) return;
74 /* send string to a system-wide monitor */
77 /* first call to OutputDebugString, initialize mutex handle */
78 HANDLE mutex
= CreateMutexExW( NULL
, L
"DBWinMutex", 0, SYNCHRONIZE
);
81 if (InterlockedCompareExchangePointer( &DBWinMutex
, mutex
, 0 ) != 0)
82 /* someone beat us here... */
92 mapping
= OpenFileMappingW( FILE_MAP_WRITE
, FALSE
, L
"DBWIN_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
);
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.
144 * hProc [I] Process to break into.
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
163 * kill [I] If set to true then kill the process on exit.
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
));