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
d33180ae
Commit
d33180ae
authored
Apr 22, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
Apr 22, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dbgeng: Implement GetModuleByIndex().
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
73a8fe94
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
119 additions
and
18 deletions
+119
-18
dbgeng.c
dlls/dbgeng/dbgeng.c
+70
-4
dbgeng.c
dlls/dbgeng/tests/dbgeng.c
+49
-14
No files found.
dlls/dbgeng/dbgeng.c
View file @
d33180ae
...
...
@@ -39,6 +39,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbgeng);
extern
NTSTATUS
WINAPI
NtSuspendProcess
(
HANDLE
handle
);
extern
NTSTATUS
WINAPI
NtResumeProcess
(
HANDLE
handle
);
struct
module_info
{
DEBUG_MODULE_PARAMETERS
params
;
};
struct
target_process
{
struct
list
entry
;
...
...
@@ -47,6 +52,7 @@ struct target_process
HANDLE
handle
;
struct
{
struct
module_info
*
info
;
unsigned
int
loaded
;
unsigned
int
unloaded
;
BOOL
initialized
;
...
...
@@ -75,6 +81,9 @@ static struct target_process *debug_client_get_target(struct debug_client *debug
static
HRESULT
debug_target_init_modules_info
(
struct
target_process
*
target
)
{
unsigned
int
i
,
count
;
HMODULE
*
modules
;
MODULEINFO
info
;
DWORD
needed
;
if
(
target
->
modules
.
initialized
)
...
...
@@ -88,7 +97,35 @@ static HRESULT debug_target_init_modules_info(struct target_process *target)
if
(
!
needed
)
return
E_FAIL
;
target
->
modules
.
loaded
=
needed
/
sizeof
(
HMODULE
);
count
=
needed
/
sizeof
(
HMODULE
);
if
(
!
(
modules
=
heap_alloc
(
count
*
sizeof
(
*
modules
))))
return
E_OUTOFMEMORY
;
if
(
!
(
target
->
modules
.
info
=
heap_alloc_zero
(
count
*
sizeof
(
*
target
->
modules
.
info
))))
{
heap_free
(
modules
);
return
E_OUTOFMEMORY
;
}
if
(
EnumProcessModules
(
target
->
handle
,
modules
,
count
*
sizeof
(
*
modules
),
&
needed
))
{
for
(
i
=
0
;
i
<
count
;
++
i
)
{
if
(
!
GetModuleInformation
(
target
->
handle
,
modules
[
i
],
&
info
,
sizeof
(
info
)))
{
WARN
(
"Failed to get module information, error %d.
\n
"
,
GetLastError
());
continue
;
}
target
->
modules
.
info
[
i
].
params
.
Base
=
(
ULONG_PTR
)
info
.
lpBaseOfDll
;
target
->
modules
.
info
[
i
].
params
.
Size
=
info
.
SizeOfImage
;
}
}
heap_free
(
modules
);
target
->
modules
.
loaded
=
count
;
target
->
modules
.
unloaded
=
0
;
/* FIXME */
target
->
modules
.
initialized
=
TRUE
;
...
...
@@ -96,6 +133,17 @@ static HRESULT debug_target_init_modules_info(struct target_process *target)
return
S_OK
;
}
static
const
struct
module_info
*
debug_target_get_module_info
(
struct
target_process
*
target
,
unsigned
int
i
)
{
if
(
FAILED
(
debug_target_init_modules_info
(
target
)))
return
NULL
;
if
(
i
>=
target
->
modules
.
loaded
)
return
NULL
;
return
&
target
->
modules
.
info
[
i
];
}
static
void
debug_client_detach_target
(
struct
target_process
*
target
)
{
NTSTATUS
status
;
...
...
@@ -185,6 +233,12 @@ static ULONG STDMETHODCALLTYPE debugclient_AddRef(IDebugClient *iface)
return
refcount
;
}
static
void
debug_target_free
(
struct
target_process
*
target
)
{
heap_free
(
target
->
modules
.
info
);
heap_free
(
target
);
}
static
ULONG
STDMETHODCALLTYPE
debugclient_Release
(
IDebugClient
*
iface
)
{
struct
debug_client
*
debug_client
=
impl_from_IDebugClient
(
iface
);
...
...
@@ -199,7 +253,7 @@ static ULONG STDMETHODCALLTYPE debugclient_Release(IDebugClient *iface)
{
debug_client_detach_target
(
cur
);
list_remove
(
&
cur
->
entry
);
heap
_free
(
cur
);
debug_target
_free
(
cur
);
}
if
(
debug_client
->
event_callbacks
)
debug_client
->
event_callbacks
->
lpVtbl
->
Release
(
debug_client
->
event_callbacks
);
...
...
@@ -955,9 +1009,21 @@ static HRESULT STDMETHODCALLTYPE debugsymbols_GetNumberModules(IDebugSymbols3 *i
static
HRESULT
STDMETHODCALLTYPE
debugsymbols_GetModuleByIndex
(
IDebugSymbols3
*
iface
,
ULONG
index
,
ULONG64
*
base
)
{
FIXME
(
"%p, %u, %p stub.
\n
"
,
iface
,
index
,
base
);
struct
debug_client
*
debug_client
=
impl_from_IDebugSymbols3
(
iface
);
const
struct
module_info
*
info
;
struct
target_process
*
target
;
return
E_NOTIMPL
;
TRACE
(
"%p, %u, %p.
\n
"
,
iface
,
index
,
base
);
if
(
!
(
target
=
debug_client_get_target
(
debug_client
)))
return
E_UNEXPECTED
;
if
(
!
(
info
=
debug_target_get_module_info
(
target
,
index
)))
return
E_INVALIDARG
;
*
base
=
info
->
params
.
Base
;
return
S_OK
;
}
static
HRESULT
STDMETHODCALLTYPE
debugsymbols_GetModuleByModuleName
(
IDebugSymbols3
*
iface
,
const
char
*
name
,
...
...
dlls/dbgeng/tests/dbgeng.c
View file @
d33180ae
...
...
@@ -224,23 +224,36 @@ static const IDebugEventCallbacksVtbl event_callbacks_vtbl =
event_callbacks_ChangeSymbolState
,
};
static
const
char
*
event_name
=
"dbgeng_test_event"
;
static
BOOL
create_target_process
(
PROCESS_INFORMATION
*
info
)
static
BOOL
create_target_process
(
const
char
*
event_name
,
PROCESS_INFORMATION
*
info
)
{
static
const
char
*
event_target_ready_name
=
"dbgeng_test_target_ready_event"
;
char
path_name
[
MAX_PATH
];
STARTUPINFOA
startup
;
HANDLE
ready_event
;
char
**
argv
;
BOOL
ret
;
ready_event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
event_target_ready_name
);
ok
(
ready_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
]);
return
CreateProcessA
(
NULL
,
path_name
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
startup
,
info
);
sprintf
(
path_name
,
"%s dbgeng target %s %s"
,
argv
[
0
],
event_name
,
event_target_ready_name
);
ret
=
CreateProcessA
(
NULL
,
path_name
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
startup
,
info
);
if
(
ret
)
{
WaitForSingleObject
(
ready_event
,
INFINITE
);
}
CloseHandle
(
ready_event
);
return
ret
;
}
static
void
test_attach
(
void
)
{
static
const
char
*
event_name
=
"dbgeng_test_event"
;
IDebugEventCallbacks
event_callbacks
=
{
&
event_callbacks_vtbl
};
PROCESS_INFORMATION
info
;
IDebugControl
*
control
;
...
...
@@ -262,7 +275,7 @@ static void test_attach(void)
event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
event_name
);
ok
(
event
!=
NULL
,
"Failed to create event.
\n
"
);
ret
=
create_target_process
(
&
info
);
ret
=
create_target_process
(
event_name
,
&
info
);
ok
(
ret
,
"Failed to create target process.
\n
"
);
is_debugged
=
TRUE
;
...
...
@@ -308,11 +321,13 @@ todo_wine
static
void
test_module_information
(
void
)
{
static
const
char
*
event_name
=
"dbgeng_test_event"
;
unsigned
int
loaded
,
unloaded
;
PROCESS_INFORMATION
info
;
IDebugSymbols
*
symbols
;
IDebugControl
*
control
;
IDebugClient
*
client
;
ULONG64
base
;
HANDLE
event
;
HRESULT
hr
;
BOOL
ret
;
...
...
@@ -329,9 +344,12 @@ static void test_module_information(void)
event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
event_name
);
ok
(
event
!=
NULL
,
"Failed to create event.
\n
"
);
ret
=
create_target_process
(
&
info
);
ret
=
create_target_process
(
event_name
,
&
info
);
ok
(
ret
,
"Failed to create target process.
\n
"
);
hr
=
control
->
lpVtbl
->
SetEngineOptions
(
control
,
DEBUG_ENGOPT_INITIAL_BREAK
);
ok
(
hr
==
S_OK
,
"Failed to set engine options, hr %#x.
\n
"
,
hr
);
hr
=
client
->
lpVtbl
->
AttachProcess
(
client
,
0
,
info
.
dwProcessId
,
DEBUG_ATTACH_NONINVASIVE
);
ok
(
hr
==
S_OK
,
"Failed to attach to process, hr %#x.
\n
"
,
hr
);
...
...
@@ -341,6 +359,16 @@ static void test_module_information(void)
/* Number of modules. */
hr
=
symbols
->
lpVtbl
->
GetNumberModules
(
symbols
,
&
loaded
,
&
unloaded
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
ok
(
loaded
>
0
,
"Unexpected module count %u.
\n
"
,
loaded
);
/* Module base. */
hr
=
symbols
->
lpVtbl
->
GetModuleByIndex
(
symbols
,
loaded
,
&
base
);
ok
(
FAILED
(
hr
),
"Unexpected hr %#x.
\n
"
,
hr
);
base
=
0
;
hr
=
symbols
->
lpVtbl
->
GetModuleByIndex
(
symbols
,
0
,
&
base
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
ok
(
!!
base
,
"Unexpected module base.
\n
"
);
hr
=
client
->
lpVtbl
->
DetachProcesses
(
client
);
ok
(
hr
==
S_OK
,
"Failed to detach, hr %#x.
\n
"
,
hr
);
...
...
@@ -356,19 +384,26 @@ static void test_module_information(void)
symbols
->
lpVtbl
->
Release
(
symbols
);
}
static
void
target_proc
(
void
)
static
void
target_proc
(
const
char
*
event_name
,
const
char
*
event_ready_name
)
{
HANDLE
event
=
OpenEventA
(
SYNCHRONIZE
,
FALSE
,
event_name
)
;
HANDLE
terminate_event
,
ready_event
;
ok
(
event
!=
NULL
,
"Failed to open event handle.
\n
"
);
terminate_event
=
OpenEventA
(
SYNCHRONIZE
,
FALSE
,
event_name
);
ok
(
terminate_event
!=
NULL
,
"Failed to open event handle.
\n
"
);
ready_event
=
OpenEventA
(
EVENT_MODIFY_STATE
,
FALSE
,
event_ready_name
);
ok
(
ready_event
!=
NULL
,
"Failed to open event handle.
\n
"
);
SetEvent
(
ready_event
);
for
(;;)
{
if
(
WaitForSingleObject
(
event
,
100
)
==
WAIT_OBJECT_0
)
if
(
WaitForSingleObject
(
terminate_
event
,
100
)
==
WAIT_OBJECT_0
)
break
;
}
CloseHandle
(
event
);
CloseHandle
(
terminate_event
);
CloseHandle
(
ready_event
);
}
START_TEST
(
dbgeng
)
...
...
@@ -378,9 +413,9 @@ START_TEST(dbgeng)
argc
=
winetest_get_mainargs
(
&
argv
);
if
(
argc
>
=
3
&&
!
strcmp
(
argv
[
2
],
"target"
))
if
(
argc
>
4
&&
!
strcmp
(
argv
[
2
],
"target"
))
{
target_proc
();
target_proc
(
argv
[
3
],
argv
[
4
]
);
return
;
}
...
...
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