Author: martin
Date: 2007-06-25 11:11:18 -0400 (Mon, 25 Jun 2007)
New Revision: 80688
Modified:
branches/martin/debugger-dublin/debugger/backend/SingleSteppingEngine.cs
branches/martin/debugger-dublin/debugger/backend/arch/Architecture_X86_64.cs
branches/martin/debugger-dublin/debugger/classes/Backtrace.cs
branches/martin/debugger-dublin/debugger/test/testsuite/TestCCtor.cs
Log:
Improve stack unwinding:
- we don't have the Main() method's stack pointer anymore since
we're not required to stop in Main()
- fix the LMF code on x86_64.
Modified:
branches/martin/debugger-dublin/debugger/backend/SingleSteppingEngine.cs
===================================================================
--- branches/martin/debugger-dublin/debugger/backend/SingleSteppingEngine.cs
2007-06-25 15:07:50 UTC (rev 80687)
+++ branches/martin/debugger-dublin/debugger/backend/SingleSteppingEngine.cs
2007-06-25 15:11:18 UTC (rev 80688)
@@ -401,11 +401,6 @@
ret_frame = null;
}
- if (!process.IsAttached && (ret_frame
!= null)) {
- main_method_stackptr =
ret_frame.StackPointer;
- main_method_retaddr =
ret_frame.TargetAddress;
- }
-
if (!process.IsManaged)
inferior.InitializeModules ();
}
@@ -445,14 +440,6 @@
//
TargetAddress frame = inferior.CurrentFrame;
- // After returning from `main', resume the target and
keep
- // running until it exits (or hit a breakpoint or
receives
- // a signal).
- if (!main_method_retaddr.IsNull && (frame ==
main_method_retaddr)) {
- do_continue ();
- return;
- }
-
//
// We're done with our stepping operation, but first we
need to
// compute the new StackFrame. While doing this,
`frame_changed'
@@ -1537,11 +1524,9 @@
if (current_frame == null)
throw new TargetException
(TargetError.NoStack);
- TargetAddress until = main_method_stackptr;
-
current_backtrace = new Backtrace
(current_frame);
- current_backtrace.GetBacktrace (this, mode,
until, max_frames);
+ current_backtrace.GetBacktrace (this, mode,
TargetAddress.Null, max_frames);
return current_backtrace;
});
@@ -1790,9 +1775,6 @@
TargetAddress end_stack_address = TargetAddress.Null;
- TargetAddress main_method_stackptr = TargetAddress.Null;
- TargetAddress main_method_retaddr = TargetAddress.Null;
-
#region Nested SSE classes
protected sealed class StackData : DebuggerMarshalByRefObject
{
Modified:
branches/martin/debugger-dublin/debugger/backend/arch/Architecture_X86_64.cs
===================================================================
---
branches/martin/debugger-dublin/debugger/backend/arch/Architecture_X86_64.cs
2007-06-25 15:07:50 UTC (rev 80687)
+++
branches/martin/debugger-dublin/debugger/backend/arch/Architecture_X86_64.cs
2007-06-25 15:11:18 UTC (rev 80688)
@@ -804,11 +804,21 @@
internal override StackFrame GetLMF (Thread thread)
{
TargetAddress lmf = thread.ReadAddress
(thread.LMFAddress);
+ return GetLMF (thread, lmf);
+ }
+ StackFrame GetLMF (Thread thread, TargetAddress lmf)
+ {
TargetBinaryReader reader = thread.ReadMemory (lmf,
88).GetReader ();
- reader.Position = 32;
+ reader.ReadTargetAddress (); // prev
+ TargetAddress lmf_addr = reader.ReadTargetAddress ();
+ reader.ReadTargetAddress (); // method
+ TargetAddress rip = reader.ReadTargetAddress ();
+ if (lmf_addr.IsNull)
+ return null;
+
TargetAddress rbx = reader.ReadTargetAddress ();
TargetAddress rbp = reader.ReadTargetAddress ();
TargetAddress rsp = reader.ReadTargetAddress ();
@@ -818,6 +828,7 @@
TargetAddress r15 = reader.ReadTargetAddress ();
Registers regs = new Registers (this);
+ regs [(int) X86_64_Register.RBX].SetValue (lmf + 24,
rip);
regs [(int) X86_64_Register.RBX].SetValue (lmf + 32,
rbx);
regs [(int) X86_64_Register.RBP].SetValue (lmf + 40,
rbp);
regs [(int) X86_64_Register.RSP].SetValue (lmf + 48,
rsp);
@@ -826,15 +837,10 @@
regs [(int) X86_64_Register.R14].SetValue (lmf + 72,
r14);
regs [(int) X86_64_Register.R15].SetValue (lmf + 80,
r15);
- TargetAddress new_rip = thread.ReadAddress (rbp + 8);
- regs [(int) X86_64_Register.RIP].SetValue (rbp + 8,
new_rip);
-
TargetAddress new_rbp = thread.ReadAddress (rbp);
regs [(int) X86_64_Register.RBP].SetValue (rbp,
new_rbp);
- rbp -= 8;
-
- return CreateFrame (thread, new_rip, rsp, new_rbp,
regs, true);
+ return CreateFrame (thread, rip, rsp, new_rbp, regs,
true);
}
}
}
Modified: branches/martin/debugger-dublin/debugger/classes/Backtrace.cs
===================================================================
--- branches/martin/debugger-dublin/debugger/classes/Backtrace.cs
2007-06-25 15:07:50 UTC (rev 80687)
+++ branches/martin/debugger-dublin/debugger/classes/Backtrace.cs
2007-06-25 15:11:18 UTC (rev 80688)
@@ -66,6 +66,14 @@
if ((max_frames != -1) && (frames.Count >
max_frames))
break;
}
+
+ // Ugly hack: in Mode == Mode.Default, we accept
wrappers but not as the
+ // last frame.
+ if ((mode == Mode.Default) && (frames.Count > 1)) {
+ StackFrame last = this [frames.Count - 1];
+ if (!IsFrameOkForMode (last, Mode.Managed))
+ frames.Remove (last);
+ }
}
private StackFrame TryLMF (ThreadServant target)
@@ -109,28 +117,37 @@
return true;
}
+ private bool IsFrameOkForMode (StackFrame frame, Mode mode)
+ {
+ if (mode == Mode.Native)
+ return true;
+ if (!frame.Language.IsManaged)
+ return false;
+ if (mode == Mode.Default)
+ return true;
+ if ((frame.SourceAddress == null) || (frame.Method ==
null))
+ return false;
+ return frame.Method.WrapperType == WrapperType.None;
+ }
+
internal bool TryUnwind (ThreadServant target, Mode mode,
TargetAddress until)
{
StackFrame new_frame = null;
- if ((mode == Mode.Managed) &&
!last_frame.Language.IsManaged) {
+ try {
+ new_frame = last_frame.UnwindStack (target);
+ } catch (TargetException) {
+ }
+
+ if ((new_frame == null) || !IsFrameOkForMode
(new_frame, mode)) {
if (TryCallback (target, last_frame, false))
return true;
+
new_frame = TryLMF (target);
- } else {
- try {
- new_frame = last_frame.UnwindStack
(target);
- } catch (TargetException) {
- }
- }
-
- if ((new_frame != null) && TryCallback (target,
new_frame, true))
+ if (new_frame == null)
+ return false;
+ } else if (TryCallback (target, new_frame, true))
return true;
- if ((new_frame == null) || (new_frame.SourceAddress ==
null)) {
- if (!last_frame.Language.IsManaged && (mode !=
Mode.Native))
- new_frame = TryLMF (target);
- }
-
if (new_frame == null)
return false;
Modified: branches/martin/debugger-dublin/debugger/test/testsuite/TestCCtor.cs
===================================================================
--- branches/martin/debugger-dublin/debugger/test/testsuite/TestCCtor.cs
2007-06-25 15:07:50 UTC (rev 80687)
+++ branches/martin/debugger-dublin/debugger/test/testsuite/TestCCtor.cs
2007-06-25 15:11:18 UTC (rev 80688)
@@ -78,9 +78,9 @@
AssertHitBreakpoint (thread, bpt_bar_cctor,
"Bar..cctor()", LineBarCCtor);
Backtrace bt_bar_cctor = thread.GetBacktrace
(Backtrace.Mode.Managed, -1);
- Assert.IsTrue (bt_bar_cctor.Count == 5);
+ Assert.IsTrue (bt_bar_cctor.Count == 3);
AssertFrame (bt_bar_cctor [0], 0, "Bar..cctor()",
LineBarCCtor);
- AssertFrame (bt_bar_cctor [4], 4, "X.Main()", LineMain
+ 1);
+ AssertFrame (bt_bar_cctor [2], 2, "X.Main()", LineMain
+ 1);
//
// Dublin Milestone III (completed on i386):
"recursive-callbacks"
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches