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

Reply via email to