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
16e88165
Commit
16e88165
authored
Mar 13, 2011
by
Eric Pouech
Committed by
Alexandre Julliard
Mar 14, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dbghelp: When doing a stack backtrace on i386 with dwarf or pdb unwinders, get…
dbghelp: When doing a stack backtrace on i386 with dwarf or pdb unwinders, get the PC from the right frame.
parent
91565010
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
81 additions
and
83 deletions
+81
-83
cpu_i386.c
dlls/dbghelp/cpu_i386.c
+79
-80
stack.c
programs/winedbg/stack.c
+2
-3
No files found.
dlls/dbghelp/cpu_i386.c
View file @
16e88165
...
...
@@ -87,6 +87,51 @@ static unsigned i386_get_addr(HANDLE hThread, const CONTEXT* ctx,
return
FALSE
;
}
#ifdef __i386__
/* fetch_next_frame32()
*
* modify (at least) context.{eip, esp, ebp} using unwind information
* either out of debug info (dwarf, pdb), or simple stack unwind
*/
static
BOOL
fetch_next_frame32
(
struct
cpu_stack_walk
*
csw
,
CONTEXT
*
context
,
DWORD_PTR
curr_pc
)
{
DWORD_PTR
xframe
;
struct
pdb_cmd_pair
cpair
[
4
];
DWORD
val32
;
if
(
dwarf2_virtual_unwind
(
csw
,
curr_pc
,
context
,
&
xframe
))
{
context
->
Esp
=
xframe
;
return
TRUE
;
}
cpair
[
0
].
name
=
"$ebp"
;
cpair
[
0
].
pvalue
=
&
context
->
Ebp
;
cpair
[
1
].
name
=
"$esp"
;
cpair
[
1
].
pvalue
=
&
context
->
Esp
;
cpair
[
2
].
name
=
"$eip"
;
cpair
[
2
].
pvalue
=
&
context
->
Eip
;
cpair
[
3
].
name
=
NULL
;
cpair
[
3
].
pvalue
=
NULL
;
if
(
!
pdb_virtual_unwind
(
csw
,
curr_pc
,
context
,
cpair
))
{
/* do a simple unwind using ebp
* we assume a "regular" prologue in the function has been used
*/
context
->
Esp
=
context
->
Ebp
+
2
*
sizeof
(
DWORD
);
if
(
!
sw_read_mem
(
csw
,
context
->
Ebp
+
sizeof
(
DWORD
),
&
val32
,
sizeof
(
DWORD
)))
{
WARN
(
"Cannot read new frame offset %p
\n
"
,
(
void
*
)(
DWORD_PTR
)(
context
->
Ebp
+
(
int
)
sizeof
(
DWORD
)));
return
FALSE
;
}
context
->
Eip
=
val32
;
/* "pop up" previous EBP value */
if
(
!
sw_read_mem
(
csw
,
context
->
Ebp
,
&
val32
,
sizeof
(
DWORD
)))
return
FALSE
;
context
->
Ebp
=
val32
;
}
return
TRUE
;
}
#endif
enum
st_mode
{
stm_start
,
stm_32bit
,
stm_16bit
,
stm_done
};
/* indexes in Reserved array */
...
...
@@ -197,7 +242,6 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
goto
done_err
;
}
curr_switch
=
(
DWORD_PTR
)
frame16
.
frame32
;
if
(
!
sw_read_mem
(
csw
,
curr_switch
,
&
ch
,
sizeof
(
ch
)))
curr_switch
=
0xFFFFFFFF
;
}
...
...
@@ -212,32 +256,6 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
* we will get it in the next frame
*/
memset
(
&
frame
->
AddrBStore
,
0
,
sizeof
(
frame
->
AddrBStore
));
#ifdef __i386__
if
(
curr_mode
==
stm_32bit
)
{
DWORD_PTR
xframe
;
struct
pdb_cmd_pair
cpair
[
4
];
CONTEXT
newctx
=
*
context
;
if
(
dwarf2_virtual_unwind
(
csw
,
frame
->
AddrPC
.
Offset
-
deltapc
,
&
newctx
,
&
xframe
))
{
frame
->
AddrReturn
.
Mode
=
AddrModeFlat
;
frame
->
AddrReturn
.
Offset
=
newctx
.
Eip
;
goto
done_pep
;
}
cpair
[
0
].
name
=
"$ebp"
;
cpair
[
0
].
pvalue
=
&
newctx
.
Ebp
;
cpair
[
1
].
name
=
"$esp"
;
cpair
[
1
].
pvalue
=
&
newctx
.
Esp
;
cpair
[
2
].
name
=
"$eip"
;
cpair
[
2
].
pvalue
=
&
newctx
.
Eip
;
cpair
[
3
].
name
=
NULL
;
cpair
[
3
].
pvalue
=
NULL
;
if
(
pdb_virtual_unwind
(
csw
,
frame
->
AddrPC
.
Offset
-
deltapc
,
&
newctx
,
cpair
))
{
frame
->
AddrReturn
.
Mode
=
AddrModeFlat
;
frame
->
AddrReturn
.
Offset
=
newctx
.
Eip
;
goto
done_pep
;
}
}
#endif
}
else
{
...
...
@@ -352,9 +370,9 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
}
else
{
frame
->
AddrPC
=
frame
->
AddrReturn
;
if
(
curr_mode
==
stm_16bit
)
{
frame
->
AddrPC
=
frame
->
AddrReturn
;
frame
->
AddrStack
.
Offset
=
frame
->
AddrFrame
.
Offset
+
2
*
sizeof
(
WORD
);
/* "pop up" previous BP value */
if
(
!
sw_read_mem
(
csw
,
sw_xlat_addr
(
csw
,
&
frame
->
AddrFrame
),
...
...
@@ -365,36 +383,17 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
else
{
#ifdef __i386__
DWORD_PTR
xframe
;
struct
pdb_cmd_pair
cpair
[
4
];
if
(
dwarf2_virtual_unwind
(
csw
,
frame
->
AddrPC
.
Offset
-
deltapc
,
context
,
&
xframe
))
{
frame
->
AddrStack
.
Mode
=
frame
->
AddrFrame
.
Mode
=
frame
->
AddrReturn
.
Mode
=
AddrModeFlat
;
frame
->
AddrStack
.
Offset
=
context
->
Esp
=
xframe
;
frame
->
AddrFrame
.
Offset
=
context
->
Ebp
;
frame
->
AddrReturn
.
Offset
=
context
->
Eip
;
goto
done_pep
;
}
cpair
[
0
].
name
=
"$ebp"
;
cpair
[
0
].
pvalue
=
&
context
->
Ebp
;
cpair
[
1
].
name
=
"$esp"
;
cpair
[
1
].
pvalue
=
&
context
->
Esp
;
cpair
[
2
].
name
=
"$eip"
;
cpair
[
2
].
pvalue
=
&
context
->
Eip
;
cpair
[
3
].
name
=
NULL
;
cpair
[
3
].
pvalue
=
NULL
;
if
(
!
fetch_next_frame32
(
csw
,
context
,
sw_xlat_addr
(
csw
,
&
frame
->
AddrPC
)
-
deltapc
))
goto
done_err
;
if
(
pdb_virtual_unwind
(
csw
,
frame
->
AddrPC
.
Offset
-
deltapc
,
context
,
cpair
))
{
frame
->
AddrStack
.
Mode
=
frame
->
AddrFrame
.
Mode
=
frame
->
AddrReturn
.
Mode
=
AddrModeFlat
;
frame
->
AddrStack
.
Offset
=
context
->
Esp
;
frame
->
AddrFrame
.
Offset
=
context
->
Ebp
;
frame
->
AddrReturn
.
Offset
=
context
->
Eip
;
goto
done_pep
;
}
frame
->
AddrStack
.
Mode
=
frame
->
AddrFrame
.
Mode
=
frame
->
AddrPC
.
Mode
=
AddrModeFlat
;
frame
->
AddrStack
.
Offset
=
context
->
Esp
;
frame
->
AddrFrame
.
Offset
=
context
->
Ebp
;
if
(
frame
->
AddrReturn
.
Offset
!=
context
->
Eip
)
FIXME
(
"new PC=%s different from Eip=%x
\n
"
,
wine_dbgstr_longlong
(
frame
->
AddrReturn
.
Offset
),
context
->
Eip
);
frame
->
AddrPC
.
Offset
=
context
->
Eip
;
#endif
frame
->
AddrStack
.
Offset
=
frame
->
AddrFrame
.
Offset
+
2
*
sizeof
(
DWORD
);
/* "pop up" previous EBP value */
if
(
!
sw_read_mem
(
csw
,
frame
->
AddrFrame
.
Offset
,
&
val32
,
sizeof
(
DWORD
)))
goto
done_err
;
frame
->
AddrFrame
.
Offset
=
val32
;
}
}
}
...
...
@@ -441,40 +440,40 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
sw_read_mem
(
csw
,
p
+
(
2
+
i
)
*
sizeof
(
WORD
),
&
val16
,
sizeof
(
val16
));
frame
->
Params
[
i
]
=
val16
;
}
#ifdef __i386__
if
(
context
)
{
#define SET(field, seg, reg) \
switch (frame->field.Mode) \
{ \
case AddrModeFlat: context->reg = frame->field.Offset; break; \
case AddrMode1616: context->seg = frame->field.Segment; context->reg = frame->field.Offset; break; \
default: assert(0); \
}
SET
(
AddrStack
,
SegSs
,
Esp
);
SET
(
AddrFrame
,
SegSs
,
Ebp
);
SET
(
AddrReturn
,
SegCs
,
Eip
);
#undef SET
}
#endif
}
else
{
unsigned
int
i
;
if
(
!
sw_read_mem
(
csw
,
frame
->
AddrFrame
.
Offset
+
sizeof
(
DWORD
),
&
val32
,
sizeof
(
DWORD
)))
{
WARN
(
"Cannot read new frame offset %p
\n
"
,
(
void
*
)(
DWORD_PTR
)(
frame
->
AddrFrame
.
Offset
+
(
int
)
sizeof
(
DWORD
)));
unsigned
int
i
;
#ifdef __i386__
CONTEXT
newctx
=
*
context
;
if
(
!
fetch_next_frame32
(
csw
,
&
newctx
,
frame
->
AddrPC
.
Offset
-
deltapc
))
goto
done_err
;
}
frame
->
AddrReturn
.
Offset
=
val32
;
frame
->
AddrReturn
.
Mode
=
AddrModeFlat
;
frame
->
AddrReturn
.
Offset
=
newctx
.
Eip
;
#endif
for
(
i
=
0
;
i
<
sizeof
(
frame
->
Params
)
/
sizeof
(
frame
->
Params
[
0
]);
i
++
)
{
sw_read_mem
(
csw
,
frame
->
AddrFrame
.
Offset
+
(
2
+
i
)
*
sizeof
(
DWORD
),
&
val32
,
sizeof
(
val32
));
frame
->
Params
[
i
]
=
val32
;
}
}
#ifdef __i386__
if
(
context
)
{
#define SET(field, seg, reg) \
switch (frame->field.Mode) \
{ \
case AddrModeFlat: context->reg = frame->field.Offset; break; \
case AddrMode1616: context->seg = frame->field.Segment; context->reg = frame->field.Offset; break; \
default: assert(0); \
}
SET
(
AddrStack
,
SegSs
,
Esp
);
SET
(
AddrFrame
,
SegSs
,
Ebp
);
SET
(
AddrReturn
,
SegCs
,
Eip
);
#undef SET
}
done_pep:
#endif
frame
->
Far
=
TRUE
;
frame
->
Virtual
=
TRUE
;
...
...
programs/winedbg/stack.c
View file @
16e88165
...
...
@@ -214,7 +214,7 @@ unsigned stack_fetch_frames(const CONTEXT* _ctx)
/* as native stackwalk can modify the context passed to it, simply copy
* it to avoid any damage
*/
CONTEXT
ctx
=
*
_ctx
,
prevctx
=
ctx
;
CONTEXT
ctx
=
*
_ctx
;
HeapFree
(
GetProcessHeap
(),
0
,
dbg_curr_thread
->
frames
);
dbg_curr_thread
->
frames
=
NULL
;
...
...
@@ -244,7 +244,7 @@ unsigned stack_fetch_frames(const CONTEXT* _ctx)
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
=
prev
ctx
;
dbg_curr_thread
->
frames
[
nf
].
context
=
ctx
;
/* 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...
*/
...
...
@@ -252,7 +252,6 @@ unsigned stack_fetch_frames(const CONTEXT* _ctx)
(
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
;
...
...
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