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
964772bc
Commit
964772bc
authored
Jan 29, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Support the NtCreateDebugObject() flags.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
a24e330b
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
98 additions
and
13 deletions
+98
-13
debugger.c
dlls/kernel32/tests/debugger.c
+74
-0
process.c
dlls/ntdll/process.c
+1
-1
sync.c
dlls/ntdll/unix/sync.c
+3
-0
server_protocol.h
include/wine/server_protocol.h
+3
-1
winternl.h
include/winternl.h
+2
-0
debugger.c
server/debugger.c
+11
-10
protocol.def
server/protocol.def
+1
-0
request.h
server/request.h
+2
-1
trace.c
server/trace.c
+1
-0
No files found.
dlls/kernel32/tests/debugger.c
View file @
964772bc
...
...
@@ -21,6 +21,8 @@
#include <stdio.h>
#include <assert.h>
#include <ntstatus.h>
#define WIN32_NO_STATUS
#include <windows.h>
#include <winternl.h>
#include <winreg.h>
...
...
@@ -43,6 +45,10 @@ static void (WINAPI *pDbgBreakPoint)(void);
static
NTSTATUS
(
WINAPI
*
pNtSuspendProcess
)(
HANDLE
process
);
static
NTSTATUS
(
WINAPI
*
pNtResumeProcess
)(
HANDLE
process
);
static
NTSTATUS
(
WINAPI
*
pNtCreateDebugObject
)(
HANDLE
*
,
ACCESS_MASK
,
OBJECT_ATTRIBUTES
*
,
ULONG
);
static
NTSTATUS
(
WINAPI
*
pDbgUiConnectToDbg
)(
void
);
static
HANDLE
(
WINAPI
*
pDbgUiGetThreadDebugObject
)(
void
);
static
void
(
WINAPI
*
pDbgUiSetThreadDebugObject
)(
HANDLE
);
static
LONG
child_failures
;
...
...
@@ -1699,6 +1705,69 @@ static void test_debugger(const char *argv0)
ok
(
ret
,
"CloseHandle failed, last error %d.
\n
"
,
GetLastError
());
}
static
DWORD
run_child_wait
(
char
*
cmd
,
HANDLE
event
)
{
PROCESS_INFORMATION
pi
;
STARTUPINFOA
si
=
{
sizeof
(
si
)
};
BOOL
ret
;
DWORD
exit_code
;
ret
=
CreateProcessA
(
NULL
,
cmd
,
NULL
,
NULL
,
TRUE
,
DEBUG_PROCESS
,
NULL
,
NULL
,
&
si
,
&
pi
);
ok
(
ret
,
"CreateProcess failed, last error %#x.
\n
"
,
GetLastError
());
Sleep
(
200
);
CloseHandle
(
pDbgUiGetThreadDebugObject
()
);
pDbgUiSetThreadDebugObject
(
0
);
SetEvent
(
event
);
WaitForSingleObject
(
pi
.
hProcess
,
1000
);
ret
=
GetExitCodeProcess
(
pi
.
hProcess
,
&
exit_code
);
ok
(
ret
,
"GetExitCodeProcess failed err=%d
\n
"
,
GetLastError
());
CloseHandle
(
pi
.
hProcess
);
CloseHandle
(
pi
.
hThread
);
return
exit_code
;
}
static
void
test_kill_on_exit
(
const
char
*
argv0
)
{
static
const
char
arguments
[]
=
" debugger wait "
;
SECURITY_ATTRIBUTES
sa
=
{
sizeof
(
sa
),
NULL
,
TRUE
};
OBJECT_ATTRIBUTES
attr
=
{
sizeof
(
attr
)
};
NTSTATUS
status
;
HANDLE
event
,
debug
;
DWORD
exit_code
;
char
*
cmd
;
event
=
CreateEventW
(
&
sa
,
FALSE
,
FALSE
,
NULL
);
ok
(
event
!=
NULL
,
"CreateEvent failed: %u
\n
"
,
GetLastError
());
cmd
=
heap_alloc
(
strlen
(
argv0
)
+
strlen
(
arguments
)
+
16
);
sprintf
(
cmd
,
"%s%s%x
\n
"
,
argv0
,
arguments
,
(
DWORD
)(
DWORD_PTR
)
event
);
status
=
pNtCreateDebugObject
(
&
debug
,
DEBUG_ALL_ACCESS
,
&
attr
,
0
);
ok
(
!
status
,
"NtCreateDebugObject failed %x
\n
"
,
status
);
pDbgUiSetThreadDebugObject
(
debug
);
exit_code
=
run_child_wait
(
cmd
,
event
);
todo_wine
ok
(
exit_code
==
0
,
"exit code = %08x
\n
"
,
exit_code
);
status
=
pNtCreateDebugObject
(
&
debug
,
DEBUG_ALL_ACCESS
,
&
attr
,
DEBUG_KILL_ON_CLOSE
);
ok
(
!
status
,
"NtCreateDebugObject failed %x
\n
"
,
status
);
pDbgUiSetThreadDebugObject
(
debug
);
exit_code
=
run_child_wait
(
cmd
,
event
);
todo_wine
ok
(
exit_code
==
STATUS_DEBUGGER_INACTIVE
,
"exit code = %08x
\n
"
,
exit_code
);
status
=
pNtCreateDebugObject
(
&
debug
,
DEBUG_ALL_ACCESS
,
&
attr
,
0xfffe
);
ok
(
status
==
STATUS_INVALID_PARAMETER
,
"NtCreateDebugObject failed %x
\n
"
,
status
);
status
=
pDbgUiConnectToDbg
();
ok
(
!
status
,
"DbgUiConnectToDbg failed %x
\n
"
,
status
);
exit_code
=
run_child_wait
(
cmd
,
event
);
todo_wine
ok
(
exit_code
==
STATUS_DEBUGGER_INACTIVE
,
"exit code = %08x
\n
"
,
exit_code
);
heap_free
(
cmd
);
}
START_TEST
(
debugger
)
{
HMODULE
hdll
;
...
...
@@ -1710,6 +1779,10 @@ START_TEST(debugger)
pDbgBreakPoint
=
(
void
*
)
GetProcAddress
(
ntdll
,
"DbgBreakPoint"
);
pNtSuspendProcess
=
(
void
*
)
GetProcAddress
(
ntdll
,
"NtSuspendProcess"
);
pNtResumeProcess
=
(
void
*
)
GetProcAddress
(
ntdll
,
"NtResumeProcess"
);
pNtCreateDebugObject
=
(
void
*
)
GetProcAddress
(
ntdll
,
"NtCreateDebugObject"
);
pDbgUiConnectToDbg
=
(
void
*
)
GetProcAddress
(
ntdll
,
"DbgUiConnectToDbg"
);
pDbgUiGetThreadDebugObject
=
(
void
*
)
GetProcAddress
(
ntdll
,
"DbgUiGetThreadDebugObject"
);
pDbgUiSetThreadDebugObject
=
(
void
*
)
GetProcAddress
(
ntdll
,
"DbgUiSetThreadDebugObject"
);
myARGC
=
winetest_get_mainargs
(
&
myARGV
);
if
(
myARGC
>=
3
&&
strcmp
(
myARGV
[
2
],
"crash"
)
==
0
)
...
...
@@ -1746,5 +1819,6 @@ START_TEST(debugger)
test_debug_children
(
myARGV
[
0
],
0
,
FALSE
,
TRUE
);
test_debug_children
(
myARGV
[
0
],
DEBUG_ONLY_THIS_PROCESS
,
FALSE
,
TRUE
);
test_debugger
(
myARGV
[
0
]);
test_kill_on_exit
(
myARGV
[
0
]);
}
}
dlls/ntdll/process.c
View file @
964772bc
...
...
@@ -145,7 +145,7 @@ NTSTATUS WINAPI DbgUiConnectToDbg(void)
if
(
DbgUiGetThreadDebugObject
())
return
STATUS_SUCCESS
;
/* already connected */
status
=
NtCreateDebugObject
(
&
handle
,
DEBUG_ALL_ACCESS
,
&
attr
,
0
);
status
=
NtCreateDebugObject
(
&
handle
,
DEBUG_ALL_ACCESS
,
&
attr
,
DEBUG_KILL_ON_CLOSE
);
if
(
!
status
)
DbgUiSetThreadDebugObject
(
handle
);
return
status
;
}
...
...
dlls/ntdll/unix/sync.c
View file @
964772bc
...
...
@@ -916,11 +916,14 @@ NTSTATUS WINAPI NtCreateDebugObject( HANDLE *handle, ACCESS_MASK access,
data_size_t
len
;
struct
object_attributes
*
objattr
;
if
(
flags
&
~
DEBUG_KILL_ON_CLOSE
)
return
STATUS_INVALID_PARAMETER
;
if
((
ret
=
alloc_object_attributes
(
attr
,
&
objattr
,
&
len
)))
return
ret
;
SERVER_START_REQ
(
create_debug_obj
)
{
req
->
access
=
access
;
req
->
flags
=
flags
;
wine_server_add_data
(
req
,
objattr
,
len
);
ret
=
wine_server_call
(
req
);
*
handle
=
wine_server_ptr_handle
(
reply
->
handle
);
...
...
include/wine/server_protocol.h
View file @
964772bc
...
...
@@ -2012,7 +2012,9 @@ struct create_debug_obj_request
{
struct
request_header
__header
;
unsigned
int
access
;
unsigned
int
flags
;
/* VARARG(objattr,object_attributes); */
char
__pad_20
[
4
];
};
struct
create_debug_obj_reply
{
...
...
@@ -6207,7 +6209,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 65
6
#define SERVER_PROTOCOL_VERSION 65
7
/* ### protocol_version end ### */
...
...
include/winternl.h
View file @
964772bc
...
...
@@ -3013,6 +3013,8 @@ typedef struct _PS_CREATE_INFO
#define DEBUG_QUERY_INFORMATION 0x0008
#define DEBUG_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x0f)
#define DEBUG_KILL_ON_CLOSE 0x1
/***********************************************************************
* Function declarations
*/
...
...
server/debugger.c
View file @
964772bc
...
...
@@ -57,7 +57,7 @@ struct debug_obj
{
struct
object
obj
;
/* object header */
struct
list
event_queue
;
/* pending events queue */
int
kill_on_exit
;
/* kill debuggees on debugger exit ?
*/
unsigned
int
flags
;
/* debug flags
*/
};
...
...
@@ -347,7 +347,8 @@ static void debug_obj_destroy( struct object *obj )
struct
debug_obj
*
debug_obj
=
(
struct
debug_obj
*
)
obj
;
assert
(
obj
->
ops
==
&
debug_obj_ops
);
detach_debugged_processes
(
debug_obj
,
debug_obj
->
kill_on_exit
?
STATUS_DEBUGGER_INACTIVE
:
0
);
detach_debugged_processes
(
debug_obj
,
(
debug_obj
->
flags
&
DEBUG_KILL_ON_CLOSE
)
?
STATUS_DEBUGGER_INACTIVE
:
0
);
/* free all pending events */
while
((
ptr
=
list_head
(
&
debug_obj
->
event_queue
)))
...
...
@@ -355,7 +356,8 @@ static void debug_obj_destroy( struct object *obj )
}
static
struct
debug_obj
*
create_debug_obj
(
struct
object
*
root
,
const
struct
unicode_str
*
name
,
unsigned
int
attr
,
const
struct
security_descriptor
*
sd
)
unsigned
int
attr
,
unsigned
int
flags
,
const
struct
security_descriptor
*
sd
)
{
struct
debug_obj
*
debug_obj
;
...
...
@@ -363,7 +365,7 @@ static struct debug_obj *create_debug_obj( struct object *root, const struct uni
{
if
(
get_error
()
!=
STATUS_OBJECT_NAME_EXISTS
)
{
debug_obj
->
kill_on_exit
=
1
;
debug_obj
->
flags
=
flags
;
list_init
(
&
debug_obj
->
event_queue
);
}
}
...
...
@@ -586,9 +588,7 @@ int set_process_debugger( struct process *process, struct thread *debugger )
if
(
!
debugger
->
debug_obj
)
/* need to allocate a context */
{
if
(
!
(
debug_obj
=
alloc_object
(
&
debug_obj_ops
)))
return
0
;
debug_obj
->
kill_on_exit
=
1
;
list_init
(
&
debug_obj
->
event_queue
);
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
;
...
...
@@ -602,7 +602,8 @@ void debug_exit_thread( struct thread *thread )
if
(
debug_obj
)
/* this thread is a debugger */
{
detach_debugged_processes
(
debug_obj
,
debug_obj
->
kill_on_exit
?
STATUS_DEBUGGER_INACTIVE
:
0
);
detach_debugged_processes
(
debug_obj
,
(
debug_obj
->
flags
&
DEBUG_KILL_ON_CLOSE
)
?
STATUS_DEBUGGER_INACTIVE
:
0
);
release_object
(
thread
->
debug_obj
);
thread
->
debug_obj
=
NULL
;
}
...
...
@@ -618,7 +619,7 @@ DECL_HANDLER(create_debug_obj)
const
struct
object_attributes
*
objattr
=
get_req_object_attributes
(
&
sd
,
&
name
,
&
root
);
if
(
!
objattr
)
return
;
if
((
debug_obj
=
create_debug_obj
(
root
,
&
name
,
objattr
->
attributes
,
sd
)))
if
((
debug_obj
=
create_debug_obj
(
root
,
&
name
,
objattr
->
attributes
,
req
->
flags
,
sd
)))
{
if
(
get_error
()
==
STATUS_OBJECT_NAME_EXISTS
)
reply
->
handle
=
alloc_handle
(
current
->
process
,
debug_obj
,
req
->
access
,
objattr
->
attributes
);
...
...
@@ -769,5 +770,5 @@ DECL_HANDLER(set_debugger_kill_on_exit)
set_error
(
STATUS_ACCESS_DENIED
);
return
;
}
current
->
debug_obj
->
kill_on_exit
=
req
->
kill_on_exit
;
current
->
debug_obj
->
flags
=
req
->
kill_on_exit
?
DEBUG_KILL_ON_CLOSE
:
0
;
}
server/protocol.def
View file @
964772bc
...
...
@@ -1590,6 +1590,7 @@ struct process_info
/* Create a debug object */
@REQ(create_debug_obj)
unsigned int access; /* wanted access rights */
unsigned int flags; /* object flags */
VARARG(objattr,object_attributes); /* object attributes */
@REPLY
obj_handle_t handle; /* handle to the debug object */
...
...
server/request.h
View file @
964772bc
...
...
@@ -1133,7 +1133,8 @@ C_ASSERT( FIELD_OFFSET(struct list_processes_reply, info_size) == 8 );
C_ASSERT
(
FIELD_OFFSET
(
struct
list_processes_reply
,
process_count
)
==
12
);
C_ASSERT
(
sizeof
(
struct
list_processes_reply
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
create_debug_obj_request
,
access
)
==
12
);
C_ASSERT
(
sizeof
(
struct
create_debug_obj_request
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
create_debug_obj_request
,
flags
)
==
16
);
C_ASSERT
(
sizeof
(
struct
create_debug_obj_request
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
create_debug_obj_reply
,
handle
)
==
8
);
C_ASSERT
(
sizeof
(
struct
create_debug_obj_reply
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
wait_debug_event_request
,
get_handle
)
==
12
);
...
...
server/trace.c
View file @
964772bc
...
...
@@ -2153,6 +2153,7 @@ static void dump_list_processes_reply( const struct list_processes_reply *req )
static
void
dump_create_debug_obj_request
(
const
struct
create_debug_obj_request
*
req
)
{
fprintf
(
stderr
,
" access=%08x"
,
req
->
access
);
fprintf
(
stderr
,
", flags=%08x"
,
req
->
flags
);
dump_varargs_object_attributes
(
", objattr="
,
cur_size
);
}
...
...
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