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
46b84e7a
Commit
46b84e7a
authored
Feb 01, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Implement NtDebugActiveProcess() and NtRemoveProcessDebug().
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
11e6f100
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
106 additions
and
81 deletions
+106
-81
debug.c
dlls/kernelbase/debug.c
+14
-23
ntdll.spec
dlls/ntdll/ntdll.spec
+4
-4
process.c
dlls/ntdll/process.c
+20
-0
process.c
dlls/ntdll/unix/process.c
+31
-3
server_protocol.h
include/wine/server_protocol.h
+3
-3
winternl.h
include/winternl.h
+4
-0
debugger.c
server/debugger.c
+22
-42
object.h
server/object.h
+0
-1
protocol.def
server/protocol.def
+3
-2
request.h
server/request.h
+3
-2
trace.c
server/trace.c
+2
-1
No files found.
dlls/kernelbase/debug.c
View file @
46b84e7a
...
...
@@ -91,22 +91,15 @@ BOOL WINAPI DECLSPEC_HOTPATCH ContinueDebugEvent( DWORD pid, DWORD tid, DWORD st
BOOL
WINAPI
DECLSPEC_HOTPATCH
DebugActiveProcess
(
DWORD
pid
)
{
HANDLE
process
;
BOOL
ret
;
SERVER_START_REQ
(
debug_process
)
{
req
->
pid
=
pid
;
req
->
attach
=
1
;
ret
=
!
wine_server_call_err
(
req
);
}
SERVER_END_REQ
;
if
(
!
ret
)
return
FALSE
;
NTSTATUS
status
;
if
(
!
(
process
=
OpenProcess
(
PROCESS_CREATE_THREAD
,
FALSE
,
pid
)))
return
FALSE
;
ret
=
set_ntstatus
(
DbgUiIssueRemoteBreakin
(
process
));
if
(
!
set_ntstatus
(
DbgUiConnectToDbg
()
))
return
FALSE
;
if
(
!
(
process
=
OpenProcess
(
PROCESS_VM_READ
|
PROCESS_VM_WRITE
|
PROCESS_SUSPEND_RESUME
|
PROCESS_CREATE_THREAD
,
FALSE
,
pid
)))
return
FALSE
;
status
=
DbgUiDebugActiveProcess
(
process
);
NtClose
(
process
);
if
(
!
ret
)
DebugActiveProcessStop
(
pid
);
return
ret
;
return
set_ntstatus
(
status
);
}
...
...
@@ -115,16 +108,14 @@ BOOL WINAPI DECLSPEC_HOTPATCH DebugActiveProcess( DWORD pid )
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
DebugActiveProcessStop
(
DWORD
pid
)
{
BOOL
ret
;
HANDLE
process
;
NTSTATUS
status
;
SERVER_START_REQ
(
debug_process
)
{
req
->
pid
=
pid
;
req
->
attach
=
0
;
ret
=
!
wine_server_call_err
(
req
);
}
SERVER_END_REQ
;
return
ret
;
if
(
!
(
process
=
OpenProcess
(
PROCESS_VM_READ
|
PROCESS_VM_WRITE
|
PROCESS_SUSPEND_RESUME
,
FALSE
,
pid
)))
return
FALSE
;
status
=
DbgUiStopDebugging
(
process
);
NtClose
(
process
);
return
set_ntstatus
(
status
);
}
...
...
dlls/ntdll/ntdll.spec
View file @
46b84e7a
...
...
@@ -37,12 +37,12 @@
@ stdcall DbgUiConnectToDbg()
@ stub DbgUiContinue
@ stub DbgUiConvertStateChangeStructure
# @ stub DbgUiDebugActiveProcess
@ stdcall DbgUiDebugActiveProcess(long)
@ stdcall DbgUiGetThreadDebugObject()
@ stdcall DbgUiIssueRemoteBreakin(long)
@ stdcall DbgUiRemoteBreakin(ptr)
@ stdcall DbgUiSetThreadDebugObject(long)
# @ stub DbgUiStopDebugging
@ stdcall DbgUiStopDebugging(long)
@ stub DbgUiWaitStateChange
@ stdcall DbgUserBreakPoint()
@ stdcall EtwEventActivityIdControl(long ptr)
...
...
@@ -340,7 +340,7 @@
@ stdcall -syscall NtReleaseSemaphore(long long ptr)
@ stdcall -syscall NtRemoveIoCompletion(ptr ptr ptr ptr ptr)
@ stdcall -syscall NtRemoveIoCompletionEx(ptr ptr long ptr ptr long)
# @ stub NtRemoveProcessDebug
@ stdcall -syscall NtRemoveProcessDebug(long long)
@ stdcall -syscall NtRenameKey(long ptr)
@ stdcall -syscall NtReplaceKey(ptr long ptr)
@ stub NtReplyPort
...
...
@@ -1345,7 +1345,7 @@
@ stdcall -private -syscall ZwReleaseSemaphore(long long ptr) NtReleaseSemaphore
@ stdcall -private -syscall ZwRemoveIoCompletion(ptr ptr ptr ptr ptr) NtRemoveIoCompletion
@ stdcall -private -syscall ZwRemoveIoCompletionEx(ptr ptr long ptr ptr long) NtRemoveIoCompletionEx
# @ stub Zw
RemoveProcessDebug
@ stdcall -private -syscall ZwRemoveProcessDebug(long long) Nt
RemoveProcessDebug
@ stdcall -private -syscall ZwRenameKey(long ptr) NtRenameKey
@ stdcall -private -syscall ZwReplaceKey(ptr long ptr) NtReplaceKey
@ stub ZwReplyPort
...
...
dlls/ntdll/process.c
View file @
46b84e7a
...
...
@@ -151,6 +151,26 @@ NTSTATUS WINAPI DbgUiConnectToDbg(void)
}
/***********************************************************************
* DbgUiDebugActiveProcess (NTDLL.@)
*/
NTSTATUS
WINAPI
DbgUiDebugActiveProcess
(
HANDLE
process
)
{
NTSTATUS
status
;
if
((
status
=
NtDebugActiveProcess
(
process
,
DbgUiGetThreadDebugObject
()
)))
return
status
;
if
((
status
=
DbgUiIssueRemoteBreakin
(
process
)))
DbgUiStopDebugging
(
process
);
return
status
;
}
/***********************************************************************
* DbgUiStopDebugging (NTDLL.@)
*/
NTSTATUS
WINAPI
DbgUiStopDebugging
(
HANDLE
process
)
{
return
NtRemoveProcessDebug
(
process
,
DbgUiGetThreadDebugObject
()
);
}
/***********************************************************************
* DbgUiRemoteBreakin (NTDLL.@)
*/
void
WINAPI
DbgUiRemoteBreakin
(
void
*
arg
)
...
...
dlls/ntdll/unix/process.c
View file @
46b84e7a
...
...
@@ -1746,10 +1746,38 @@ NTSTATUS WINAPI NtResumeProcess( HANDLE handle )
/**********************************************************************
* NtDebugActiveProcess (NTDLL.@)
*/
NTSTATUS
WINAPI
NtDebugActiveProcess
(
HANDLE
process
,
HANDLE
debug
_object
)
NTSTATUS
WINAPI
NtDebugActiveProcess
(
HANDLE
process
,
HANDLE
debug
)
{
FIXME
(
"(%p %p), stub!
\n
"
,
process
,
debug_object
);
return
STATUS_SUCCESS
;
NTSTATUS
ret
;
SERVER_START_REQ
(
debug_process
)
{
req
->
handle
=
wine_server_obj_handle
(
process
);
req
->
debug
=
wine_server_obj_handle
(
debug
);
req
->
attach
=
1
;
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
return
ret
;
}
/**********************************************************************
* NtRemoveProcessDebug (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRemoveProcessDebug
(
HANDLE
process
,
HANDLE
debug
)
{
NTSTATUS
ret
;
SERVER_START_REQ
(
debug_process
)
{
req
->
handle
=
wine_server_obj_handle
(
process
);
req
->
debug
=
wine_server_obj_handle
(
debug
);
req
->
attach
=
0
;
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
return
ret
;
}
...
...
include/wine/server_protocol.h
View file @
46b84e7a
...
...
@@ -2094,9 +2094,9 @@ struct continue_debug_event_reply
struct
debug_process_request
{
struct
request_header
__header
;
process_id_t
pid
;
obj_handle_t
handle
;
obj_handle_t
debug
;
int
attach
;
char
__pad_20
[
4
];
};
struct
debug_process_reply
{
...
...
@@ -6211,7 +6211,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 65
8
#define SERVER_PROTOCOL_VERSION 65
9
/* ### protocol_version end ### */
...
...
include/winternl.h
View file @
46b84e7a
...
...
@@ -3023,10 +3023,12 @@ NTSYSAPI void WINAPI DbgBreakPoint(void);
NTSYSAPI
NTSTATUS
WINAPIV
DbgPrint
(
LPCSTR
fmt
,
...);
NTSYSAPI
NTSTATUS
WINAPIV
DbgPrintEx
(
ULONG
iComponentId
,
ULONG
Level
,
LPCSTR
fmt
,
...);
NTSYSAPI
NTSTATUS
WINAPI
DbgUiConnectToDbg
(
void
);
NTSYSAPI
NTSTATUS
WINAPI
DbgUiDebugActiveProcess
(
HANDLE
);
NTSYSAPI
HANDLE
WINAPI
DbgUiGetThreadDebugObject
(
void
);
NTSYSAPI
NTSTATUS
WINAPI
DbgUiIssueRemoteBreakin
(
HANDLE
);
NTSYSAPI
void
WINAPI
DbgUiRemoteBreakin
(
void
*
);
NTSYSAPI
void
WINAPI
DbgUiSetThreadDebugObject
(
HANDLE
);
NTSYSAPI
NTSTATUS
WINAPI
DbgUiStopDebugging
(
HANDLE
);
NTSYSAPI
void
WINAPI
DbgUserBreakPoint
(
void
);
NTSYSAPI
NTSTATUS
WINAPI
LdrAccessResource
(
HMODULE
,
const
IMAGE_RESOURCE_DATA_ENTRY
*
,
void
**
,
PULONG
);
NTSYSAPI
NTSTATUS
WINAPI
LdrAddDllDirectory
(
const
UNICODE_STRING
*
,
void
**
);
...
...
@@ -3104,6 +3106,7 @@ NTSYSAPI NTSTATUS WINAPI NtCreateThreadEx(HANDLE*,ACCESS_MASK,OBJECT_ATTRIBUTES
NTSYSAPI
NTSTATUS
WINAPI
NtCreateTimer
(
HANDLE
*
,
ACCESS_MASK
,
const
OBJECT_ATTRIBUTES
*
,
TIMER_TYPE
);
NTSYSAPI
NTSTATUS
WINAPI
NtCreateToken
(
PHANDLE
,
ACCESS_MASK
,
POBJECT_ATTRIBUTES
,
TOKEN_TYPE
,
PLUID
,
PLARGE_INTEGER
,
PTOKEN_USER
,
PTOKEN_GROUPS
,
PTOKEN_PRIVILEGES
,
PTOKEN_OWNER
,
PTOKEN_PRIMARY_GROUP
,
PTOKEN_DEFAULT_DACL
,
PTOKEN_SOURCE
);
NTSYSAPI
NTSTATUS
WINAPI
NtCreateUserProcess
(
HANDLE
*
,
HANDLE
*
,
ACCESS_MASK
,
ACCESS_MASK
,
OBJECT_ATTRIBUTES
*
,
OBJECT_ATTRIBUTES
*
,
ULONG
,
ULONG
,
RTL_USER_PROCESS_PARAMETERS
*
,
PS_CREATE_INFO
*
,
PS_ATTRIBUTE_LIST
*
);
NTSYSAPI
NTSTATUS
WINAPI
NtDebugActiveProcess
(
HANDLE
,
HANDLE
);
NTSYSAPI
NTSTATUS
WINAPI
NtDelayExecution
(
BOOLEAN
,
const
LARGE_INTEGER
*
);
NTSYSAPI
NTSTATUS
WINAPI
NtDeleteAtom
(
RTL_ATOM
);
NTSYSAPI
NTSTATUS
WINAPI
NtDeleteFile
(
POBJECT_ATTRIBUTES
);
...
...
@@ -3228,6 +3231,7 @@ NTSYSAPI NTSTATUS WINAPI NtReleaseMutant(HANDLE,PLONG);
NTSYSAPI
NTSTATUS
WINAPI
NtReleaseSemaphore
(
HANDLE
,
ULONG
,
PULONG
);
NTSYSAPI
NTSTATUS
WINAPI
NtRemoveIoCompletion
(
HANDLE
,
PULONG_PTR
,
PULONG_PTR
,
PIO_STATUS_BLOCK
,
PLARGE_INTEGER
);
NTSYSAPI
NTSTATUS
WINAPI
NtRemoveIoCompletionEx
(
HANDLE
,
FILE_IO_COMPLETION_INFORMATION
*
,
ULONG
,
ULONG
*
,
LARGE_INTEGER
*
,
BOOLEAN
);
NTSYSAPI
NTSTATUS
WINAPI
NtRemoveProcessDebug
(
HANDLE
,
HANDLE
);
NTSYSAPI
NTSTATUS
WINAPI
NtRenameKey
(
HANDLE
,
UNICODE_STRING
*
);
NTSYSAPI
NTSTATUS
WINAPI
NtReplaceKey
(
POBJECT_ATTRIBUTES
,
HANDLE
,
POBJECT_ATTRIBUTES
);
NTSYSAPI
NTSTATUS
WINAPI
NtReplyPort
(
HANDLE
,
PLPC_MESSAGE
);
...
...
server/debugger.c
View file @
46b84e7a
...
...
@@ -485,34 +485,30 @@ void resume_delayed_debug_events( struct thread *thread )
}
/* attach a process to a debugger thread and suspend it */
static
int
debugger_attach
(
struct
process
*
process
,
struct
thread
*
debugger
)
static
int
debugger_attach
(
struct
process
*
process
,
struct
thread
*
debugger
,
struct
debug_obj
*
debug_obj
)
{
if
(
process
->
debug_obj
)
goto
error
;
/* already being debugged */
if
(
debugger
->
process
==
process
)
goto
error
;
if
(
!
is_process_init_done
(
process
))
goto
error
;
/* still starting up */
if
(
list_empty
(
&
process
->
thread_list
))
goto
error
;
/* no thread running in the process */
/* don't let a debugger debug its console... won't work */
if
(
debugger
->
process
->
console
)
{
struct
thread
*
renderer
=
console_get_renderer
(
debugger
->
process
->
console
);
if
(
renderer
&&
renderer
->
process
==
process
)
goto
error
;
if
(
renderer
&&
renderer
->
process
==
process
)
goto
error
;
}
if
(
!
debugger
->
debug_obj
)
debugger
->
debug_obj
=
(
struct
debug_obj
*
)
grab_object
(
debug_obj
);
suspend_process
(
process
);
if
(
!
set_process_debugger
(
process
,
debugger
))
{
resume_process
(
process
);
return
0
;
}
if
(
!
set_process_debug_flag
(
process
,
1
))
{
process
->
debug_obj
=
NULL
;
resume_process
(
process
);
return
0
;
}
process
->
debug_obj
=
debug_obj
;
process
->
debug_children
=
0
;
generate_startup_debug_events
(
process
,
0
);
resume_process
(
process
);
return
1
;
error:
...
...
@@ -526,9 +522,6 @@ void debugger_detach( struct process *process, struct debug_obj *debug_obj )
{
struct
debug_event
*
event
,
*
next
;
/* init should be done, otherwise wouldn't be attached */
assert
(
is_process_init_done
(
process
));
suspend_process
(
process
);
/* send continue indication for all events */
...
...
@@ -549,7 +542,6 @@ void debugger_detach( struct process *process, struct debug_obj *debug_obj )
process
->
debug_obj
=
NULL
;
if
(
!
set_process_debug_flag
(
process
,
0
))
clear_error
();
/* ignore error */
/* from this function */
resume_process
(
process
);
}
...
...
@@ -584,22 +576,6 @@ void generate_startup_debug_events( struct process *process, client_ptr_t entry
}
}
/* set the debugger of a given process */
int
set_process_debugger
(
struct
process
*
process
,
struct
thread
*
debugger
)
{
struct
debug_obj
*
debug_obj
;
assert
(
!
process
->
debug_obj
);
if
(
!
debugger
->
debug_obj
)
/* need to allocate a context */
{
if
(
!
(
debug_obj
=
create_debug_obj
(
NULL
,
NULL
,
0
,
DEBUG_KILL_ON_CLOSE
,
NULL
)))
return
0
;
debugger
->
debug_obj
=
debug_obj
;
}
process
->
debug_obj
=
debugger
->
debug_obj
;
return
1
;
}
/* a thread is exiting */
void
debug_exit_thread
(
struct
thread
*
thread
)
{
...
...
@@ -692,23 +668,27 @@ DECL_HANDLER(continue_debug_event)
}
}
/*
Start
debugging an existing process */
/*
start or stop
debugging an existing process */
DECL_HANDLER
(
debug_process
)
{
struct
process
*
process
=
get_process_from_id
(
req
->
pid
);
if
(
!
process
)
return
;
struct
debug_obj
*
debug_obj
;
struct
process
*
process
=
get_process_from_handle
(
req
->
handle
,
PROCESS_VM_READ
|
PROCESS_VM_WRITE
|
PROCESS_SUSPEND_RESUME
);
if
(
!
req
->
attach
)
if
(
!
process
)
return
;
if
((
debug_obj
=
get_debug_obj
(
current
->
process
,
req
->
debug
,
DEBUG_PROCESS_ASSIGN
)))
{
if
(
current
->
debug_obj
&&
process
->
debug_obj
==
current
->
debug_obj
)
debugger_detach
(
process
,
current
->
debug_obj
);
else
set_error
(
STATUS_ACCESS_DENIED
);
if
(
req
->
attach
)
{
if
(
!
process
->
debug_obj
)
debugger_attach
(
process
,
current
,
debug_obj
);
else
set_error
(
STATUS_ACCESS_DENIED
);
}
else
if
(
debugger_attach
(
process
,
current
))
else
{
generate_startup_debug_events
(
process
,
0
);
resume_process
(
process
);
if
(
process
->
debug_obj
==
debug_obj
)
debugger_detach
(
process
,
debug_obj
);
else
set_error
(
STATUS_ACCESS_DENIED
);
}
release_object
(
debug_obj
);
}
release_object
(
process
);
}
...
...
server/object.h
View file @
46b84e7a
...
...
@@ -212,7 +212,6 @@ extern void sock_init(void);
/* debugger functions */
extern
int
set_process_debugger
(
struct
process
*
process
,
struct
thread
*
debugger
);
extern
void
generate_debug_event
(
struct
thread
*
thread
,
int
code
,
const
void
*
arg
);
extern
void
resume_delayed_debug_events
(
struct
thread
*
thread
);
extern
void
generate_startup_debug_events
(
struct
process
*
process
,
client_ptr_t
entry
);
...
...
server/protocol.def
View file @
46b84e7a
...
...
@@ -1637,9 +1637,10 @@ struct process_info
@END
/* Start
/
stop debugging an existing process */
/* Start
or
stop debugging an existing process */
@REQ(debug_process)
process_id_t pid; /* id of the process to debug */
obj_handle_t handle; /* process handle */
obj_handle_t debug; /* debug object to attach to the process */
int attach; /* 1=attaching / 0=detaching from the process */
@END
...
...
server/request.h
View file @
46b84e7a
...
...
@@ -1159,8 +1159,9 @@ C_ASSERT( FIELD_OFFSET(struct continue_debug_event_request, pid) == 12 );
C_ASSERT
(
FIELD_OFFSET
(
struct
continue_debug_event_request
,
tid
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
continue_debug_event_request
,
status
)
==
20
);
C_ASSERT
(
sizeof
(
struct
continue_debug_event_request
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
debug_process_request
,
pid
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
debug_process_request
,
attach
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
debug_process_request
,
handle
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
debug_process_request
,
debug
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
debug_process_request
,
attach
)
==
20
);
C_ASSERT
(
sizeof
(
struct
debug_process_request
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
set_debugger_kill_on_exit_request
,
kill_on_exit
)
==
12
);
C_ASSERT
(
sizeof
(
struct
set_debugger_kill_on_exit_request
)
==
16
);
...
...
server/trace.c
View file @
46b84e7a
...
...
@@ -2206,7 +2206,8 @@ 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=%04x"
,
req
->
pid
);
fprintf
(
stderr
,
" handle=%04x"
,
req
->
handle
);
fprintf
(
stderr
,
", debug=%04x"
,
req
->
debug
);
fprintf
(
stderr
,
", attach=%d"
,
req
->
attach
);
}
...
...
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