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
d29c6ead
Commit
d29c6ead
authored
Mar 30, 2010
by
Eric Pouech
Committed by
Alexandre Julliard
Mar 31, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winedbg: Store the CONTEXT in each stack frame to enable register access in the non topmost frames.
parent
1991ff2a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
54 additions
and
20 deletions
+54
-20
debugger.h
programs/winedbg/debugger.h
+4
-2
memory.c
programs/winedbg/memory.c
+3
-8
stack.c
programs/winedbg/stack.c
+45
-8
tgt_active.c
programs/winedbg/tgt_active.c
+1
-1
tgt_minidump.c
programs/winedbg/tgt_minidump.c
+1
-1
No files found.
programs/winedbg/debugger.h
View file @
d29c6ead
...
...
@@ -192,6 +192,8 @@ struct dbg_thread
DWORD_PTR
linear_pc
;
DWORD_PTR
linear_frame
;
DWORD_PTR
linear_stack
;
CONTEXT
context
;
/* context we got out of stackwalk for this frame */
BOOL
is_ctx_valid
;
/* is the context above valid */
}
*
frames
;
int
num_frames
;
int
curr_frame
;
...
...
@@ -387,8 +389,8 @@ extern void stack_info(void);
extern
void
stack_backtrace
(
DWORD
threadID
);
extern
BOOL
stack_set_frame
(
int
newframe
);
extern
BOOL
stack_get_current_frame
(
IMAGEHLP_STACK_FRAME
*
ihsf
);
extern
BOOL
stack_get_register_
current_frame
(
unsigned
regno
,
DWORD_PTR
**
pval
);
extern
unsigned
stack_fetch_frames
(
void
);
extern
BOOL
stack_get_register_
frame
(
const
struct
dbg_internal_var
*
div
,
DWORD_PTR
**
pval
);
extern
unsigned
stack_fetch_frames
(
const
CONTEXT
*
ctx
);
extern
BOOL
stack_get_current_symbol
(
SYMBOL_INFO
*
sym
);
/* symbol.c */
...
...
programs/winedbg/memory.c
View file @
d29c6ead
...
...
@@ -694,16 +694,11 @@ BOOL memory_get_register(DWORD regno, DWORD_PTR** value, char* buffer, int len)
{
if
(
div
->
val
==
regno
)
{
if
(
dbg_curr_thread
->
curr_frame
!=
0
)
if
(
!
stack_get_register_frame
(
div
,
value
)
)
{
if
(
!
stack_get_register_current_frame
(
regno
,
value
))
{
if
(
buffer
)
snprintf
(
buffer
,
len
,
"<register %s not in topmost frame>"
,
div
->
name
);
return
FALSE
;
}
if
(
buffer
)
snprintf
(
buffer
,
len
,
"<register %s not accessible in this frame>"
,
div
->
name
);
return
FALSE
;
}
else
*
value
=
(
DWORD_PTR
*
)((
char
*
)
&
dbg_context
+
(
DWORD_PTR
)
div
->
pval
);
if
(
buffer
)
lstrcpynA
(
buffer
,
div
->
name
,
len
);
return
TRUE
;
...
...
programs/winedbg/stack.c
View file @
d29c6ead
...
...
@@ -119,6 +119,35 @@ BOOL stack_get_register_current_frame(unsigned regno, DWORD_PTR** pval)
return
TRUE
;
}
BOOL
stack_get_register_frame
(
const
struct
dbg_internal_var
*
div
,
DWORD_PTR
**
pval
)
{
if
(
dbg_curr_thread
->
frames
==
NULL
)
return
FALSE
;
if
(
dbg_curr_thread
->
frames
[
dbg_curr_thread
->
curr_frame
].
is_ctx_valid
)
*
pval
=
(
DWORD_PTR
*
)((
char
*
)
&
dbg_curr_thread
->
frames
[
dbg_curr_thread
->
curr_frame
].
context
+
(
DWORD_PTR
)
div
->
pval
);
else
{
enum
be_cpu_addr
kind
;
if
(
!
be_cpu
->
get_register_info
(
div
->
val
,
&
kind
))
return
FALSE
;
/* reuse some known registers directly out of stackwalk details */
switch
(
kind
)
{
case
be_cpu_addr_pc
:
*
pval
=
&
dbg_curr_thread
->
frames
[
dbg_curr_thread
->
curr_frame
].
linear_pc
;
break
;
case
be_cpu_addr_stack
:
*
pval
=
&
dbg_curr_thread
->
frames
[
dbg_curr_thread
->
curr_frame
].
linear_stack
;
break
;
case
be_cpu_addr_frame
:
*
pval
=
&
dbg_curr_thread
->
frames
[
dbg_curr_thread
->
curr_frame
].
linear_frame
;
break
;
}
}
return
TRUE
;
}
BOOL
stack_set_frame
(
int
newframe
)
{
ADDRESS64
addr
;
...
...
@@ -163,14 +192,14 @@ static BOOL CALLBACK stack_read_mem(HANDLE hProc, DWORD64 addr,
*
* Do a backtrace on the current thread
*/
unsigned
stack_fetch_frames
(
void
)
unsigned
stack_fetch_frames
(
const
CONTEXT
*
_ctx
)
{
STACKFRAME64
sf
;
unsigned
nf
=
0
;
/* as native stackwalk can modify the context passed to it, simply copy
* it to avoid any damage
*/
CONTEXT
ctx
=
dbg_context
;
CONTEXT
ctx
=
*
_ctx
,
prevctx
=
ctx
;
HeapFree
(
GetProcessHeap
(),
0
,
dbg_curr_thread
->
frames
);
dbg_curr_thread
->
frames
=
NULL
;
...
...
@@ -200,6 +229,15 @@ unsigned stack_fetch_frames(void)
dbg_curr_thread
->
frames
[
nf
].
linear_frame
=
(
DWORD_PTR
)
memory_to_linear_addr
(
&
sf
.
AddrFrame
);
dbg_curr_thread
->
frames
[
nf
].
addr_stack
=
sf
.
AddrStack
;
dbg_curr_thread
->
frames
[
nf
].
linear_stack
=
(
DWORD_PTR
)
memory_to_linear_addr
(
&
sf
.
AddrStack
);
dbg_curr_thread
->
frames
[
nf
].
context
=
prevctx
;
/* FIXME: can this heuristic be improved: we declare first context always valid, and next ones
* if it has been modified by the call to StackWalk...
*/
dbg_curr_thread
->
frames
[
nf
].
is_ctx_valid
=
(
nf
==
0
||
(
dbg_curr_thread
->
frames
[
nf
-
1
].
is_ctx_valid
&&
memcmp
(
&
dbg_curr_thread
->
frames
[
nf
-
1
].
context
,
&
ctx
,
sizeof
(
ctx
))));
prevctx
=
ctx
;
nf
++
;
/* we've probably gotten ourselves into an infinite loop so bail */
if
(
nf
>
200
)
break
;
...
...
@@ -317,27 +355,26 @@ static void backtrace_tid(struct dbg_process* pcs, DWORD tid)
dbg_printf
(
"Unknown thread id (%04x) in process (%04x)
\n
"
,
tid
,
pcs
->
pid
);
else
{
CONTEXT
saved_ctx
=
dbg_
context
;
CONTEXT
context
;
dbg_curr_tid
=
dbg_curr_thread
->
tid
;
memset
(
&
dbg_context
,
0
,
sizeof
(
dbg_
context
));
dbg_
context
.
ContextFlags
=
CONTEXT_FULL
;
memset
(
&
context
,
0
,
sizeof
(
context
));
context
.
ContextFlags
=
CONTEXT_FULL
;
if
(
SuspendThread
(
dbg_curr_thread
->
handle
)
!=
-
1
)
{
if
(
!
GetThreadContext
(
dbg_curr_thread
->
handle
,
&
dbg_
context
))
if
(
!
GetThreadContext
(
dbg_curr_thread
->
handle
,
&
context
))
{
dbg_printf
(
"Can't get context for thread %04x in current process
\n
"
,
tid
);
}
else
{
stack_fetch_frames
();
stack_fetch_frames
(
&
context
);
backtrace
();
}
ResumeThread
(
dbg_curr_thread
->
handle
);
}
else
dbg_printf
(
"Can't suspend thread %04x in current process
\n
"
,
tid
);
dbg_context
=
saved_ctx
;
}
dbg_curr_thread
=
thread
;
dbg_curr_tid
=
thread
?
thread
->
tid
:
0
;
...
...
programs/winedbg/tgt_active.c
View file @
d29c6ead
...
...
@@ -157,7 +157,7 @@ static unsigned dbg_exception_prolog(BOOL is_debug, BOOL first_chance, const EXC
* Do a quiet backtrace so that we have an idea of what the situation
* is WRT the source files.
*/
stack_fetch_frames
();
stack_fetch_frames
(
&
dbg_context
);
if
(
is_debug
&&
!
is_break
&&
break_should_continue
(
&
addr
,
rec
->
ExceptionCode
))
return
FALSE
;
...
...
programs/winedbg/tgt_minidump.c
View file @
d29c6ead
...
...
@@ -376,7 +376,7 @@ static enum dbg_start minidump_do_reload(struct tgt_process_minidump_data* data)
memcpy
(
&
dbg_context
,
(
char
*
)
data
->
mapping
+
mes
->
ThreadContext
.
Rva
,
min
(
sizeof
(
dbg_context
),
mes
->
ThreadContext
.
DataSize
));
memory_get_current_pc
(
&
addr
);
stack_fetch_frames
();
stack_fetch_frames
(
&
dbg_context
);
be_cpu
->
print_context
(
dbg_curr_thread
->
handle
,
&
dbg_context
,
0
);
stack_info
();
be_cpu
->
print_segment_info
(
dbg_curr_thread
->
handle
,
&
dbg_context
);
...
...
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