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
8f3e72ed
Commit
8f3e72ed
authored
Apr 11, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
Apr 11, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dbgeng: Keep a list of processes to attach to.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
f1562cfd
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
357 additions
and
2 deletions
+357
-2
dbgeng.c
dlls/dbgeng/dbgeng.c
+37
-2
dbgeng.c
dlls/dbgeng/tests/dbgeng.c
+231
-0
dbgeng.h
include/dbgeng.h
+89
-0
No files found.
dlls/dbgeng/dbgeng.c
View file @
8f3e72ed
...
...
@@ -31,9 +31,17 @@
#include "wine/debug.h"
#include "wine/heap.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
dbgeng
);
struct
target_process
{
struct
list
entry
;
unsigned
int
pid
;
unsigned
int
attach_flags
;
};
struct
debug_client
{
IDebugClient
IDebugClient_iface
;
...
...
@@ -42,6 +50,7 @@ struct debug_client
IDebugControl2
IDebugControl2_iface
;
LONG
refcount
;
ULONG
engine_options
;
struct
list
targets
;
};
static
struct
debug_client
*
impl_from_IDebugClient
(
IDebugClient
*
iface
)
...
...
@@ -113,11 +122,19 @@ static ULONG STDMETHODCALLTYPE debugclient_Release(IDebugClient *iface)
{
struct
debug_client
*
debug_client
=
impl_from_IDebugClient
(
iface
);
ULONG
refcount
=
InterlockedDecrement
(
&
debug_client
->
refcount
);
struct
target_process
*
cur
,
*
cur2
;
TRACE
(
"%p, %d.
\n
"
,
debug_client
,
refcount
);
if
(
!
refcount
)
{
LIST_FOR_EACH_ENTRY_SAFE
(
cur
,
cur2
,
&
debug_client
->
targets
,
struct
target_process
,
entry
)
{
list_remove
(
&
cur
->
entry
);
heap_free
(
cur
);
}
heap_free
(
debug_client
);
}
return
refcount
;
}
...
...
@@ -195,9 +212,26 @@ static HRESULT STDMETHODCALLTYPE debugclient_GetRunningProcessDescription(IDebug
static
HRESULT
STDMETHODCALLTYPE
debugclient_AttachProcess
(
IDebugClient
*
iface
,
ULONG64
server
,
ULONG
pid
,
ULONG
flags
)
{
FIXME
(
"%p, %s, %u, %#x stub.
\n
"
,
iface
,
wine_dbgstr_longlong
(
server
),
pid
,
flags
);
struct
debug_client
*
debug_client
=
impl_from_IDebugClient
(
iface
);
struct
target_process
*
process
;
return
E_NOTIMPL
;
TRACE
(
"%p, %s, %u, %#x.
\n
"
,
iface
,
wine_dbgstr_longlong
(
server
),
pid
,
flags
);
if
(
server
)
{
FIXME
(
"Remote debugging is not supported.
\n
"
);
return
E_NOTIMPL
;
}
if
(
!
(
process
=
heap_alloc
(
sizeof
(
*
process
))))
return
E_OUTOFMEMORY
;
process
->
pid
=
pid
;
process
->
attach_flags
=
flags
;
list_add_head
(
&
debug_client
->
targets
,
&
process
->
entry
);
return
S_OK
;
}
static
HRESULT
STDMETHODCALLTYPE
debugclient_CreateProcess
(
IDebugClient
*
iface
,
ULONG64
server
,
char
*
cmdline
,
...
...
@@ -2142,6 +2176,7 @@ HRESULT WINAPI DebugCreate(REFIID riid, void **obj)
debug_client
->
IDebugSymbols_iface
.
lpVtbl
=
&
debugsymbolsvtbl
;
debug_client
->
IDebugControl2_iface
.
lpVtbl
=
&
debugcontrolvtbl
;
debug_client
->
refcount
=
1
;
list_init
(
&
debug_client
->
targets
);
unk
=
(
IUnknown
*
)
&
debug_client
->
IDebugClient_iface
;
...
...
dlls/dbgeng/tests/dbgeng.c
View file @
8f3e72ed
...
...
@@ -17,6 +17,7 @@
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "windef.h"
...
...
@@ -99,7 +100,237 @@ static void test_engine_options(void)
control
->
lpVtbl
->
Release
(
control
);
}
static
HRESULT
WINAPI
event_callbacks_QueryInterface
(
IDebugEventCallbacks
*
iface
,
REFIID
riid
,
void
**
out
)
{
if
(
IsEqualIID
(
riid
,
&
IID_IDebugEventCallbacks
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
out
=
iface
;
iface
->
lpVtbl
->
AddRef
(
iface
);
return
S_OK
;
}
*
out
=
NULL
;
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
event_callbacks_AddRef
(
IDebugEventCallbacks
*
iface
)
{
return
2
;
}
static
ULONG
WINAPI
event_callbacks_Release
(
IDebugEventCallbacks
*
iface
)
{
return
1
;
}
static
HRESULT
WINAPI
event_callbacks_GetInterestMask
(
IDebugEventCallbacks
*
iface
,
ULONG
*
mask
)
{
*
mask
=
~
0u
;
return
S_OK
;
}
static
HRESULT
WINAPI
event_callbacks_Breakpoint
(
IDebugEventCallbacks
*
iface
,
PDEBUG_BREAKPOINT
breakpoint
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_Exception
(
IDebugEventCallbacks
*
iface
,
EXCEPTION_RECORD64
*
exception
,
ULONG
first_chance
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_CreateThread
(
IDebugEventCallbacks
*
iface
,
ULONG64
handle
,
ULONG64
data_offset
,
ULONG64
start_offset
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_ExitThread
(
IDebugEventCallbacks
*
iface
,
ULONG
exit_code
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_CreateProcess
(
IDebugEventCallbacks
*
iface
,
ULONG64
image_handle
,
ULONG64
handle
,
ULONG64
base_offset
,
ULONG
module_size
,
const
char
*
module_name
,
const
char
*
image_name
,
ULONG
checksum
,
ULONG
timedatestamp
,
ULONG64
initial_thread_handle
,
ULONG64
thread_data_offset
,
ULONG64
start_offset
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_ExitProcess
(
IDebugEventCallbacks
*
iface
,
ULONG
exit_code
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_LoadModule
(
IDebugEventCallbacks
*
iface
,
ULONG64
image_handle
,
ULONG64
base_offset
,
ULONG
module_size
,
const
char
*
module_name
,
const
char
*
image_name
,
ULONG
checksum
,
ULONG
timedatestamp
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_UnloadModule
(
IDebugEventCallbacks
*
iface
,
const
char
*
image_basename
,
ULONG64
base_offset
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_SystemError
(
IDebugEventCallbacks
*
iface
,
ULONG
error
,
ULONG
level
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_SessionStatus
(
IDebugEventCallbacks
*
iface
,
ULONG
status
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_ChangeDebuggeeState
(
IDebugEventCallbacks
*
iface
,
ULONG
flags
,
ULONG64
argument
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_ChangeEngineState
(
IDebugEventCallbacks
*
iface
,
ULONG
flags
,
ULONG64
argument
)
{
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
event_callbacks_ChangeSymbolState
(
IDebugEventCallbacks
*
iface
,
ULONG
flags
,
ULONG64
argument
)
{
return
E_NOTIMPL
;
}
static
const
IDebugEventCallbacksVtbl
event_callbacks_vtbl
=
{
event_callbacks_QueryInterface
,
event_callbacks_AddRef
,
event_callbacks_Release
,
event_callbacks_GetInterestMask
,
event_callbacks_Breakpoint
,
event_callbacks_Exception
,
event_callbacks_CreateThread
,
event_callbacks_ExitThread
,
event_callbacks_CreateProcess
,
event_callbacks_ExitProcess
,
event_callbacks_LoadModule
,
event_callbacks_UnloadModule
,
event_callbacks_SystemError
,
event_callbacks_SessionStatus
,
event_callbacks_ChangeDebuggeeState
,
event_callbacks_ChangeEngineState
,
event_callbacks_ChangeSymbolState
,
};
static
const
char
*
event_name
=
"dbgeng_test_event"
;
static
void
test_attach
(
void
)
{
IDebugEventCallbacks
event_callbacks
=
{
&
event_callbacks_vtbl
};
PROCESS_INFORMATION
info
;
char
path_name
[
MAX_PATH
];
IDebugControl
*
control
;
IDebugClient
*
client
;
STARTUPINFOA
startup
;
BOOL
is_debugged
;
HANDLE
event
;
char
**
argv
;
HRESULT
hr
;
BOOL
ret
;
hr
=
DebugCreate
(
&
IID_IDebugClient
,
(
void
**
)
&
client
);
ok
(
hr
==
S_OK
,
"Failed to create engine object, hr %#x.
\n
"
,
hr
);
hr
=
client
->
lpVtbl
->
QueryInterface
(
client
,
&
IID_IDebugControl
,
(
void
**
)
&
control
);
ok
(
hr
==
S_OK
,
"Failed to get interface pointer, hr %#x.
\n
"
,
hr
);
hr
=
client
->
lpVtbl
->
SetEventCallbacks
(
client
,
&
event_callbacks
);
todo_wine
ok
(
hr
==
S_OK
,
"Failed to set event callbacks, hr %#x.
\n
"
,
hr
);
event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
event_name
);
ok
(
event
!=
NULL
,
"Failed to create event.
\n
"
);
winetest_get_mainargs
(
&
argv
);
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
sprintf
(
path_name
,
"%s dbgeng target"
,
argv
[
0
]);
ret
=
CreateProcessA
(
NULL
,
path_name
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
startup
,
&
info
),
ok
(
ret
,
"Failed to create target process.
\n
"
);
is_debugged
=
TRUE
;
CheckRemoteDebuggerPresent
(
info
.
hProcess
,
&
is_debugged
);
ok
(
!
is_debugged
,
"Unexpected mode.
\n
"
);
/* Non-invasive mode. */
hr
=
client
->
lpVtbl
->
AttachProcess
(
client
,
0
,
info
.
dwProcessId
,
DEBUG_ATTACH_NONINVASIVE
);
ok
(
hr
==
S_OK
,
"Failed to attach to process, hr %#x.
\n
"
,
hr
);
is_debugged
=
TRUE
;
ret
=
CheckRemoteDebuggerPresent
(
info
.
hProcess
,
&
is_debugged
);
ok
(
ret
,
"Failed to check target status.
\n
"
);
ok
(
!
is_debugged
,
"Unexpected mode.
\n
"
);
hr
=
control
->
lpVtbl
->
WaitForEvent
(
control
,
0
,
INFINITE
);
todo_wine
ok
(
hr
==
S_OK
,
"Waiting for event failed, hr %#x.
\n
"
,
hr
);
is_debugged
=
TRUE
;
ret
=
CheckRemoteDebuggerPresent
(
info
.
hProcess
,
&
is_debugged
);
ok
(
ret
,
"Failed to check target status.
\n
"
);
ok
(
!
is_debugged
,
"Unexpected mode.
\n
"
);
hr
=
client
->
lpVtbl
->
DetachProcesses
(
client
);
todo_wine
ok
(
hr
==
S_OK
,
"Failed to detach, hr %#x.
\n
"
,
hr
);
hr
=
client
->
lpVtbl
->
EndSession
(
client
,
DEBUG_END_ACTIVE_DETACH
);
todo_wine
ok
(
hr
==
S_OK
,
"Failed to end session, hr %#x.
\n
"
,
hr
);
SetEvent
(
event
);
winetest_wait_child_process
(
info
.
hProcess
);
CloseHandle
(
info
.
hProcess
);
CloseHandle
(
info
.
hThread
);
CloseHandle
(
event
);
client
->
lpVtbl
->
Release
(
client
);
control
->
lpVtbl
->
Release
(
control
);
}
static
void
target_proc
(
void
)
{
HANDLE
event
=
OpenEventA
(
SYNCHRONIZE
,
FALSE
,
event_name
);
ok
(
event
!=
NULL
,
"Failed to open event handle.
\n
"
);
for
(;;)
{
if
(
WaitForSingleObject
(
event
,
100
)
==
WAIT_OBJECT_0
)
break
;
}
CloseHandle
(
event
);
}
START_TEST
(
dbgeng
)
{
char
**
argv
;
int
argc
;
argc
=
winetest_get_mainargs
(
&
argv
);
if
(
argc
>=
3
&&
!
strcmp
(
argv
[
2
],
"target"
))
{
target_proc
();
return
;
}
test_engine_options
();
test_attach
();
}
include/dbgeng.h
View file @
8f3e72ed
...
...
@@ -73,6 +73,95 @@ DEFINE_GUID(IID_IDebugSystemObjects3, 0xe9676e2f, 0xe286, 0x4ea3, 0xb0, 0xf9
#define DEBUG_ATTACH_INVASIVE_RESUME_PROCESS 0x00000010
#define DEBUG_ATTACH_NONINVASIVE_ALLOW_PARTIAL 0x00000020
/* EndSession() flags */
#define DEBUG_END_PASSIVE 0x00000000
#define DEBUG_END_ACTIVE_TERMINATE 0x00000001
#define DEBUG_END_ACTIVE_DETACH 0x00000002
#define DEBUG_END_REENTRANT 0x00000003
#define DEBUG_END_DISCONNECT 0x00000004
/* ChangeEngineState() flags */
#define DEBUG_CES_CURRENT_THREAD 0x00000001
#define DEBUG_CES_EFFECTIVE_PROCESSOR 0x00000002
#define DEBUG_CES_BREAKPOINTS 0x00000004
#define DEBUG_CES_CODE_LEVEL 0x00000008
#define DEBUG_CES_EXECUTION_STATUS 0x00000010
#define DEBUG_CES_ENGINE_OPTIONS 0x00000020
#define DEBUG_CES_LOG_FILE 0x00000040
#define DEBUG_CES_RADIX 0x00000080
#define DEBUG_CES_EVENT_FILTERS 0x00000100
#define DEBUG_CES_PROCESS_OPTIONS 0x00000200
#define DEBUG_CES_EXTENSIONS 0x00000400
#define DEBUG_CES_SYSTEMS 0x00000800
#define DEBUG_CES_ASSEMBLY_OPTIONS 0x00001000
#define DEBUG_CES_EXPRESSION_SYNTAX 0x00002000
#define DEBUG_CES_TEXT_REPLACEMENTS 0x00004000
#define DEBUG_CES_ALL 0xffffffff
#define DEBUG_STATUS_NO_CHANGE 0
#define DEBUG_STATUS_GO 1
#define DEBUG_STATUS_GO_HANDLED 2
#define DEBUG_STATUS_GO_NOT_HANDLED 3
#define DEBUG_STATUS_STEP_OVER 4
#define DEBUG_STATUS_STEP_INTO 5
#define DEBUG_STATUS_BREAK 6
#define DEBUG_STATUS_NO_DEBUGGEE 7
#define DEBUG_STATUS_STEP_BRANCH 8
#define DEBUG_STATUS_IGNORE_EVENT 9
#define DEBUG_STATUS_RESTART_REQUESTED 10
#define DEBUG_STATUS_REVERSE_GO 11
#define DEBUG_STATUS_REVERSE_STEP_BRANCH 12
#define DEBUG_STATUS_REVERSE_STEP_OVER 13
#define DEBUG_STATUS_REVERSE_STEP_INTO 14
#define DEBUG_STATUS_OUT_OF_SYNC 15
#define DEBUG_STATUS_WAIT_INPUT 16
#define DEBUG_STATUS_TIMEOUT 17
#define DEBUG_STATUS_MASK 0x1f
/* ChangeSymbolState() flags */
#define DEBUG_CSS_LOADS 0x00000001
#define DEBUG_CSS_UNLOADS 0x00000002
#define DEBUG_CSS_SCOPE 0x00000004
#define DEBUG_CSS_PATHS 0x00000008
#define DEBUG_CSS_SYMBOL_OPTIONS 0x00000010
#define DEBUG_CSS_TYPE_OPTIONS 0x00000020
#define DEBUG_CSS_COLLAPSE_CHILDREN 0x00000040
#define DEBUG_CSS_ALL 0xffffffff
/* SessionStatus() flags */
#define DEBUG_SESSION_ACTIVE 0x00000000
#define DEBUG_SESSION_END_SESSION_ACTIVE_TERMINATE 0x00000001
#define DEBUG_SESSION_END_SESSION_ACTIVE_DETACH 0x00000002
#define DEBUG_SESSION_END_SESSION_PASSIVE 0x00000003
#define DEBUG_SESSION_END 0x00000004
#define DEBUG_SESSION_REBOOT 0x00000005
#define DEBUG_SESSION_HIBERNATE 0x00000006
#define DEBUG_SESSION_FAILURE 0x00000007
/* ChangeDebuggeeState() flags */
#define DEBUG_CDS_REGISTERS 0x00000001
#define DEBUG_CDS_DATA 0x00000002
#define DEBUG_CDS_REFRESH 0x00000004
#define DEBUG_CDS_ALL 0xffffffff
#define DEBUG_CDS_REFRESH_EVALUATE 1
#define DEBUG_CDS_REFRESH_EXECUTE 2
#define DEBUG_CDS_REFRESH_EXECUTECOMMANDFILE 3
#define DEBUG_CDS_REFRESH_ADDBREAKPOINT 4
#define DEBUG_CDS_REFRESH_REMOVEBREAKPOINT 5
#define DEBUG_CDS_REFRESH_WRITEVIRTUAL 6
#define DEBUG_CDS_REFRESH_WRITEVIRTUALUNCACHED 7
#define DEBUG_CDS_REFRESH_WRITEPHYSICAL 8
#define DEBUG_CDS_REFRESH_WRITEPHYSICAL2 9
#define DEBUG_CDS_REFRESH_SETVALUE 10
#define DEBUG_CDS_REFRESH_SETVALUE2 11
#define DEBUG_CDS_REFRESH_SETSCOPE 12
#define DEBUG_CDS_REFRESH_SETSCOPEFRAMEBYINDEX 13
#define DEBUG_CDS_REFRESH_SETSCOPEFROMJITDEBUGINFO 14
#define DEBUG_CDS_REFRESH_SETSCOPEFROMSTOREDEVENT 15
#define DEBUG_CDS_REFRESH_INLINESTEP 16
#define DEBUG_CDS_REFRESH_INLINESTEP_PSEUDO 17
typedef
struct
_DEBUG_MODULE_PARAMETERS
{
ULONG64
Base
;
...
...
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