Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c04f4051
Commit
c04f4051
authored
Aug 15, 2001
by
Eric Pouech
Committed by
Alexandre Julliard
Aug 15, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Modified the debugger launching code so that only one instance of the
debugger is created per process.
parent
20bc491d
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
147 additions
and
86 deletions
+147
-86
except.c
win32/except.c
+147
-86
No files found.
win32/except.c
View file @
c04f4051
...
...
@@ -186,50 +186,22 @@ static int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *c
return
ret
;
}
/*******************************************************************
* UnhandledExceptionFilter (KERNEL32.@)
/******************************************************************
* start_debugger
*
* Does the effective debugger startup according to 'format'
*/
DWORD
WINAPI
UnhandledExceptionFilter
(
PEXCEPTION_POINTERS
epointers
)
static
BOOL
start_debugger
(
PEXCEPTION_POINTERS
epointers
,
HANDLE
hEvent
)
{
char
format
[
256
];
char
buffer
[
256
];
HKEY
hDbgConf
;
DWORD
bAuto
=
FALSE
;
DWORD
ret
=
EXCEPTION_EXECUTE_HANDLER
;
int
status
;
/* send a last chance event to the debugger */
status
=
send_debug_event
(
epointers
->
ExceptionRecord
,
FALSE
,
epointers
->
ContextRecord
);
switch
(
status
)
{
case
DBG_CONTINUE
:
return
EXCEPTION_CONTINUE_EXECUTION
;
case
DBG_EXCEPTION_NOT_HANDLED
:
TerminateProcess
(
GetCurrentProcess
(),
epointers
->
ExceptionRecord
->
ExceptionCode
);
break
;
/* not reached */
case
0
:
/* no debugger is present */
if
(
epointers
->
ExceptionRecord
->
ExceptionCode
==
CONTROL_C_EXIT
)
{
/* do not launch the debugger on ^C, simply terminate the process */
TerminateProcess
(
GetCurrentProcess
(),
1
);
}
break
;
default:
FIXME
(
"Unsupported yet debug continue value %d (please report)
\n
"
,
status
);
}
if
(
top_filter
)
{
DWORD
ret
=
top_filter
(
epointers
);
if
(
ret
!=
EXCEPTION_CONTINUE_SEARCH
)
return
ret
;
}
/* FIXME: Should check the current error mode */
PROCESS_INFORMATION
info
;
STARTUPINFOA
startup
;
char
buffer
[
256
];
char
format
[
256
];
if
(
!
RegOpenKeyA
(
HKEY_LOCAL_MACHINE
,
"Software
\\
Microsoft
\\
Windows NT
\\
CurrentVersion
\\
AeDebug"
,
&
hDbgConf
))
{
"Software
\\
Microsoft
\\
Windows NT
\\
CurrentVersion
\\
AeDebug"
,
&
hDbgConf
))
{
DWORD
type
;
DWORD
count
;
...
...
@@ -249,61 +221,150 @@ DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
}
RegCloseKey
(
hDbgConf
);
}
else
{
/* format[0] = 0;
*/
strcpy
(
format
,
"debugger/winedbg %ld %ld"
);
/* try a default setup...
*/
strcpy
(
format
,
"debugger/winedbg %ld %ld"
);
}
if
(
!
bAuto
)
{
HMODULE
mod
=
GetModuleHandleA
(
"user32.dll"
);
MessageBoxA_funcptr
pMessageBoxA
=
NULL
;
if
(
mod
)
pMessageBoxA
=
(
MessageBoxA_funcptr
)
GetProcAddress
(
mod
,
"MessageBoxA"
);
if
(
pMessageBoxA
)
{
format_exception_msg
(
epointers
,
buffer
,
sizeof
(
buffer
)
);
if
(
pMessageBoxA
(
0
,
buffer
,
"Exception raised"
,
MB_YESNO
|
MB_ICONHAND
)
==
IDNO
)
{
TRACE
(
"Killing process
\n
"
);
return
EXCEPTION_EXECUTE_HANDLER
;
}
}
HMODULE
mod
=
GetModuleHandleA
(
"user32.dll"
);
MessageBoxA_funcptr
pMessageBoxA
=
NULL
;
if
(
mod
)
pMessageBoxA
=
(
MessageBoxA_funcptr
)
GetProcAddress
(
mod
,
"MessageBoxA"
);
if
(
pMessageBoxA
)
{
format_exception_msg
(
epointers
,
buffer
,
sizeof
(
buffer
)
);
if
(
pMessageBoxA
(
0
,
buffer
,
"Exception raised"
,
MB_YESNO
|
MB_ICONHAND
)
==
IDNO
)
{
TRACE
(
"Killing process
\n
"
);
return
FALSE
;
}
}
}
if
(
format
[
0
])
{
HANDLE
hEvent
;
PROCESS_INFORMATION
info
;
STARTUPINFOA
startup
;
OBJECT_ATTRIBUTES
attr
;
attr
.
Length
=
sizeof
(
attr
);
attr
.
RootDirectory
=
0
;
attr
.
Attributes
=
OBJ_INHERIT
;
attr
.
ObjectName
=
NULL
;
attr
.
SecurityDescriptor
=
NULL
;
attr
.
SecurityQualityOfService
=
NULL
;
TRACE
(
"Starting debugger (fmt=%s)
\n
"
,
format
);
NtCreateEvent
(
&
hEvent
,
EVENT_ALL_ACCESS
,
&
attr
,
FALSE
,
FALSE
);
sprintf
(
buffer
,
format
,
GetCurrentProcessId
(),
hEvent
);
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
if
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
TRUE
,
0
,
NULL
,
NULL
,
&
startup
,
&
info
))
{
WaitForSingleObject
(
hEvent
,
INFINITE
);
ret
=
EXCEPTION_CONTINUE_SEARCH
;
}
else
{
ERR
(
"Couldn't start debugger (%s) (%ld)
\n
"
"Read the Wine Developers Guide on how to set up winedbg or another debugger
\n
"
,
buffer
,
GetLastError
());
}
CloseHandle
(
hEvent
);
}
else
{
ERR
(
"No standard debugger defined in the registry => no debugging session
\n
"
);
TRACE
(
"Starting debugger (fmt=%s)
\n
"
,
format
);
sprintf
(
buffer
,
format
,
GetCurrentProcessId
(),
hEvent
);
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
if
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
TRUE
,
0
,
NULL
,
NULL
,
&
startup
,
&
info
))
{
/* wait for debugger to come up... */
WaitForSingleObject
(
hEvent
,
INFINITE
);
return
TRUE
;
}
return
ret
;
ERR
(
"Couldn't start debugger (%s) (%ld)
\n
"
"Read the Wine Developers Guide on how to set up winedbg or another debugger
\n
"
,
buffer
,
GetLastError
());
return
FALSE
;
}
/******************************************************************
* start_debugger_atomic
*
* starts the debugger is an atomic way:
* - either the debugger is not started and it is started
* - either the debugger has already been started by an other thread
* - either the debugger couldn't be started
*
* returns TRUE for the two first condition, FALSE for the last
*/
static
int
start_debugger_atomic
(
PEXCEPTION_POINTERS
epointers
)
{
static
HANDLE
hRunOnce
/* = 0 */
;
if
(
hRunOnce
==
0
)
{
OBJECT_ATTRIBUTES
attr
;
HANDLE
hEvent
;
attr
.
Length
=
sizeof
(
attr
);
attr
.
RootDirectory
=
0
;
attr
.
Attributes
=
OBJ_INHERIT
;
attr
.
ObjectName
=
NULL
;
attr
.
SecurityDescriptor
=
NULL
;
attr
.
SecurityQualityOfService
=
NULL
;
/* ask for manual reset, so that once the debugger is started, every thread will be
* know it
*/
NtCreateEvent
(
&
hEvent
,
EVENT_ALL_ACCESS
,
&
attr
,
TRUE
,
FALSE
);
if
(
InterlockedCompareExchange
(
(
LPLONG
)
&
hRunOnce
,
hEvent
,
0
)
==
0
)
{
/* ok, our event has been set... we're the winning thread */
BOOL
ret
=
start_debugger
(
epointers
,
hRunOnce
);
DWORD
tmp
;
if
(
!
ret
)
{
/* so that the other threads won't be stuck */
NtSetEvent
(
hRunOnce
,
&
tmp
);
}
return
ret
;
}
/* someone beat us here... */
CloseHandle
(
hEvent
);
}
/* and wait for the winner to have actually created the debugger */
WaitForSingleObject
(
hRunOnce
,
INFINITE
);
/* in fact, here, we only know that someone has tried to start the debugger, we'll know
* by reposting the exception if it has actually attached to the current process
*/
return
TRUE
;
}
/*******************************************************************
* UnhandledExceptionFilter (KERNEL32.@)
*/
DWORD
WINAPI
UnhandledExceptionFilter
(
PEXCEPTION_POINTERS
epointers
)
{
int
status
;
int
loop
=
0
;
for
(
loop
=
0
;
loop
<=
1
;
loop
++
)
{
/* send a last chance event to the debugger */
status
=
send_debug_event
(
epointers
->
ExceptionRecord
,
FALSE
,
epointers
->
ContextRecord
);
switch
(
status
)
{
case
DBG_CONTINUE
:
return
EXCEPTION_CONTINUE_EXECUTION
;
case
DBG_EXCEPTION_NOT_HANDLED
:
TerminateProcess
(
GetCurrentProcess
(),
epointers
->
ExceptionRecord
->
ExceptionCode
);
break
;
/* not reached */
case
0
:
/* no debugger is present */
if
(
epointers
->
ExceptionRecord
->
ExceptionCode
==
CONTROL_C_EXIT
)
{
/* do not launch the debugger on ^C, simply terminate the process */
TerminateProcess
(
GetCurrentProcess
(),
1
);
}
/* second try, the debugger isn't present... */
if
(
loop
==
1
)
return
EXCEPTION_EXECUTE_HANDLER
;
break
;
default:
FIXME
(
"Unsupported yet debug continue value %d (please report)
\n
"
,
status
);
return
EXCEPTION_EXECUTE_HANDLER
;
}
/* should only be there when loop == 0 */
if
(
top_filter
)
{
DWORD
ret
=
top_filter
(
epointers
);
if
(
ret
!=
EXCEPTION_CONTINUE_SEARCH
)
return
ret
;
}
/* FIXME: Should check the current error mode */
if
(
!
start_debugger_atomic
(
epointers
))
return
EXCEPTION_EXECUTE_HANDLER
;
/* now that we should have a debugger attached, try to resend event */
}
return
EXCEPTION_EXECUTE_HANDLER
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment