Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
fbccb38e
Commit
fbccb38e
authored
Feb 27, 2002
by
Eric Pouech
Committed by
Alexandre Julliard
Feb 27, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New XP debugging APIs: implemented DebugActiveProcessStop,
DebugSetProcessKillOnExit, DebugBreakProcess.
parent
b66ab302
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
224 additions
and
9 deletions
+224
-9
debugger.c
dlls/kernel/debugger.c
+71
-1
kernel32.spec
dlls/kernel/kernel32.spec
+5
-0
winbase.h
include/winbase.h
+3
-0
server_protocol.h
include/wine/server_protocol.h
+17
-1
debugger.c
server/debugger.c
+90
-4
process.c
server/process.c
+15
-1
process.h
server/process.h
+3
-0
protocol.def
server/protocol.def
+8
-1
request.h
server/request.h
+2
-0
trace.c
server/trace.c
+10
-1
No files found.
dlls/kernel/debugger.c
View file @
fbccb38e
...
...
@@ -150,7 +150,7 @@ BOOL WINAPI ContinueDebugEvent(
/**********************************************************************
* DebugActiveProcess (KERNEL32.@)
*
* Attempts to attach the dugger to a process.
* Attempts to attach the d
eb
ugger to a process.
*
* RETURNS
*
...
...
@@ -163,6 +163,30 @@ BOOL WINAPI DebugActiveProcess(
SERVER_START_REQ
(
debug_process
)
{
req
->
pid
=
(
void
*
)
pid
;
req
->
attach
=
1
;
ret
=
!
wine_server_call_err
(
req
);
}
SERVER_END_REQ
;
return
ret
;
}
/**********************************************************************
* DebugActiveProcessStop (KERNEL32.@)
*
* Attempts to detach the debugger from a process.
*
* RETURNS
*
* True if the debugger was detached from the process.
*/
BOOL
WINAPI
DebugActiveProcessStop
(
DWORD
pid
)
/* [in] The process to be detached. */
{
BOOL
ret
;
SERVER_START_REQ
(
debug_process
)
{
req
->
pid
=
(
void
*
)
pid
;
req
->
attach
=
0
;
ret
=
!
wine_server_call_err
(
req
);
}
SERVER_END_REQ
;
...
...
@@ -236,6 +260,32 @@ void WINAPI DebugBreak(void)
DbgBreakPoint
();
}
/***********************************************************************
* DebugBreakProcess (KERNEL32.@)
*
* Raises an exception so that a debugger (if attached)
* can take some action. Same as DebugBreak, but applies to any process.
*/
BOOL
WINAPI
DebugBreakProcess
(
HANDLE
hProc
)
{
#if 0 /* FIXME: not correct */
int res;
int pid;
TRACE("(%08lx)\n", (DWORD)hProc);
SERVER_START_REQ( get_process_info )
{
req->handle = hProc;
res = wine_server_call_err( req );
pid = (int)reply->pid;
}
SERVER_END_REQ;
return !res && kill(pid, SIGINT) == 0;
#endif
return
FALSE
;
}
/***********************************************************************
* DebugBreak (KERNEL.203)
...
...
@@ -309,3 +359,23 @@ void WINAPIV _DebugOutput( void )
/* Output */
FIXME
(
"%s %04x %s
\n
"
,
caller
,
flags
,
debugstr_a
(
MapSL
(
spec
))
);
}
/***********************************************************************
* DebugSetProcessKillOnExit (KERNEL.328)
*
* Let a debugger decide wether a debuggee will be killed upon debugger
* termination
*/
BOOL
WINAPI
DebugSetProcessKillOnExit
(
BOOL
kill
)
{
BOOL
ret
=
FALSE
;
SERVER_START_REQ
(
set_debugger_kill_on_exit
)
{
req
->
kill_on_exit
=
kill
;
ret
=
!
wine_server_call_err
(
req
);
}
SERVER_END_REQ
;
return
ret
;
}
dlls/kernel/kernel32.spec
View file @
fbccb38e
...
...
@@ -970,6 +970,11 @@ debug_channels (comm console debugstr dll int resource stress thunk toolhelp
@ stdcall SetCalendarInfoA(long long long str) SetCalendarInfoA
@ stdcall SetCalendarInfoW(long long long wstr) SetCalendarInfoW
# XP extensions
@ stdcall DebugActiveProcessStop(long) DebugActiveProcessStop
@ stdcall DebugBreakProcess(long) DebugBreakProcess
@ stdcall DebugSetProcessKillOnExit(long) DebugSetProcessKillOnExit
################################################################
# Wine extensions: Win16 functions that are needed by other dlls
#
...
...
include/winbase.h
View file @
fbccb38e
...
...
@@ -1135,7 +1135,10 @@ HANDLE WINAPI CreateWaitableTimerA(LPSECURITY_ATTRIBUTES,BOOL,LPCSTR);
HANDLE
WINAPI
CreateWaitableTimerW
(
LPSECURITY_ATTRIBUTES
,
BOOL
,
LPCWSTR
);
#define CreateWaitableTimer WINELIB_NAME_AW(CreateWaitableTimer)
BOOL
WINAPI
DebugActiveProcess
(
DWORD
);
BOOL
WINAPI
DebugActiveProcessStop
(
DWORD
);
void
WINAPI
DebugBreak
(
void
);
BOOL
WINAPI
DebugBreakProcess
(
HANDLE
);
BOOL
WINAPI
DebugSetProcessKillOnExit
(
BOOL
);
BOOL
WINAPI
DeregisterEventSource
(
HANDLE
);
BOOL
WINAPI
DeviceIoControl
(
HANDLE
,
DWORD
,
LPVOID
,
DWORD
,
LPVOID
,
DWORD
,
LPDWORD
,
LPOVERLAPPED
);
BOOL
WINAPI
DisableThreadLibraryCalls
(
HMODULE
);
...
...
include/wine/server_protocol.h
View file @
fbccb38e
...
...
@@ -1554,6 +1554,7 @@ struct debug_process_request
{
struct
request_header
__header
;
void
*
pid
;
int
attach
;
};
struct
debug_process_reply
{
...
...
@@ -1562,6 +1563,18 @@ struct debug_process_reply
struct
set_debugger_kill_on_exit_request
{
struct
request_header
__header
;
int
kill_on_exit
;
};
struct
set_debugger_kill_on_exit_reply
{
struct
reply_header
__header
;
};
struct
read_process_memory_request
{
struct
request_header
__header
;
...
...
@@ -2668,6 +2681,7 @@ enum request
REQ_output_debug_string
,
REQ_continue_debug_event
,
REQ_debug_process
,
REQ_set_debugger_kill_on_exit
,
REQ_read_process_memory
,
REQ_write_process_memory
,
REQ_create_key
,
...
...
@@ -2823,6 +2837,7 @@ union generic_request
struct
output_debug_string_request
output_debug_string_request
;
struct
continue_debug_event_request
continue_debug_event_request
;
struct
debug_process_request
debug_process_request
;
struct
set_debugger_kill_on_exit_request
set_debugger_kill_on_exit_request
;
struct
read_process_memory_request
read_process_memory_request
;
struct
write_process_memory_request
write_process_memory_request
;
struct
create_key_request
create_key_request
;
...
...
@@ -2976,6 +2991,7 @@ union generic_reply
struct
output_debug_string_reply
output_debug_string_reply
;
struct
continue_debug_event_reply
continue_debug_event_reply
;
struct
debug_process_reply
debug_process_reply
;
struct
set_debugger_kill_on_exit_reply
set_debugger_kill_on_exit_reply
;
struct
read_process_memory_reply
read_process_memory_reply
;
struct
write_process_memory_reply
write_process_memory_reply
;
struct
create_key_reply
create_key_reply
;
...
...
@@ -3043,6 +3059,6 @@ union generic_reply
struct
get_window_properties_reply
get_window_properties_reply
;
};
#define SERVER_PROTOCOL_VERSION 7
0
#define SERVER_PROTOCOL_VERSION 7
1
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/debugger.c
View file @
fbccb38e
...
...
@@ -38,6 +38,7 @@ struct debug_ctx
struct
object
obj
;
/* object header */
struct
debug_event
*
event_head
;
/* head of pending events queue */
struct
debug_event
*
event_tail
;
/* tail of pending events queue */
int
kill_on_exit
;
/* kill debuggees on debugger exit ? */
};
...
...
@@ -422,11 +423,13 @@ static int debugger_attach( struct process *process, struct thread *debugger )
/* we must have been able to attach all threads */
for
(
thread
=
process
->
thread_list
;
thread
;
thread
=
thread
->
proc_next
)
{
if
(
!
thread
->
attached
)
{
resume_process
(
process
);
goto
error
;
}
}
if
(
set_process_debugger
(
process
,
debugger
))
return
1
;
resume_process
(
process
);
...
...
@@ -437,6 +440,65 @@ static int debugger_attach( struct process *process, struct thread *debugger )
return
0
;
}
/* detach a process from a debugger thread (and resume it ?) */
int
debugger_detach
(
struct
process
*
process
,
struct
thread
*
debugger
)
{
struct
thread
*
thread
;
struct
debug_event
*
event
;
struct
debug_ctx
*
debug_ctx
;
if
(
!
process
->
debugger
||
process
->
debugger
!=
debugger
)
goto
error
;
/* not currently debugged, or debugged by another debugger */
if
(
!
debugger
->
debug_ctx
)
goto
error
;
/* should be a debugger */
/* init should be done, otherwise wouldn't be attached */
assert
(
!
process
->
init_event
);
suspend_process
(
process
);
/* send continue indication for all events */
debug_ctx
=
debugger
->
debug_ctx
;
/* find the event in the queue
* FIXME: could loop on process' threads and look the debug_event field */
for
(
event
=
debug_ctx
->
event_head
;
event
;
event
=
event
->
next
)
{
if
(
event
->
state
!=
EVENT_QUEUED
)
continue
;
if
(
event
->
sender
->
process
==
process
)
{
assert
(
event
->
sender
->
debug_event
==
event
);
event
->
status
=
DBG_CONTINUE
;
event
->
state
=
EVENT_CONTINUED
;
wake_up
(
&
event
->
obj
,
0
);
unlink_event
(
debug_ctx
,
event
);
/* from queued debug event */
resume_process
(
process
);
}
}
/* remove relationships between process and its debugger */
process
->
debugger
=
NULL
;
release_object
(
debugger
->
debug_ctx
);
debugger
->
debug_ctx
=
NULL
;
/* now detach all the threads */
for
(
thread
=
process
->
thread_list
;
thread
;
thread
=
thread
->
proc_next
)
{
if
(
thread
->
attached
)
{
detach_thread
(
thread
,
0
);
}
}
/* from this function */
resume_process
(
process
);
return
0
;
error:
set_error
(
STATUS_ACCESS_DENIED
);
return
0
;
}
/* generate all startup events of a given process */
void
generate_startup_debug_events
(
struct
process
*
process
,
void
*
entry
)
{
...
...
@@ -470,6 +532,7 @@ int set_process_debugger( struct process *process, struct thread *debugger )
if
(
!
(
debug_ctx
=
alloc_object
(
&
debug_ctx_ops
,
-
1
)))
return
0
;
debug_ctx
->
event_head
=
NULL
;
debug_ctx
->
event_tail
=
NULL
;
debug_ctx
->
kill_on_exit
=
1
;
debugger
->
debug_ctx
=
debug_ctx
;
}
process
->
debugger
=
debugger
;
...
...
@@ -481,8 +544,15 @@ void debug_exit_thread( struct thread *thread )
{
if
(
thread
->
debug_ctx
)
/* this thread is a debugger */
{
/* kill all debugged processes */
kill_debugged_processes
(
thread
,
thread
->
exit_code
);
if
(
thread
->
debug_ctx
->
kill_on_exit
)
{
/* kill all debugged processes */
kill_debugged_processes
(
thread
,
thread
->
exit_code
);
}
else
{
detach_debugged_processes
(
thread
);
}
release_object
(
thread
->
debug_ctx
);
thread
->
debug_ctx
=
NULL
;
}
...
...
@@ -538,12 +608,17 @@ DECL_HANDLER(continue_debug_event)
/* Start debugging an existing process */
DECL_HANDLER
(
debug_process
)
{
struct
debug_event_exception
data
;
struct
process
*
process
=
get_process_from_id
(
req
->
pid
);
if
(
!
process
)
return
;
if
(
debugger_attach
(
process
,
current
))
if
(
!
req
->
attach
)
{
debugger_detach
(
process
,
current
);
}
else
if
(
debugger_attach
(
process
,
current
))
{
struct
debug_event_exception
data
;
generate_startup_debug_events
(
process
,
NULL
);
resume_process
(
process
);
...
...
@@ -622,3 +697,14 @@ DECL_HANDLER(output_debug_string)
data
.
length
=
req
->
length
;
generate_debug_event
(
current
,
OUTPUT_DEBUG_STRING_EVENT
,
&
data
);
}
/* set debugger kill on exit flag */
DECL_HANDLER
(
set_debugger_kill_on_exit
)
{
if
(
!
current
->
debug_ctx
)
{
set_error
(
STATUS_ACCESS_DENIED
);
return
;
}
current
->
debug_ctx
->
kill_on_exit
=
req
->
kill_on_exit
;
}
server/process.c
View file @
fbccb38e
...
...
@@ -573,10 +573,24 @@ void kill_debugged_processes( struct thread *debugger, int exit_code )
}
/* detach a debugger from all its debuggees */
void
detach_debugged_processes
(
struct
thread
*
debugger
)
{
struct
process
*
process
;
for
(
process
=
first_process
;
process
;
process
=
process
->
next
)
{
if
(
process
->
debugger
==
debugger
&&
process
->
running_threads
)
{
debugger_detach
(
process
,
debugger
);
}
}
}
/* get all information about a process */
static
void
get_process_info
(
struct
process
*
process
,
struct
get_process_info_reply
*
reply
)
{
reply
->
pid
=
process
;
reply
->
pid
=
get_process_id
(
process
)
;
reply
->
debugged
=
(
process
->
debugger
!=
0
);
reply
->
exit_code
=
process
->
exit_code
;
reply
->
priority
=
process
->
priority
;
...
...
server/process.h
View file @
fbccb38e
...
...
@@ -71,6 +71,8 @@ extern struct thread *create_process( int fd );
extern
struct
process
*
get_process_from_id
(
void
*
id
);
extern
struct
process
*
get_process_from_handle
(
handle_t
handle
,
unsigned
int
access
);
extern
int
process_set_debugger
(
struct
process
*
process
,
struct
thread
*
thread
);
extern
int
debugger_detach
(
struct
process
*
process
,
struct
thread
*
debugger
);
extern
void
add_process_thread
(
struct
process
*
process
,
struct
thread
*
thread
);
extern
void
remove_process_thread
(
struct
process
*
process
,
...
...
@@ -80,6 +82,7 @@ extern void resume_process( struct process *process );
extern
void
kill_process
(
struct
process
*
process
,
struct
thread
*
skip
,
int
exit_code
);
extern
void
kill_console_processes
(
struct
thread
*
renderer
,
int
exit_code
);
extern
void
kill_debugged_processes
(
struct
thread
*
debugger
,
int
exit_code
);
extern
void
detach_debugged_processes
(
struct
thread
*
debugger
);
extern
struct
process_snapshot
*
process_snap
(
int
*
count
);
extern
struct
module_snapshot
*
module_snap
(
struct
process
*
process
,
int
*
count
);
...
...
server/protocol.def
View file @
fbccb38e
...
...
@@ -1117,9 +1117,16 @@ enum char_info_mode
@END
/* Start debugging an existing process */
/* Start
/stop
debugging an existing process */
@REQ(debug_process)
void* pid; /* id of the process to debug */
int attach; /* 1=attaching / 0=detaching from the process */
@END
/* Set debugger kill on exit flag */
@REQ(set_debugger_kill_on_exit)
int kill_on_exit; /* 0=detach/1=kill debuggee when debugger dies */
@END
...
...
server/request.h
View file @
fbccb38e
...
...
@@ -170,6 +170,7 @@ DECL_HANDLER(get_exception_status);
DECL_HANDLER
(
output_debug_string
);
DECL_HANDLER
(
continue_debug_event
);
DECL_HANDLER
(
debug_process
);
DECL_HANDLER
(
set_debugger_kill_on_exit
);
DECL_HANDLER
(
read_process_memory
);
DECL_HANDLER
(
write_process_memory
);
DECL_HANDLER
(
create_key
);
...
...
@@ -324,6 +325,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_output_debug_string
,
(
req_handler
)
req_continue_debug_event
,
(
req_handler
)
req_debug_process
,
(
req_handler
)
req_set_debugger_kill_on_exit
,
(
req_handler
)
req_read_process_memory
,
(
req_handler
)
req_write_process_memory
,
(
req_handler
)
req_create_key
,
...
...
server/trace.c
View file @
fbccb38e
...
...
@@ -1284,7 +1284,13 @@ static void dump_continue_debug_event_request( const struct continue_debug_event
static
void
dump_debug_process_request
(
const
struct
debug_process_request
*
req
)
{
fprintf
(
stderr
,
" pid=%p"
,
req
->
pid
);
fprintf
(
stderr
,
" pid=%p,"
,
req
->
pid
);
fprintf
(
stderr
,
" attach=%d"
,
req
->
attach
);
}
static
void
dump_set_debugger_kill_on_exit_request
(
const
struct
set_debugger_kill_on_exit_request
*
req
)
{
fprintf
(
stderr
,
" kill_on_exit=%d"
,
req
->
kill_on_exit
);
}
static
void
dump_read_process_memory_request
(
const
struct
read_process_memory_request
*
req
)
...
...
@@ -2115,6 +2121,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_output_debug_string_request
,
(
dump_func
)
dump_continue_debug_event_request
,
(
dump_func
)
dump_debug_process_request
,
(
dump_func
)
dump_set_debugger_kill_on_exit_request
,
(
dump_func
)
dump_read_process_memory_request
,
(
dump_func
)
dump_write_process_memory_request
,
(
dump_func
)
dump_create_key_request
,
...
...
@@ -2266,6 +2273,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
dump_read_process_memory_reply
,
(
dump_func
)
0
,
(
dump_func
)
dump_create_key_reply
,
...
...
@@ -2417,6 +2425,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"output_debug_string"
,
"continue_debug_event"
,
"debug_process"
,
"set_debugger_kill_on_exit"
,
"read_process_memory"
,
"write_process_memory"
,
"create_key"
,
...
...
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