Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

2007-08-01 Martin Baulig <martin@ximian.com>

	Merged the `debugger-dublin' branch.


svn path=/trunk/debugger/; revision=83184
  • Loading branch information...
commit 45fd38558609854900201fd4f74cbb96e4561cba 2 parents 822f20d + d4b57a9
Martin Baulig authored
Showing with 4,535 additions and 2,676 deletions.
  1. +171 −0 ChangeLog
  2. +45 −53 backend/BreakpointHandle.cs
  3. +1 −0  backend/DebuggerServant.cs
  4. +1 −20 backend/ILanguageBackend.cs
  5. +54 −9 backend/Inferior.cs
  6. +49 −47 backend/MonoThreadManager.cs
  7. +3 −5 backend/ProcessServant.cs
  8. +540 −338 backend/SingleSteppingEngine.cs
  9. +7 −4 backend/ThreadServant.cs
  10. +22 −8 backend/arch/Architecture.cs
  11. +18 −12 backend/arch/Architecture_I386.cs
  12. +63 −54 backend/arch/Architecture_X86_64.cs
  13. +6 −87 backend/arch/Bfd.cs
  14. +2 −4 backend/arch/BfdDisassembler.cs
  15. +9 −4 backend/arch/CoreFile.cs
  16. +1 −1  backend/arch/DwarfFrameReader.cs
  17. +471 −369 backend/arch/DwarfReader.cs
  18. +166 −129 backend/server/i386-arch.c
  19. +26 −5 backend/server/library.c
  20. +24 −3 backend/server/server.h
  21. +4 −1 backend/server/x86-ptrace.c
  22. +170 −124 backend/server/x86_64-arch.c
  23. +2 −1  classes/AddressBreakpoint.cs
  24. +63 −80 classes/AssemblerMethod.cs
  25. +54 −11 classes/Backtrace.cs
  26. +6 −1 classes/Breakpoint.cs
  27. +3 −0  classes/DebuggerConfiguration.xsd
  28. +6 −0 classes/DebuggerOptions.cs
  29. +15 −15 classes/DebuggerSession.cs
  30. +4 −3 classes/ExpressionBreakpoint.cs
  31. +0 −5 classes/ISymbolTable.cs
  32. +3 −197 classes/LineNumberTable.cs
  33. +83 −0 classes/MainMethodBreakpoint.cs
  34. +1 −0  classes/Makefile.am
  35. +5 −11 classes/Method.cs
  36. +60 −0 classes/MethodSource.cs
  37. +7 −20 classes/Module.cs
  38. +1 −1  classes/Process.cs
  39. +14 −24 classes/SourceAddress.cs
  40. +3 −2 classes/SourceBreakpoint.cs
  41. +11 −98 classes/SourceInfo.cs
  42. +43 −91 classes/SourceLocation.cs
  43. +55 −14 classes/StackFrame.cs
  44. +1 −0  classes/TargetException.cs
  45. +5 −5 classes/Thread.cs
  46. +242 −0 doc/debugger-dublin.txt
  47. +66 −35 frontend/Command.cs
  48. +1 −1  frontend/Completer.cs
  49. +56 −50 frontend/Expression.cs
  50. +3 −3 frontend/Interpreter.cs
  51. +2 −2 frontend/ObjectFormatter.cs
  52. +8 −9 frontend/ScriptingContext.cs
  53. +8 −7 frontend/Style.cs
  54. +3 −2 languages/AbsoluteTargetLocation.cs
  55. +3 −4 languages/BitfieldTargetLocation.cs
  56. +3 −2 languages/ClientSuppliedTargetLocation.cs
  57. +37 −0 languages/DereferencedTargetLocation.cs
  58. +5 −7 languages/RelativeTargetLocation.cs
  59. +26 −4 languages/TargetFunctionType.cs
  60. +6 −13 languages/TargetLocation.cs
  61. +5 −15 languages/TargetObject.cs
  62. +1 −1  languages/TargetObjectObject.cs
  63. +1 −1  languages/TargetType.cs
  64. +3 −3 languages/mono/MonoArrayObject.cs
  65. +1 −1  languages/mono/MonoClassInfo.cs
  66. +1 −1  languages/mono/MonoClassObject.cs
  67. +27 −9 languages/mono/MonoClassType.cs
  68. +77 −9 languages/mono/MonoFunctionType.cs
  69. +23 −0 languages/mono/MonoFundamentalType.cs
  70. +222 −115 languages/mono/MonoLanguageBackend.cs
  71. +9 −21 languages/mono/MonoMember.cs
  72. +1 −1  languages/mono/MonoObjectObject.cs
  73. +4 −1 languages/mono/MonoObjectType.cs
  74. +1 −1  languages/mono/MonoPointerObject.cs
  75. +1 −1  languages/mono/MonoStringObject.cs
  76. +6 −4 languages/mono/MonoStringType.cs
  77. +676 −428 languages/mono/MonoSymbolFile.cs
  78. +1 −1  languages/mono/MonoVariable.cs
  79. +5 −6 languages/mono/MonoVariableLocation.cs
  80. +2 −2 languages/native/NativeArrayObject.cs
  81. +30 −6 languages/native/NativeFunctionType.cs
  82. +5 −0 languages/native/NativeLanguage.cs
  83. +4 −3 languages/native/NativePointerObject.cs
  84. +1 −1  languages/native/NativeStringObject.cs
  85. +1 −1  languages/native/NativeStructObject.cs
  86. +2 −2 languages/native/NativeStructType.cs
  87. +6 −3 test/src/Makefile.am
  88. +31 −0 test/src/TestAppDomain.cs
  89. +44 −0 test/src/TestCCtor.cs
  90. +151 −0 test/src/testnativetypes.c
  91. +2 −1  test/testsuite/Makefile.am
  92. +18 −4 test/testsuite/NUnit.cs
  93. +8 −8 test/testsuite/TestAbort.cs
  94. +130 −0 test/testsuite/TestAppDomain.cs
  95. +3 −4 test/testsuite/TestByRef.cs
  96. +134 −0 test/testsuite/TestCCtor.cs
  97. +12 −12 test/testsuite/TestDelegate.cs
  98. +4 −4 test/testsuite/TestExec.cs
  99. +2 −3 test/testsuite/TestInvocation.cs
  100. +5 −1 test/testsuite/TestManagedTypes.cs
  101. +4 −7 test/testsuite/TestMethodLookup.cs
  102. +104 −0 test/testsuite/testnativetypes.cs
View
171 ChangeLog
@@ -1,3 +1,7 @@
+2007-08-01 Martin Baulig <martin@ximian.com>
+
+ Merged the `debugger-dublin' branch.
+
2007-06-21 Martin Baulig <martin@ximian.com>
* backend/server/x86-linux-ptrace.c
@@ -16,6 +20,173 @@
`MinDynamicVersion' at 58. The new `debugger-dublin' branch uses
59, but it's backwards-compatible.
+2007-07-31 Martin Baulig <martin@ximian.com>
+
+ * test/src/TestAppDomain.cs: New test.
+ * test/testsuite/TestAppDomain.cs: New test.
+
+2007-07-31 Martin Baulig <martin@ximian.com>
+
+ * backend/arch/Architecture_X86_64.cs
+ (Architecture_X86_64.GetJumpOrCallTarget): New private method; fix
+ and improve GetCallTarget() and also add support for jump
+ instructions.
+
+ * backend/SingleSteppingEngine.cs
+ (SingleSteppingEngine.OperationNativeTrampoline): New operation;
+ keep stepping while we're in the trampoline like `finish -native'.
+
+2007-07-30 Martin Baulig <martin@ximian.com>
+
+ * languages/TargetLocation.cs
+ (TargetLocation.Address): Replaced by GetAddress().
+ (TargetLocation.GetAddress): New public function; replaces the
+ `Address' property.
+ (TargetLocation.GetDereferencedTargetLocation): Removed the
+ `Thread' argument; returns a `DereferencedTargetLocation'.
+
+ * languages/TargetObject.cs
+ (TargetObject.Address): Replaced by GetAddress().
+ (TargetObject.GetAddress): New public function; replaces the
+ `Address' property.
+ (TargetObject.IsNull): Removed.
+
+2007-07-30 Martin Baulig <martin@ximian.com>
+
+ * test/testsuite/testnativetypes.cs: New test.
+ * test/src/testnativetypes.c: New test.
+
+2007-07-30 Martin Baulig <martin@ximian.com>
+
+ * languages/DeferencedTargetLocation.cs: New file.
+
+2007-07-28 Martin Baulig <martin@ximian.com>
+
+ * backend/arch/DwarfReader.cs: Almost completely redesign the line
+ number table; it's no longer based on methods and now also works
+ with newer versions of gcc and g++.
+
+2007-07-28 Martin Baulig <martin@ximian.com>
+
+ * classes/SourceLocation.cs
+ (SourceLocation): Add a .ctor which takes a `SourceFile' in
+ addition to a `MethodSource'.
+
+2007-07-27 Martin Baulig <martin@ximian.com>
+
+ * classes/LineNumberTable.cs
+ (LineNumberTable): Made Lookup() and DumpLineNumbers() abstract;
+ move the actual implementation into MonoSymbolFile.cs and
+ DwarfReader.cs.
+
+2007-07-27 Martin Baulig <martin@ximian.com>
+
+ * classes/LineNumberTable.cs
+ (LineNumberTable.Name): Removed.
+ (LineNumberTable.Module): Removed.
+
+2007-07-27 Martin Baulig <martin@ximian.com>
+
+ * classes/SourceAddress.cs
+ (SourceAddress.Null): Removed.
+ (SourceAddress.LineNumberTable): Removed.
+ (SourceAddress.SourceBuffer): New public property.
+
+ * classes/LineNumberTable.cs
+ (LineNumberTable.IsDynamic): Removed.
+ (LineNumberTable.SourceBuffer): Removed.
+
+2007-07-27 Martin Baulig <martin@ximian.com>
+
+ * classes/MethodSource.cs
+ (MethodSource.IsDynamic): New public property.
+ (MethodSource.HasSourceCode): Renamed into `HasSourceFile'.
+ (MethodSource.HasSourceBuffer): New public property.
+ (MethodSource.SourceBuffer): New public property.
+
+ * classes/AssemblerMethod.cs
+ (AssemblerMethod): Derive from `MethodSource', not
+ `LineNumberTable'.
+
+ * classes/Method.cs
+ (Method.HasSourceFile): Removed.
+ (Method.SourceFile): Removed.
+
+ * languages/mono/MonoSymbolFile.cs
+ (WrapperMethod): Also create a MethodSource for wrappers.
+
+2007-07-26 Martin Baulig <martin@ximian.com>
+
+ * classes/SourceAddress.cs
+ (SourceAddress.Location): Removed.
+ (SourceAddress.SourceFile): New public property.
+
+ * classes/LineNumberTable.cs
+ (LineNumberTable): Removed `MethodSource', `Addresses',
+ `StartRow', `EndRow' and `GetNamespaces()'.
+
+ * classes/Method.cs
+ (Method.HasSource): New public property.
+ (Method.MethodSource): New public property.
+ (Method.GetNamespaces): New public method.
+ (Method): Removed `StartRow' and `EndRow'; get them from the
+ `MethodSource' instead.
+
+2007-07-20 Martin Baulig <martin@ximian.com>
+
+ * languages/mono/MonoFundamentalType.cs: New file.
+ (MonoFundamentalType): New type.
+
+ * languages/mono/MonoStringType.cs
+ (MonoStringType): Derive from `MonoFundamentalType'.
+
+ * languages/mono/MonoObjectType.cs
+ (MonoObjectType): Create the MonoClassType in the .ctor.
+
+ * languages/mono/MonoSymbolFile.cs
+ (MonoSymbolFile.LookupMonoClass): New public method; calls
+ LookupMonoType() and then returns a `MonoClassType', this also
+ works for fundamental types.
+
+ * languages/mono/MonoLanguageBackend.cs
+ (MonoBuiltinTypeInfo): Use the new `MonoFundamentalType'.
+
+2007-06-28 Martin Baulig <martin@ximian.com>
+
+ * backend/MonoThreadManager.cs
+ (MonoDebuggerInfo): Reflect latest runtime changes; add the new
+ `DebuggerVersion' field.
+
+2007-06-04 Martin Baulig <martin@ximian.com>
+
+ * classes/Thread.cs
+ (Thread.CallMethod (long,string)): Added second `long' argument
+ so we can now pass a long value in addition to the string to the
+ target.
+
+ * backends/Inferior.cs
+ (Inferior.CallMethod (long,string)): Added second `long' argument
+ so we can now pass a long value in addition to the string to the
+ target.
+
+ * backends/server/server.h
+ (mono_debugger_server_call_method_1): Added `guint64 data_arg'
+ argument.
+
+2007-06-04 Martin Baulig <martin@ximian.com>
+
+ Replace `SourceMethod' with a new abstract `MethodSource'.
+
+ * classes/MethodSource.cs: New file.
+ (MethodSource): New public abstract class.
+
+ * classes/SourceInfo.cs
+ (SourceMethod): Removed; we now use the new `MethodSource'.
+
+ * classes/Module.cs
+ (Module.LookupMethod): Removed; use FindMethod() instead.
+ (Module.RegisterLoadHandler): Removed.
+
2007-05-29 Wade Berrier <wberrier@novell.com>
* classes/Makefile.am: fix make dist (remove MethodSource.cs)
View
98 backend/BreakpointHandle.cs
@@ -12,6 +12,8 @@ protected BreakpointHandle (Breakpoint breakpoint)
this.Breakpoint = breakpoint;
}
+ internal abstract bool Insert (SingleSteppingEngine sse);
+
public abstract void Insert (Thread target);
public abstract void Remove (Thread target);
@@ -27,6 +29,11 @@ internal SimpleBreakpointHandle (Breakpoint breakpoint, int index)
this.index = index;
}
+ internal override bool Insert (SingleSteppingEngine sse)
+ {
+ throw new InternalError ();
+ }
+
public override void Insert (Thread target)
{
throw new InternalError ();
@@ -51,6 +58,12 @@ public AddressBreakpointHandle (Breakpoint breakpoint, TargetAddress address)
this.Address = address;
}
+ internal override bool Insert (SingleSteppingEngine sse)
+ {
+ index = sse.Inferior.InsertBreakpoint (Breakpoint, Address);
+ return false;
+ }
+
public override void Insert (Thread target)
{
index = target.InsertBreakpoint (Breakpoint, Address);
@@ -66,87 +79,54 @@ public override void Remove (Thread target)
internal class FunctionBreakpointHandle : BreakpointHandle
{
- ILoadHandler load_handler;
TargetFunctionType function;
- SourceMethod source;
+ bool has_load_handler;
int line = -1;
int index = -1;
int domain;
- public FunctionBreakpointHandle (Breakpoint bpt, int domain, SourceMethod source)
+ public FunctionBreakpointHandle (Breakpoint bpt, int domain,
+ TargetFunctionType function, int line)
: base (bpt)
{
+ this.function = function;
this.domain = domain;
- this.source = source;
- }
-
- public FunctionBreakpointHandle (Breakpoint bpt, int domain,
- SourceMethod source, int line)
- : this (bpt, domain, source)
- {
this.line = line;
}
- public FunctionBreakpointHandle (Breakpoint bpt, int domain,
- TargetFunctionType function)
- : this (bpt, domain, function.Source, -1)
- {
- this.function = function;
+ internal TargetFunctionType Function {
+ get { return function; }
}
- public override void Insert (Thread target)
+ internal override bool Insert (SingleSteppingEngine sse)
{
- if ((load_handler != null) || (index > 0))
- return;
-
- if ((function != null) && function.IsLoaded) {
- index = target.InsertBreakpoint (Breakpoint, function);
- return;
- }
+ if (has_load_handler || (index > 0))
+ return false;
- load_handler = source.SourceFile.Module.SymbolFile.RegisterLoadHandler (
- target, source, method_loaded, null);
+ throw new InternalError ();
}
- public override void Remove (Thread target)
+ public override void Insert (Thread target)
{
- if (index > 0)
- target.RemoveBreakpoint (index);
-
- if (load_handler != null)
- load_handler.Remove ();
+ if (has_load_handler || (index > 0))
+ return;
- load_handler = null;
- index = -1;
+ has_load_handler = function.InsertBreakpoint (target, MethodLoaded);
}
- protected TargetAddress GetAddress (int domain)
+ internal void MethodLoaded (TargetMemoryAccess target, Method method)
{
- Method method = source.GetMethod (domain);
- if (method == null)
- return TargetAddress.Null;
-
+ TargetAddress address;
if (line != -1) {
if (method.HasLineNumbers)
- return method.LineNumberTable.Lookup (line);
+ address = method.LineNumberTable.Lookup (line);
else
- return TargetAddress.Null;
+ address = TargetAddress.Null;
} else if (method.HasMethodBounds)
- return method.MethodStartAddress;
+ address = method.MethodStartAddress;
else
- return method.StartAddress;
- }
+ address = method.StartAddress;
- // <summary>
- // The method has just been loaded, lookup the breakpoint
- // address and actually insert it.
- // </summary>
- public void method_loaded (TargetMemoryAccess target,
- SourceMethod source, object data)
- {
- load_handler = null;
-
- TargetAddress address = GetAddress (domain);
if (address.IsNull)
return;
@@ -158,5 +138,17 @@ protected TargetAddress GetAddress (int domain)
index = -1;
}
}
+
+ public override void Remove (Thread target)
+ {
+ if (index > 0)
+ target.RemoveBreakpoint (index);
+
+ if (has_load_handler)
+ function.RemoveBreakpoint (target);
+
+ has_load_handler = false;
+ index = -1;
+ }
}
}
View
1  backend/DebuggerServant.cs
@@ -60,6 +60,7 @@ internal void OnProcessCreatedEvent (ProcessServant process)
internal void OnTargetExitedEvent ()
{
+ MonoLanguageBackend.PrintStatistics ();
client.OnTargetExitedEvent ();
}
View
21 backend/ILanguageBackend.cs
@@ -34,30 +34,11 @@ internal interface ILanguageBackend : IDisposable
get;
}
- TargetAddress RuntimeInvokeFunc {
- get;
- }
-
- TargetAddress CompileMethodFunc {
- get;
- }
-
- TargetAddress GetVirtualMethodFunc {
- get;
- }
-
- TargetAddress GetBoxedObjectFunc {
- get;
- }
-
TargetAddress GetTrampolineAddress (TargetMemoryAccess memory,
TargetAddress address,
out bool is_start);
- SourceMethod GetTrampoline (TargetMemoryAccess memory,
+ MethodSource GetTrampoline (TargetMemoryAccess memory,
TargetAddress address);
-
- void Notification (Inferior inferior, NotificationType type,
- TargetAddress data, long arg);
}
}
View
63 backend/Inferior.cs
@@ -103,13 +103,16 @@ internal class Inferior : TargetMemoryAccess, ITargetNotification, IDisposable
static extern TargetError mono_debugger_server_call_method (IntPtr handle, long method_address, long method_argument1, long method_argument2, long callback_argument);
[DllImport("monodebuggerserver")]
- static extern TargetError mono_debugger_server_call_method_1 (IntPtr handle, long method_address, long method_argument, string string_argument, long callback_argument);
+ static extern TargetError mono_debugger_server_call_method_1 (IntPtr handle, long method_address, long method_argument, long data_argument, string string_argument, long callback_argument);
[DllImport("monodebuggerserver")]
static extern TargetError mono_debugger_server_call_method_2 (IntPtr handle, long method_address, long method_argument, long callback_argument);
[DllImport("monodebuggerserver")]
- static extern TargetError mono_debugger_server_abort_invoke (IntPtr handle);
+ static extern TargetError mono_debugger_server_mark_rti_frame (IntPtr handle);
+
+ [DllImport("monodebuggerserver")]
+ static extern TargetError mono_debugger_server_abort_invoke (IntPtr handle, long stack_pointer);
[DllImport("monodebuggerserver")]
static extern TargetError mono_debugger_server_call_method_invoke (IntPtr handle, long invoke_method, long method_address, int num_params, int blob_size, IntPtr param_data, IntPtr offset_data, IntPtr blob_data, long callback_argument, bool debug);
@@ -172,6 +175,9 @@ internal class Inferior : TargetMemoryAccess, ITargetNotification, IDisposable
static extern TargetError mono_debugger_server_pop_registers (IntPtr handle);
[DllImport("monodebuggerserver")]
+ static extern TargetError mono_debugger_server_get_callback_frame (IntPtr handle, long stack_pointer, bool exact_match, IntPtr registers);
+
+ [DllImport("monodebuggerserver")]
static extern void mono_debugger_server_set_notification (IntPtr handle, long address);
internal enum ChildEventType {
@@ -319,16 +325,16 @@ protected static void check_error (TargetError error)
}
}
- public void CallMethod (TargetAddress method, long arg1, string arg2,
- long callback_arg)
+ public void CallMethod (TargetAddress method, long arg1, long arg2,
+ string arg3, long callback_arg)
{
check_disposed ();
TargetState old_state = change_target_state (TargetState.Running);
try {
check_error (mono_debugger_server_call_method_1 (
- server_handle, method.Address, arg1,
- arg2, callback_arg));
+ server_handle, method.Address, arg1, arg2,
+ arg3, callback_arg));
} catch {
change_target_state (old_state);
throw;
@@ -374,7 +380,7 @@ public void CallMethod (TargetAddress method, long arg1, long callback_arg)
continue;
if (obj.Location.HasAddress) {
blob_offsets [i] = -1;
- addresses [i] = obj.Location.Address.Address;
+ addresses [i] = obj.Location.GetAddress (this).Address;
continue;
}
blobs [i] = obj.Location.ReadBuffer (target, obj.Type.Size);
@@ -417,9 +423,19 @@ public void CallMethod (TargetAddress method, long arg1, long callback_arg)
}
}
- public void AbortInvoke ()
+ public void MarkRuntimeInvokeFrame ()
+ {
+ check_error (mono_debugger_server_mark_rti_frame (server_handle));
+ }
+
+ public bool AbortInvoke (TargetAddress stack_pointer)
{
- check_error (mono_debugger_server_abort_invoke (server_handle));
+ TargetError result = mono_debugger_server_abort_invoke (
+ server_handle, stack_pointer.Address);
+ if (result == TargetError.NoCallbackFrame)
+ return false;
+ check_error (result);
+ return true;
}
public int InsertBreakpoint (TargetAddress address)
@@ -1157,6 +1173,13 @@ public void SetRegisters (Registers registers)
IntPtr buffer = IntPtr.Zero;
try {
int count = arch.CountRegisters;
+
+ Registers old_regs = GetRegisters ();
+ for (int i = 0; i < count; i++) {
+ if (!registers [i].Valid)
+ registers [i].SetValue (old_regs [i].Value);
+ }
+
int buffer_size = count * 8;
buffer = Marshal.AllocHGlobal (buffer_size);
Marshal.Copy (registers.Values, 0, buffer, count);
@@ -1228,6 +1251,28 @@ public void PopRegisters ()
check_error (mono_debugger_server_pop_registers (server_handle));
}
+ internal Registers GetCallbackFrame (TargetAddress stack_pointer, bool exact_match)
+ {
+ IntPtr buffer = IntPtr.Zero;
+ try {
+ int count = arch.CountRegisters;
+ int buffer_size = count * 8;
+ buffer = Marshal.AllocHGlobal (buffer_size);
+ TargetError result = mono_debugger_server_get_callback_frame (
+ server_handle, stack_pointer.Address, exact_match, buffer);
+ if (result == TargetError.NoCallbackFrame)
+ return null;
+ check_error (result);
+ long[] retval = new long [count];
+ Marshal.Copy (buffer, retval, 0, count);
+
+ return new Registers (arch, retval);
+ } finally {
+ if (buffer != IntPtr.Zero)
+ Marshal.FreeHGlobal (buffer);
+ }
+ }
+
internal void SetNotificationAddress (TargetAddress notification)
{
mono_debugger_server_set_notification (server_handle, notification.Address);
View
96 backend/MonoThreadManager.cs
@@ -10,6 +10,11 @@
using System.Collections.Specialized;
using System.Runtime.InteropServices;
+using Mono.Debugger;
+using Mono.Debugger.Languages;
+using Mono.Debugger.Languages.Mono;
+
+
namespace Mono.Debugger.Backends
{
@@ -24,11 +29,9 @@ internal class MonoThreadManager
MonoDebuggerInfo debugger_info;
TargetAddress notification_address = TargetAddress.Null;
Inferior inferior;
- bool stop_in_main;
public static MonoThreadManager Initialize (ThreadManager thread_manager,
- Inferior inferior, bool attach,
- bool stop_in_main)
+ Inferior inferior, bool attach)
{
TargetAddress info = inferior.GetSectionAddress (".mdb_debug_info");
if (!info.IsNull)
@@ -38,16 +41,14 @@ internal class MonoThreadManager
if (info.IsNull)
return null;
- return new MonoThreadManager (
- thread_manager, inferior, info, attach, stop_in_main);
+ return new MonoThreadManager (thread_manager, inferior, info, attach);
}
protected MonoThreadManager (ThreadManager thread_manager, Inferior inferior,
- TargetAddress info, bool attach, bool stop_in_main)
+ TargetAddress info, bool attach)
{
this.inferior = inferior;
this.thread_manager = thread_manager;
- this.stop_in_main = stop_in_main;
TargetBinaryReader header = inferior.ReadMemory (info, 16).GetReader ();
long magic = header.ReadInt64 ();
@@ -84,6 +85,8 @@ protected void initialize_notifications (Inferior inferior)
notification_address = inferior.ReadAddress (debugger_info.NotificationAddress);
inferior.SetNotificationAddress (notification_address);
+ inferior.WriteInteger (debugger_info.DebuggerVersion, 2);
+
if (notification_bpt > 0) {
inferior.BreakpointManager.RemoveBreakpoint (inferior, notification_bpt);
notification_bpt = -1;
@@ -116,7 +119,7 @@ public override bool CheckBreakpointHit (Thread target, TargetAddress address)
TargetAddress main_function;
TargetAddress main_thread;
- ILanguageBackend csharp_language;
+ MonoLanguageBackend csharp_language;
internal MonoDebuggerInfo MonoDebuggerInfo {
get { return debugger_info; }
@@ -177,8 +180,9 @@ internal void ThreadCreated (SingleSteppingEngine sse)
break;
case NotificationType.InitializeThreadManager:
- csharp_language = inferior.Process.CreateDebuggerHandler (
+ csharp_language = inferior.Process.CreateMonoLanguage (
debugger_info);
+ csharp_language.Initialize (inferior);
break;
case NotificationType.ReachedMain: {
@@ -186,11 +190,10 @@ internal void ThreadCreated (SingleSteppingEngine sse)
inferior.AddressDomain, cevent.Data1);
inferior.InitializeModules ();
+ engine.ProcessServant.MonoLanguage.ReachedMain (inferior, data);
- if (stop_in_main)
- engine.ReachedManagedMain (data);
- resume_target = !stop_in_main;
- return true;
+ resume_target = false;
+ return false;
}
case NotificationType.WrapperMain:
@@ -254,7 +257,7 @@ internal void ThreadCreated (SingleSteppingEngine sse)
internal class MonoDebuggerInfo
{
// These constants must match up with those in mono/mono/metadata/mono-debug.h
- public const int MinDynamicVersion = 58;
+ public const int MinDynamicVersion = 59;
public const int MaxDynamicVersion = 59;
public const long DynamicMagic = 0x7aff65af4253d427;
@@ -265,20 +268,22 @@ internal class MonoDebuggerInfo
public readonly TargetAddress CompileMethod;
public readonly TargetAddress GetVirtualMethod;
public readonly TargetAddress GetBoxedObjectMethod;
- public readonly TargetAddress InsertBreakpoint;
- public readonly TargetAddress RemoveBreakpoint;
public readonly TargetAddress RuntimeInvoke;
public readonly TargetAddress CreateString;
public readonly TargetAddress ClassGetStaticFieldData;
public readonly TargetAddress LookupClass;
- public readonly TargetAddress LookupType;
public readonly TargetAddress LookupAssembly;
public readonly TargetAddress RunFinally;
public readonly TargetAddress GetCurrentThread;
+ public readonly TargetAddress InsertBreakpoint;
+ public readonly TargetAddress RemoveBreakpoint;
+ public readonly TargetAddress RuntimeClassInit;
public readonly TargetAddress Attach;
public readonly TargetAddress Detach;
public readonly TargetAddress Initialize;
public readonly TargetAddress GetLMFAddress;
+ public readonly TargetAddress DebuggerVersion;
+ public readonly TargetAddress DataTable;
public readonly MonoMetadataInfo MonoMetadataInfo;
@@ -287,44 +292,41 @@ internal MonoDebuggerInfo (TargetMemoryAccess memory, TargetReader reader)
/* skip past magic, version, and total_size */
reader.Offset = 16;
- SymbolTableSize = reader.ReadInteger ();
+ int address_size = memory.TargetInfo.TargetAddressSize;
+
+ SymbolTableSize = reader.ReadInteger ();
reader.Offset = 24;
- NotificationAddress = reader.ReadAddress ();
- MonoTrampolineCode = reader.ReadAddress ();
- SymbolTable = reader.ReadAddress ();
+ NotificationAddress = reader.ReadAddress ();
+ MonoTrampolineCode = reader.ReadAddress ();
+ SymbolTable = reader.ReadAddress ();
TargetAddress metadata_info = reader.ReadAddress ();
- CompileMethod = reader.ReadAddress ();
- GetVirtualMethod = reader.ReadAddress ();
- GetBoxedObjectMethod = reader.ReadAddress ();
- InsertBreakpoint = reader.ReadAddress ();
- RemoveBreakpoint = reader.ReadAddress ();
- RuntimeInvoke = reader.ReadAddress ();
- CreateString = reader.ReadAddress ();
- ClassGetStaticFieldData = reader.ReadAddress ();
- LookupClass = reader.ReadAddress ();
- LookupType = reader.ReadAddress ();
- LookupAssembly = reader.ReadAddress ();
- RunFinally = reader.ReadAddress ();
- GetCurrentThread = reader.ReadAddress ();
- Attach = reader.ReadAddress ();
- Detach = reader.ReadAddress ();
- Initialize = reader.ReadAddress ();
- GetLMFAddress = reader.ReadAddress ();
+ CompileMethod = reader.ReadAddress ();
+ GetVirtualMethod = reader.ReadAddress ();
+ GetBoxedObjectMethod = reader.ReadAddress ();
+ RuntimeInvoke = reader.ReadAddress ();
+ ClassGetStaticFieldData = reader.ReadAddress ();
+ RunFinally = reader.ReadAddress ();
+ GetCurrentThread = reader.ReadAddress ();
+ Attach = reader.ReadAddress ();
+ Detach = reader.ReadAddress ();
+ Initialize = reader.ReadAddress ();
+ GetLMFAddress = reader.ReadAddress ();
+
+ DebuggerVersion = reader.ReadAddress ();
+ DataTable = reader.ReadAddress ();
+
+ CreateString = reader.ReadAddress ();
+ LookupClass = reader.ReadAddress ();
+ LookupAssembly = reader.ReadAddress ();
+ InsertBreakpoint = reader.ReadAddress ();
+ RemoveBreakpoint = reader.ReadAddress ();
+ RuntimeClassInit = reader.ReadAddress ();
MonoMetadataInfo = new MonoMetadataInfo (memory, metadata_info);
Report.Debug (DebugFlags.JitSymtab, this);
}
-
- public override string ToString ()
- {
- return String.Format (
- "MonoDebuggerInfo ({0:x}:{1:x}:{2:x}:{3:x}:{4:x}:{5:x}:{6:x})",
- MonoTrampolineCode, SymbolTable, SymbolTableSize,
- CompileMethod, InsertBreakpoint, RemoveBreakpoint,
- RuntimeInvoke);
- }
}
internal class MonoMetadataInfo
View
8 backend/ProcessServant.cs
@@ -305,8 +305,7 @@ internal void WaitForApplication ()
initialized = true;
if (!is_forked || is_exec) {
mono_manager = MonoThreadManager.Initialize (
- manager, inferior, (start.PID != 0) && !is_exec,
- !is_exec);
+ manager, inferior, (start.PID != 0) && !is_exec);
if (!is_forked && !is_exec && !is_attached &&
!start.IsNative && (mono_manager == null))
throw new TargetException (TargetError.CannotStartTarget,
@@ -356,8 +355,7 @@ internal void OnTargetDetached ()
Dispose ();
}
- // XXX This desperately needs to be renamed.
- internal ILanguageBackend CreateDebuggerHandler (MonoDebuggerInfo info)
+ internal MonoLanguageBackend CreateMonoLanguage (MonoDebuggerInfo info)
{
mono_language = new MonoLanguageBackend (this, info);
languages.Add (mono_language);
@@ -416,7 +414,7 @@ public SourceLocation FindLocation (string file, int line)
public SourceLocation FindMethod (string name)
{
foreach (Module module in Modules) {
- SourceMethod method = module.FindMethod (name);
+ MethodSource method = module.FindMethod (name);
if (method != null)
return new SourceLocation (method);
View
878 backend/SingleSteppingEngine.cs
@@ -87,7 +87,6 @@ internal class SingleSteppingEngine : ThreadServant
DebuggerWaitHandle.CurrentThread, this);
exception_handlers = new Hashtable ();
- callback_stack = new Stack ();
}
public SingleSteppingEngine (ThreadManager manager, ProcessServant process,
@@ -371,8 +370,6 @@ protected void ProcessChildEvent (Inferior.ChildEvent cevent)
break;
case Inferior.ChildEventType.CHILD_CALLBACK_COMPLETED:
- callback_stack.Pop ();
-
frame_changed (inferior.CurrentFrame, null);
result = new TargetEventArgs (
TargetEventType.TargetStopped, 0,
@@ -396,19 +393,6 @@ protected void ProcessChildEvent (Inferior.ChildEvent cevent, TargetEventArgs re
(cevent.Type != Inferior.ChildEventType.CHILD_SIGNALED)) {
reached_main = true;
- StackFrame ret_frame;
- try {
- ret_frame = inferior.Architecture.UnwindStack (
- current_frame, inferior, null, 0);
- } catch {
- 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 ();
}
@@ -448,14 +432,6 @@ protected void ProcessChildEvent (Inferior.ChildEvent cevent, TargetEventArgs re
//
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'
@@ -488,7 +464,7 @@ protected void ProcessChildEvent (Inferior.ChildEvent cevent, TargetEventArgs re
pending_bpt = current_operation.PendingBreakpoint;
if (pending_bpt >= 0) {
Breakpoint bpt = process.BreakpointManager.LookupBreakpoint (pending_bpt);
- if ((bpt != null) && bpt.Breaks (thread.ID)) {
+ if ((bpt != null) && bpt.Breaks (thread.ID) && !bpt.HideFromUser) {
result = new TargetEventArgs (
TargetEventType.TargetHitBreakpoint, bpt.Index,
current_frame);
@@ -520,12 +496,6 @@ void OperationCompleted (TargetEventArgs result)
}
}
- internal void ReachedManagedMain (TargetAddress method)
- {
- TargetAddress compile = process.MonoLanguage.CompileMethodFunc;
- PushOperation (new OperationCompileMethod (this, compile, method, null));
- }
-
internal void OnManagedThreadCreated (long tid, TargetAddress end_stack_address)
{
this.tid = tid;
@@ -547,6 +517,7 @@ internal void OnThreadExited (Inferior.ChildEvent cevent)
result = new TargetEventArgs (TargetEventType.TargetSignaled, arg);
else
result = new TargetEventArgs (TargetEventType.TargetExited, arg);
+ temp_breakpoint_id = 0;
OperationCompleted (result);
process.OnThreadExitedEvent (this);
@@ -660,7 +631,10 @@ void ExecuteOperation (Operation operation)
public override Method Lookup (TargetAddress address)
{
process.UpdateSymbolTable (inferior);
- return process.SymbolTableManager.Lookup (address);
+ Method method = process.SymbolTableManager.Lookup (address);
+ Report.Debug (DebugFlags.JitSymtab, "{0} lookup {1}: {2}",
+ this, address, method);
+ return method;
}
public override Symbol SimpleLookup (TargetAddress address, bool exact_match)
@@ -733,6 +707,10 @@ public override Symbol SimpleLookup (TargetAddress address, bool exact_match)
get { return inferior.CurrentFrame; }
}
+ protected MonoDebuggerInfo MonoDebuggerInfo {
+ get { return process.MonoManager.MonoDebuggerInfo; }
+ }
+
public override TargetState State {
get {
if (inferior == null)
@@ -1009,9 +987,14 @@ Operation frame_changed (TargetAddress address, Operation operation)
return new_operation;
}
- update_current_frame (new StackFrame (
- thread, iframe.Address, iframe.StackPointer,
- iframe.FrameAddress, registers, current_method, source));
+ if (source != null)
+ update_current_frame (new StackFrame (
+ thread, iframe.Address, iframe.StackPointer,
+ iframe.FrameAddress, registers, current_method, source));
+ else
+ update_current_frame (new StackFrame (
+ thread, iframe.Address, iframe.StackPointer,
+ iframe.FrameAddress, registers, current_method));
} else {
if (!same_method && (current_method != null)) {
Operation new_operation = check_method_operation (
@@ -1033,7 +1016,8 @@ Operation frame_changed (TargetAddress address, Operation operation)
}
update_current_frame (new StackFrame (
thread, iframe.Address, iframe.StackPointer,
- iframe.FrameAddress, registers, name));
+ iframe.FrameAddress, registers, thread.NativeLanguage,
+ name));
}
}
@@ -1179,25 +1163,22 @@ void do_step_native ()
inferior.Step ();
}
- void do_trampoline (ILanguageBackend language, TargetAddress trampoline,
- TrampolineHandler handler, bool is_start)
+ void do_trampoline (ILanguageBackend language, TargetAddress call,
+ TargetAddress trampoline, TrampolineHandler handler,
+ bool is_start)
{
- TargetAddress compile = language.CompileMethodFunc;
-
Report.Debug (DebugFlags.SSE,
- "{0} found trampoline {1}/{3} (compile is {2}) while running {4}",
- this, trampoline, compile, is_start, current_operation);
+ "{0} found trampoline {1}/{2} while running {3}",
+ this, trampoline, is_start, current_operation);
- if (is_start) {
- Console.WriteLine ("DO TRAMPOLINE: {0}", trampoline);
- // PushOperation (new OperationFinish (this, true, null));
- do_continue (trampoline);
- return;
- }
+ if (!language.Language.IsManaged) {
+ if (is_start) {
+ PushOperation (new OperationNativeTrampoline (
+ this, trampoline, handler));
+ return;
+ }
- if (compile.IsNull) {
- Method method = null;
- method = Lookup (trampoline);
+ Method method = Lookup (trampoline);
if (!MethodHasSource (method)) {
do_next_native ();
return;
@@ -1207,15 +1188,37 @@ void do_step_native ()
return;
}
- PushOperation (new OperationCompileMethod (this, compile, trampoline, handler));
+ if (is_start) {
+ do_continue (trampoline);
+ return;
+ }
+
+ Report.Debug (DebugFlags.SSE,
+ "{0} doing trampoline: {1} {2} {3}", this, current_operation,
+ call, trampoline);
+
+ PushOperation (new OperationTrampoline (this, trampoline, handler));
return;
}
+ void trampoline_callback (TargetAddress address)
+ {
+ Report.Debug (DebugFlags.SSE,
+ "{0} trampoline callback: {1}", this, address);
+ }
+
protected bool MethodHasSource (Method method)
{
if ((method == null) || !method.HasLineNumbers || !method.HasMethodBounds)
return false;
+ if (method.WrapperType == WrapperType.ManagedToNative) {
+ DebuggerConfiguration config = process.Session.Config;
+ ModuleGroup native_group = config.GetModuleGroup ("native");
+ if (!native_group.StepInto)
+ return false;
+ }
+
if (current_method != null) {
if ((method.Module != current_method.Module) && !method.Module.StepInto)
return false;
@@ -1230,9 +1233,7 @@ protected bool MethodHasSource (Method method)
SourceAddress addr = lnt.Lookup (method.MethodStartAddress);
if (addr == null) {
- Console.WriteLine ("OOOOPS - No source for method: " +
- "{0} {1} - {2} {3}",
- method, lnt, lnt.StartRow, lnt.EndRow);
+ Report.Error ("OOOOPS - No source for method: {0}", method);
lnt.DumpLineNumbers ();
return false;
}
@@ -1276,13 +1277,13 @@ StepFrame CreateStepFrame (StepMode mode)
return new StepFrame (language, mode);
}
- StackData save_stack ()
+ StackData save_stack (long id)
{
//
// Save current state.
//
StackData stack_data = new StackData (
- current_method, inferior.CurrentFrame, current_frame,
+ id, current_method, inferior.CurrentFrame, current_frame,
current_backtrace, registers);
current_method = null;
@@ -1308,22 +1309,6 @@ void restore_stack (StackData stack)
current_frame = stack.Frame;
current_backtrace = stack.Backtrace;
registers = stack.Registers;
- Report.Debug (DebugFlags.SSE,
- "{0} restored stack: {1}", this, current_frame);
- }
-
- void discard_stack (StackData stack)
- {
- }
-
- void push_runtime_invoke (StackFrame rti_frame)
- {
- callback_stack.Push (rti_frame);
- }
-
- void pop_runtime_invoke ()
- {
- callback_stack.Pop ();
}
// <summary>
@@ -1475,18 +1460,16 @@ public override void Background (TargetAddress until, CommandResult result)
is_virtual, debug, result));
}
- public override CommandResult CallMethod (TargetAddress method, long method_argument,
+ public override CommandResult CallMethod (TargetAddress method, long arg1, long arg2,
string string_argument)
{
return StartOperation (new OperationCallMethod (
- this, method, method_argument, string_argument));
+ this, method, arg1, arg2, string_argument));
}
- public override CommandResult CallMethod (TargetAddress method, TargetAddress arg1,
- TargetAddress arg2)
+ public override CommandResult CallMethod (TargetAddress method, long arg1, long arg2)
{
- return StartOperation (new OperationCallMethod (
- this, method, arg1.Address, arg2.Address));
+ return StartOperation (new OperationCallMethod (this, method, arg1, arg2));
}
public override CommandResult CallMethod (TargetAddress method, TargetAddress argument)
@@ -1495,39 +1478,22 @@ public override CommandResult CallMethod (TargetAddress method, TargetAddress ar
this, method, argument.Address));
}
- protected void return_finished (StackFrame parent_frame)
- {
- StackFrame rti_frame = null;
- if (callback_stack.Count > 0)
- rti_frame = (StackFrame) callback_stack.Peek ();
-
- /*
- * Check whether we're crossing a runtime-invoke boundary and
- * abort the invocation if neccessary.
- */
- if ((rti_frame != null) &&
- (parent_frame.StackPointer >= rti_frame.StackPointer)) {
- inferior.AbortInvoke ();
- callback_stack.Pop ();
- return;
- }
-
- inferior.SetRegisters (parent_frame.Registers);
- }
-
public override CommandResult Return (bool run_finally)
{
return (CommandResult) SendCommand (delegate {
GetBacktrace (Backtrace.Mode.Native, -1);
if (current_backtrace == null)
throw new TargetException (TargetError.NoStack);
+ if (current_backtrace.Count < 2)
+ throw new TargetException (TargetError.NoStack);
StackFrame parent_frame = current_backtrace.Frames [1];
if (parent_frame == null)
return null;
if (!process.IsManagedApplication || !run_finally) {
- return_finished (parent_frame);
+ inferior.AbortInvoke (parent_frame.StackPointer);
+ inferior.SetRegisters (parent_frame.Registers);
frame_changed (inferior.CurrentFrame, null);
TargetEventArgs args = new TargetEventArgs (
TargetEventType.TargetStopped, 0, current_frame);
@@ -1547,14 +1513,11 @@ public override CommandResult AbortInvocation ()
if (current_backtrace == null)
throw new TargetException (TargetError.NoStack);
- if ((callback_stack.Count == 0) || !process.IsManagedApplication)
+ if (!process.IsManagedApplication)
throw new InvalidOperationException ();
- StackFrame rti_frame = (StackFrame) callback_stack.Peek ();
- MonoLanguageBackend language = process.MonoLanguage;
-
return StartOperation (new OperationAbortInvocation (
- this, language, current_backtrace, rti_frame));
+ this, current_backtrace));
});
}
@@ -1572,18 +1535,9 @@ public override Backtrace GetBacktrace (Backtrace.Mode mode, int max_frames)
if (current_frame == null)
throw new TargetException (TargetError.NoStack);
- TargetAddress until = main_method_stackptr;
-
current_backtrace = new Backtrace (current_frame);
- foreach (StackFrame rti_frame in callback_stack) {
- current_backtrace.GetBacktrace (
- this, mode, rti_frame.StackPointer, max_frames);
-
- current_backtrace.AddFrame (rti_frame);
- }
-
- current_backtrace.GetBacktrace (this, mode, until, max_frames);
+ current_backtrace.GetBacktrace (this, mode, TargetAddress.Null, max_frames);
return current_backtrace;
});
@@ -1715,6 +1669,14 @@ public override string ReadString (TargetAddress address)
});
}
+ internal override Registers GetCallbackFrame (TargetAddress stack_pointer,
+ bool exact_match)
+ {
+ return (Registers) SendCommand (delegate {
+ return inferior.GetCallbackFrame (stack_pointer, exact_match);
+ });
+ }
+
public override void WriteBuffer (TargetAddress address, byte[] buffer)
{
SendCommand (delegate {
@@ -1808,7 +1770,6 @@ protected override void DoDispose ()
Disassembler disassembler;
ProcessStart start;
Hashtable exception_handlers;
- Stack callback_stack;
bool engine_stopped;
bool stop_requested;
bool has_thread_lock;
@@ -1825,22 +1786,21 @@ protected override void DoDispose ()
TargetAddress end_stack_address = TargetAddress.Null;
- TargetAddress main_method_stackptr = TargetAddress.Null;
- TargetAddress main_method_retaddr = TargetAddress.Null;
-
#region Nested SSE classes
- internal sealed class StackData : DebuggerMarshalByRefObject
+ protected sealed class StackData : DebuggerMarshalByRefObject
{
+ public readonly long ID;
public readonly Method Method;
public readonly TargetAddress Address;
public readonly StackFrame Frame;
public readonly Backtrace Backtrace;
public readonly Registers Registers;
- public StackData (Method method, TargetAddress address,
+ public StackData (long id, Method method, TargetAddress address,
StackFrame frame, Backtrace backtrace,
Registers registers)
{
+ this.ID = id;
this.Method = method;
this.Address = address;
this.Frame = frame;
@@ -1865,6 +1825,10 @@ protected enum EventResult
get;
}
+ protected bool HasChild {
+ get { return child != null; }
+ }
+
protected readonly SingleSteppingEngine sse;
protected readonly Inferior inferior;
@@ -2022,8 +1986,12 @@ public OperationStart (SingleSteppingEngine sse, CommandResult result)
protected override void DoExecute ()
{ }
+ Queue pending_events;
+ StackFrame main_frame;
bool initialized;
+ bool has_main;
bool has_lmf;
+ bool completed;
protected override EventResult DoProcessEvent (Inferior.ChildEvent cevent,
out TargetEventArgs args)
@@ -2034,7 +2002,11 @@ protected override void DoExecute ()
inferior.CurrentFrame);
args = null;
- if (cevent.Type != Inferior.ChildEventType.CHILD_STOPPED)
+ if ((cevent.Type == Inferior.ChildEventType.CHILD_NOTIFICATION) &&
+ ((NotificationType) cevent.Argument == NotificationType.ReachedMain))
+ has_main = true;
+ else if ((cevent.Type != Inferior.ChildEventType.CHILD_STOPPED) &&
+ (cevent.Type != Inferior.ChildEventType.CHILD_CALLBACK))
return EventResult.Completed;
if (sse.Architecture.IsSyscallInstruction (inferior, inferior.CurrentFrame)) {
@@ -2059,8 +2031,21 @@ protected override void DoExecute ()
sse.PushOperation (new OperationGetLMFAddr (sse, null));
return EventResult.Running;
}
+ } else {
+ has_main = true;
+ }
+ if (!has_main)
return EventResult.Completed;
+
+ if (pending_events == null) {
+ pending_events = new Queue (sse.ProcessServant.Session.Events);
+ compute_main_frame ();
+ }
+
+ while (!completed) {
+ if (do_execute ())
+ return EventResult.Running;
}
if (sse.ProcessServant.IsAttached)
@@ -2069,10 +2054,150 @@ protected override void DoExecute ()
Report.Debug (DebugFlags.SSE,
"{0} start #1: {1} {2} {3}", sse, cevent,
sse.ProcessServant.IsAttached, inferior.MainMethodAddress);
- sse.PushOperation (new OperationRun (
- sse, inferior.MainMethodAddress, true, Result));
+ sse.PushOperation (new OperationRun (sse, true, Result));
return EventResult.Running;
}
+
+ void compute_main_frame ()
+ {
+ Inferior.StackFrame iframe = inferior.GetCurrentFrame ();
+ Registers registers = inferior.GetRegisters ();
+
+ if (sse.ProcessServant.MonoManager != null) {
+ MonoLanguageBackend mono = sse.ProcessServant.MonoLanguage;
+
+ MonoFunctionType main = mono.MainMethod;
+
+ MethodSource source = main.MonoClass.File.GetMethodByToken (main.Token);
+ if (source != null) {
+ SourceLocation location = new SourceLocation (source);
+
+ main_frame = new StackFrame (
+ sse.thread, iframe.Address, iframe.StackPointer,
+ iframe.FrameAddress, registers, main, location);
+ } else {
+ main_frame = new StackFrame (
+ sse.thread, iframe.Address, iframe.StackPointer,
+ iframe.FrameAddress, registers);
+ }
+ sse.update_current_frame (main_frame);
+ } else {
+ Method method = sse.Lookup (inferior.MainMethodAddress);
+
+ main_frame = new StackFrame (
+ sse.thread, iframe.Address, iframe.StackPointer,
+ iframe.FrameAddress, registers, method);
+ sse.update_current_frame (main_frame);
+ }
+ }
+
+ bool do_execute ()
+ {
+ Report.Debug (DebugFlags.SSE,
+ "{0} managed main execute: {1} {2}", sse,
+ inferior.CurrentFrame, pending_events.Count);
+
+ while (pending_events.Count > 0) {
+ Event e = (Event) pending_events.Dequeue ();
+ Report.Debug (DebugFlags.SSE,
+ "{0} managed main: {1} {2}", sse, e, e.IsEnabled);
+
+ if (!e.IsEnabled)
+ continue;
+
+ Breakpoint breakpoint = e as Breakpoint;
+ if (breakpoint == null)
+ continue;
+
+ try {
+ if (activate_breakpoint (breakpoint))
+ return true;
+ } catch (TargetException ex) {
+ Report.Error ("Cannot insert breakpoint {0}: {1}",
+ e.Index, ex.Message);
+ } catch (Exception ex) {
+ Report.Error ("Cannot insert breakpoint {0}: {1}",
+ e.Index, ex.Message);
+ }
+ }
+
+ Report.Debug (DebugFlags.SSE, "{0} managed main done", sse);
+
+ completed = true;
+ return false;
+ }
+
+ bool activate_breakpoint (Breakpoint breakpoint)
+ {
+ BreakpointHandle handle = breakpoint.Resolve (sse, main_frame);
+ if (handle == null)
+ return false;
+
+ FunctionBreakpointHandle fhandle = handle as FunctionBreakpointHandle;
+ if (fhandle == null) {
+ handle.Insert (sse.Client);
+ return false;
+ }
+
+ sse.PushOperation (new OperationMethodBreakpoint (
+ sse, fhandle.Function, fhandle.MethodLoaded));
+ return true;
+ }
+ }
+
+ protected class OperationMethodBreakpoint : OperationCallback
+ {
+ public readonly MonoFunctionType Function;
+ public readonly MethodLoadedHandler Handler;
+
+ MonoLanguageBackend language;
+ int index;
+
+ bool class_resolved;
+
+ public OperationMethodBreakpoint (SingleSteppingEngine sse, TargetFunctionType func,
+ MethodLoadedHandler handler)
+ : base (sse)
+ {
+ this.Function = (MonoFunctionType) func;
+ this.Handler = handler;
+ }
+
+ protected override void DoExecute ()
+ {
+ language = sse.process.MonoLanguage;
+
+ TargetAddress image = Function.MonoClass.File.MonoImage;
+
+ inferior.CallMethod (sse.MonoDebuggerInfo.LookupClass, image.Address,
+ 0, Function.MonoClass.Name, ID);
+ }
+
+ protected override EventResult CallbackCompleted (long data1, long data2)
+ {
+ Report.Debug (DebugFlags.SSE,
+ "{0} method breakpoint callback: {1} {2:x} {3:x} {4}",
+ sse, inferior.CurrentFrame, data1, data2, class_resolved);
+
+ if (!class_resolved) {
+ TargetAddress klass = new TargetAddress (inferior.AddressDomain, data1);
+ MonoClassInfo info = Function.MonoClass.ClassResolved (sse.Client, klass);
+ TargetAddress method = info.GetMethodAddress (Function.Token);
+
+ index = MonoLanguageBackend.GetUniqueID ();
+
+ inferior.CallMethod (sse.MonoDebuggerInfo.InsertBreakpoint,
+ method.Address, index, ID);
+
+ language.RegisterMethodLoadHandler (index, Handler);
+
+ class_resolved = true;
+ return EventResult.Running;
+ }
+
+ RestoreStack ();
+ return EventResult.AskParent;
+ }
}
protected class OperationInitialize : Operation
@@ -2126,17 +2251,15 @@ protected override void DoExecute ()
inferior.CallMethod (info.GetCurrentThread, 0, 0, ID);
}
- protected override bool CallbackCompleted (long data1, long data2)
+ protected override EventResult CallbackCompleted (long data1, long data2)
{
Report.Debug (DebugFlags.SSE,
"{0} get current thread: {1:x} {2:x} {3}",
sse, data1, data2, Result);
- RestoreStack ();
-
if (data1 == 0) {
sse.PushOperation (new OperationRun (sse, null));
- return false;
+ return EventResult.Running;
}
TargetAddress thread = new TargetAddress (inferior.AddressDomain, data1);
@@ -2150,7 +2273,7 @@ protected override bool CallbackCompleted (long data1, long data2)
sse.OnManagedThreadCreated (tid, thread + info.ThreadEndStackOffset);
sse.PushOperation (new OperationGetLMFAddr (sse, null));
- return false;
+ return EventResult.Running;
}
}
@@ -2170,17 +2293,16 @@ protected override void DoExecute ()
inferior.CallMethod (info.Attach, 0, 0, ID);
}
- protected override bool CallbackCompleted (long data1, long data2)
+ protected override EventResult CallbackCompleted (long data1, long data2)
{
Report.Debug (DebugFlags.SSE,
"{0} attach done: {1:x} {2:x} {3}",
sse, data1, data2, Result);
- RestoreStack ();
inferior.InitializeModules ();
sse.PushOperation (new OperationGetLMFAddr (sse, null));
- return false;
+ return EventResult.Running;
}
}
@@ -2200,25 +2322,7 @@ protected override void DoExecute ()
inferior.CallMethod (info.GetLMFAddress, 0, 0, ID);
}
- protected override bool CallbackCompleted (Inferior.ChildEvent cevent,
- out TargetEventArgs args,
- out EventResult result)
- {
- Report.Debug (DebugFlags.SSE, "{0} get lmf done: {1} {2}",
- sse, cevent, Result);
-
- args = null;
-
- if (!CallbackCompleted (cevent.Data1, cevent.Data2)) {
- result = EventResult.Running;
- return true;
- }
-
- result = EventResult.Completed;
- return true;
- }
-
- protected override bool CallbackCompleted (long data1, long data2)
+ protected override EventResult CallbackCompleted (long data1, long data2)
{
Report.Debug (DebugFlags.SSE,
"{0} get lmf: {1:x} {2:x} {3}",
@@ -2226,7 +2330,7 @@ protected override bool CallbackCompleted (long data1, long data2)
RestoreStack ();
sse.lmf_address = new TargetAddress (inferior.AddressDomain, data1);
- return true;
+ return EventResult.AskParent;
}
}
@@ -2246,23 +2350,12 @@ protected override void DoExecute ()
inferior.CallMethod (info.Detach, 0, 0, ID);
}
- protected override bool CallbackCompleted (Inferior.ChildEvent cevent,
- out TargetEventArgs args,
- out EventResult result)
+ protected override EventResult CallbackCompleted (long data1, long data2)
{
- Report.Debug (DebugFlags.SSE, "{0} detach done: {1} {2}",
- sse, cevent, Result);
+ Report.Debug (DebugFlags.SSE, "{0} detach done: {1}", sse, Result);
sse.DoDetach ();
-
- args = null;
- result = EventResult.CompletedCallback;
- return true;
- }
-
- protected override bool CallbackCompleted (long data1, long data2)
- {
- throw new InternalError ();
+ return EventResult.CompletedCallback;
}
}
@@ -2286,8 +2379,37 @@ protected class OperationStepOverBreakpoint : Operation
get { return false; }
}
+ bool check_trampolines ()
+ {
+ if (is_trampoline || !sse.process.IsManaged)
+ return false;
+
+ int insn_size;
+ TargetAddress call = inferior.Architecture.GetCallTarget (
+ inferior, inferior.CurrentFrame, out insn_size);
+ if (call.IsNull)
+ return false;
+
+ bool is_start;
+ TargetAddress trampoline = sse.process.MonoLanguage.GetTrampolineAddress (
+ inferior, call, out is_start);
+
+ if (trampoline.IsNull)
+ return false;
+
+ sse.PushOperation (new OperationTrampoline (sse, trampoline, null));
+ return true;
+ }
+
protected override void DoExecute ()
{
+ Report.Debug (DebugFlags.SSE,
+ "{0} stepping over breakpoint: {1} {2}", sse,
+ is_trampoline, until);
+
+ if (check_trampolines ())
+ return;
+
sse.process.AcquireGlobalThreadLock (sse);
inferior.DisableBreakpoint (Index);
@@ -2304,32 +2426,7 @@ protected override void DoExecute ()
return;
}
- Method method = sse.Lookup (inferior.CurrentFrame);
-
- if (method == null) {
- inferior.Step ();
- return;
- }
-
- ILanguageBackend language = method.Module.LanguageBackend;
-
- int insn_size;
- TargetAddress current_frame = inferior.CurrentFrame;
- TargetAddress call = inferior.Architecture.GetCallTarget (
- inferior, current_frame, out insn_size);
- if (call.IsNull) {
- inferior.Step ();
- return;
- }
-
- bool is_start;
- TargetAddress trampoline_address = language.GetTrampolineAddress (
- inferior, call, out is_start);
-
- if (!trampoline_address.IsNull)
- sse.do_trampoline (language, trampoline_address, null, is_start);
- else
- inferior.Step ();
+ inferior.Step ();
}
bool ReleaseThreadLock (Inferior.ChildEvent cevent)
@@ -2433,7 +2530,7 @@ protected bool CheckTrampoline (TargetAddress call)
*/
if (!trampoline.IsNull) {
sse.do_trampoline (
- language, trampoline, TrampolineHandler, is_start);
+ language, call, trampoline, TrampolineHandler, is_start);
return true;
}
}
@@ -2840,7 +2937,7 @@ protected OperationCallback (SingleSteppingEngine sse, CommandResult result)
public override void Execute ()
{
- stack_data = sse.save_stack ();
+ stack_data = sse.save_stack (ID);
base.Execute ();
}
@@ -2858,63 +2955,38 @@ public override void Execute ()
sse.do_continue ();
return EventResult.Running;
} else if (cevent.Type != Inferior.ChildEventType.CHILD_CALLBACK) {
- Report.Debug (DebugFlags.SSE, "{0} aborting callback {1} at {2}: {3}",
- sse, this, inferior.CurrentFrame, cevent);
- RestoreStack ();
- return EventResult.CompletedCallback;
+ Report.Debug (DebugFlags.SSE,
+ "{0} aborting callback {1} ({2}) at {3}: {4}",
+ sse, this, ID, inferior.CurrentFrame, cevent);
+ AbortOperation ();
+ return EventResult.Completed;
}
if (ID != cevent.Argument) {
- AbortCallback ();
- goto out_frame_changed;
+ Report.Debug (DebugFlags.SSE,
+ "{0} aborting callback {1} ({2}) at {3}: {4}",
+ sse, this, ID, inferior.CurrentFrame, cevent);
+ AbortOperation ();
+ return EventResult.Completed;
}
try {
- EventResult result;
- if (CallbackCompleted (cevent, out args, out result))
- return result;
+ args = null;
+ return CallbackCompleted (cevent.Data1, cevent.Data2);
} catch (Exception ex) {
RestoreStack ();
return EventResult.CompletedCallback;
}
-
- if (stack_data != null) {
- sse.restore_stack (stack_data);
- return EventResult.CompletedCallback;
- }
-
- out_frame_changed:
- sse.frame_changed (inferior.CurrentFrame, null);
- args = new TargetEventArgs (
- TargetEventType.TargetStopped, 0, sse.current_frame);
- return EventResult.Completed;
- }
-
- protected virtual bool CallbackCompleted (Inferior.ChildEvent cevent,
- out TargetEventArgs args,
- out EventResult result)
- {
- if (!CallbackCompleted (cevent.Data1, cevent.Data2)) {
- args = null;
- result = EventResult.Running;
- return true;
- }
-
- args = null;
- result = EventResult.CompletedCallback;
- return false;
}
- protected abstract bool CallbackCompleted (long data1, long data2);
+ protected abstract EventResult CallbackCompleted (long data1, long data2);
public override bool IsSourceOperation {
get { return false; }
}
- public void AbortCallback ()
+ protected void AbortOperation ()
{
- if (stack_data != null)
- sse.discard_stack (stack_data);
stack_data = null;
}
@@ -2927,25 +2999,8 @@ protected void RestoreStack ()
protected void DiscardStack ()
{
- if (stack_data != null)
- sse.discard_stack (stack_data);
stack_data = null;
}
-
- protected void PushRuntimeInvoke ()
- {
- Inferior.StackFrame iframe = inferior.GetCurrentFrame ();
- Registers registers = inferior.GetRegisters ();
-
- Symbol name = new Symbol ("<method called from mdb>", iframe.Address, 0);
-
- StackFrame rti_frame = new StackFrame (
- sse.thread, iframe.Address, iframe.StackPointer,
- iframe.FrameAddress, registers, name);
-
- sse.push_runtime_invoke (rti_frame);
- rti_frame.ParentFrame = stack_data.Frame;
- }
}
protected class OperationRuntimeInvoke : OperationCallback
@@ -2960,7 +3015,6 @@ protected class OperationRuntimeInvoke : OperationCallback
TargetAddress method = TargetAddress.Null;
TargetAddress invoke = TargetAddress.Null;
TargetClassObject instance;
- bool pushed_rti_frame;
Stage stage;
protected enum Stage {
@@ -3009,7 +3063,8 @@ protected override void DoExecute ()
"{0} rti resolving class {1}:{2:x}", sse, image, token);
inferior.CallMethod (
- language.LookupClassFunc, image.Address, token, ID);
+ sse.MonoDebuggerInfo.LookupClass, image.Address, 0,
+ Function.MonoClass.Name, ID);
return;
}
@@ -3036,7 +3091,7 @@ void do_execute ()
stage = Stage.CompilingMethod;
inferior.CallMethod (
- language.CompileMethodFunc, method.Address, 0, ID);
+ sse.MonoDebuggerInfo.CompileMethod, method.Address, 0, ID);
return;
}
@@ -3044,7 +3099,7 @@ void do_execute ()
sse.insert_temporary_breakpoint (invoke);
inferior.RuntimeInvoke (
- sse.Thread, language.RuntimeInvokeFunc,
+ sse.Thread, sse.MonoDebuggerInfo.RuntimeInvoke,
method, instance, ParamObjects, ID, Debug);
stage = Stage.InvokedMethod;
@@ -3071,8 +3126,8 @@ bool get_method_address ()
TargetAddress klass = ((MonoClassObject) instance).KlassAddress;
stage = Stage.BoxingInstance;
inferior.CallMethod (
- language.GetBoxedObjectFunc, klass.Address,
- instance.Location.Address.Address, ID);
+ sse.MonoDebuggerInfo.GetBoxedObjectMethod, klass.Address,
+ instance.Location.GetAddress (sse).Address, ID);
return false;
}
@@ -3087,12 +3142,13 @@ bool get_virtual_method ()
stage = Stage.GettingVirtualMethod;
inferior.CallMethod (
- language.GetVirtualMethodFunc, instance.Location.Address.Address,
+ sse.MonoDebuggerInfo.GetVirtualMethod,
+ instance.Location.GetAddress (sse).Address,
method.Address, ID);
return false;
}
- protected override bool CallbackCompleted (long data1, long data2)
+ protected override EventResult CallbackCompleted (long data1, long data2)
{
switch (stage) {
case Stage.Uninitialized: {
@@ -3104,7 +3160,7 @@ protected override bool CallbackCompleted (long data1, long data2)
Function.MonoClass.ClassResolved (sse.Thread, klass);
stage = Stage.ResolvedClass;
do_execute ();
- return false;
+ return EventResult.Running;
}
case Stage.BoxingInstance: {
@@ -3117,7 +3173,7 @@ protected override bool CallbackCompleted (long data1, long data2)
instance = (MonoClassObject) instance.Type.ParentType.GetObject (new_loc);
stage = Stage.HasMethodAddress;
do_execute ();
- return false;
+ return EventResult.Running;
}
case Stage.GettingVirtualMethod: {
@@ -3133,7 +3189,8 @@ protected override bool CallbackCompleted (long data1, long data2)
Result.ExceptionMessage = String.Format (
"Unable to get virtual method `{0}'.", Function.FullName);
Result.InvocationCompleted = true;
- return true;
+ RestoreStack ();
+ return EventResult.CompletedCallback;
}
if (!class_type.IsByRef) {
@@ -3144,7 +3201,7 @@ protected override bool CallbackCompleted (long data1, long data2)
stage = Stage.HasVirtualMethod;
do_execute ();
- return false;
+ return EventResult.Running;
}
case Stage.CompilingMethod: {
@@ -3155,7 +3212,7 @@ protected override bool CallbackCompleted (long data1, long data2)
stage = Stage.CompiledMethod;
do_execute ();
- return false;
+ return EventResult.Running;
}
case Stage.InvokedMethod: {
@@ -3163,11 +3220,6 @@ protected override bool CallbackCompleted (long data1, long data2)
"{0} rti done: {1:x} {2:x}",
sse, data1, data2);
- if (pushed_rti_frame) {
- sse.pop_runtime_invoke ();
- pushed_rti_frame = false;
- }
-
if (data2 != 0) {
TargetAddress exc_address = new TargetAddress (
inferior.AddressDomain, data2);
@@ -3187,7 +3239,8 @@ protected override bool CallbackCompleted (long data1, long data2)
}
Result.InvocationCompleted = true;
- return true;
+ RestoreStack ();
+ return EventResult.CompletedCallback;
}
default:
@@ -3216,8 +3269,7 @@ protected override bool CallbackCompleted (long data1, long data2)
"{0} stopped at invoke method {1}",
sse, invoke);
- PushRuntimeInvoke ();
- pushed_rti_frame = true;
+ inferior.MarkRuntimeInvokeFrame ();
}
args = null;
@@ -3247,12 +3299,14 @@ protected class OperationCallMethod : OperationCallback
public readonly string StringArgument;
public OperationCallMethod (SingleSteppingEngine sse,
- TargetAddress method, long arg, string sarg)
+ TargetAddress method, long arg1, long arg2,
+ string sarg)
: base (sse)
{
this.Type = CallMethodType.LongString;
this.Method = method;
- this.Argument1 = arg;
+ this.Argument1 = arg1;
+ this.Argument2 = arg2;
this.StringArgument = sarg;
}
@@ -3287,7 +3341,8 @@ protected override void DoExecute ()
break;
case CallMethodType.LongString:
- inferior.CallMethod (Method, Argument1, StringArgument, ID);
+ inferior.CallMethod (Method, Argument1, Argument2,
+ StringArgument, ID);
break;
default:
@@ -3295,7 +3350,7 @@ protected override void DoExecute ()
}
}
- protected override bool CallbackCompleted (long data1, long data2)
+ protected override EventResult CallbackCompleted (long data1, long data2)
{
if (inferior.TargetAddressSize == 4)
data1 &= 0xffffffffL;
@@ -3303,76 +3358,235 @@ protected override bool CallbackCompleted (long data1, long data2)
Report.Debug (DebugFlags.SSE,
"{0} call method done: {1:x} {2:x} {3}",
sse, data1, data2, Result);
-
- Result.Result = new TargetAddress (inferior.AddressDomain, data1);
- return true;
+ RestoreStack ();
+ Result.Result = new TargetAddress (inferior.AddressDomain, data1);
+ return EventResult.CompletedCallback;
}
}
- protected class OperationCompileMethod : OperationCallback
+ protected delegate void MyTrampolineHandler (TargetAddress address);
+
+ protected class OperationTrampoline : Operation
{
- public readonly TargetAddress CompileMethod;
- public readonly TargetAddress MethodAddress;
+ public readonly TargetAddress Method;
public readonly TrampolineHandler TrampolineHandler;
+ TargetAddress address = TargetAddress.Null;
+ bool compiled;
bool completed;
- public OperationCompileMethod (SingleSteppingEngine sse,
- TargetAddress compile, TargetAddress address,
- TrampolineHandler handler)
- : base (sse)
+ public OperationTrampoline (SingleSteppingEngine sse, TargetAddress method,
+ TrampolineHandler handler)
+ : base (sse, null)
{
- this.CompileMethod = compile;
- this.MethodAddress = address;
+ this.Method = method;
this.TrampolineHandler = handler;
}
+ public override bool IsSourceOperation {
+ get { return true; }
+ }
+
protected override void DoExecute ()
{
- Report.Debug (DebugFlags.SSE, "{0} compiling method: {1}", sse, MethodAddress);
- inferior.CallMethod (CompileMethod, MethodAddress.Address, 0, ID);
+ sse.PushOperation (new OperationRuntimeClassInit (sse, Method));
}
- protected override bool CallbackCompleted (long data1, long data2)
+ protected override EventResult DoProcessEvent (Inferior.ChildEvent cevent,
+ out TargetEventArgs args)
{
- TargetAddress address = new TargetAddress (
- inferior.AddressDomain, data1);
+ Report.Debug (DebugFlags.SSE,
+ "{0} trampoline event: {1}", sse, cevent);
- Report.Debug (DebugFlags.SSE, "{0} done compiling method: {1}",
- sse, address);
+ args = null;
+
+ Report.Debug (DebugFlags.SSE, "{0} resuming operation {1}: {2} {3} {4} {5}",
+ sse, this, address, inferior.CurrentFrame, compiled, completed);
+
+ if (completed)
+ return EventResult.ResumeOperation;
+
+ if (!compiled) {
+ compiled = true;
+ sse.PushOperation (new OperationCompileMethod (sse, Method,
+ delegate (TargetAddress the_address) {
+ this.address = the_address;
+ }));
+ return EventResult.Running;
+ }
- RestoreStack ();
completed = true;
- Method method = sse.Lookup (address);
- Report.Debug (DebugFlags.SSE,
- "{0} compiled method: {1} {2} {3} {4} {5}",
- sse, address, method,
- method != null ? method.Module : null,
- sse.MethodHasSource (method), TrampolineHandler);
+ if (TrampolineHandler != null) {
+ Method method = sse.Lookup (address);
+ Report.Debug (DebugFlags.SSE,
+ "{0} compiled method: {1} {2} {3} {4} {5}",
+ sse, address, method,
+ method != null ? method.Module : null,
+ sse.MethodHasSource (method), TrampolineHandler);
- if ((TrampolineHandler != null) && !TrampolineHandler (method)) {
- sse.do_next_native ();
- return false;
+ if (!TrampolineHandler (method)) {
+ sse.do_next_native ();
+ return EventResult.Running;
+ }
}
Report.Debug (DebugFlags.SSE, "{0} entering trampoline {1} at {2}",
- sse, inferior.CurrentFrame, address);
+ sse, address, inferior.CurrentFrame);
sse.do_continue (address, true);
- return false;
+ return EventResult.Running;
+ }
+ }
+
+ protected class OperationNativeTrampoline : Operation
+ {
+ public readonly TrampolineHandler TrampolineHandler;
+ public readonly TargetAddress Trampoline;
+
+ TargetAddress stack_pointer;
+ bool entered_trampoline;
+ bool done;
+
+ public OperationNativeTrampoline (SingleSteppingEngine sse, TargetAddress trampoline,
+ TrampolineHandler handler)
+ : base (sse, null)
+ {
+ this.TrampolineHandler = handler;
+ this.Trampoline = trampoline;
+ }
+
+ public override bool IsSourceOperation {
+ get { return true; }
+ }
+
+ protected override void DoExecute ()
+ {
+ Inferior.StackFrame frame = inferior.GetCurrentFrame ();
+ stack_pointer = frame.StackPointer;
+
+ Report.Debug (DebugFlags.SSE,
+ "{0} starting native trampoline {1} at {2}: {3}",
+ sse, Trampoline, frame.Address, stack_pointer);
+
+ sse.do_continue (Trampoline);
}
protected override EventResult DoProcessEvent (Inferior.ChildEvent cevent,
out TargetEventArgs args)
{
- if (!completed)
- return base.DoProcessEvent (cevent, out args);
-
+ Report.Debug (DebugFlags.SSE,
+ "{0} native trampoline event: {1}", sse, cevent);
args = null;
- return EventResult.AskParent;
+
+ Inferior.StackFrame frame = inferior.GetCurrentFrame ();
+
+ if (done)
+ return EventResult.Completed;
+
+ if (!entered_trampoline) {
+ stack_pointer = frame.StackPointer;
+
+ sse.do_step_native ();
+ entered_trampoline = true;
+ return EventResult.Running;
+ }
+
+ if (frame.StackPointer <= stack_pointer) {
+ sse.do_next_native ();
+ return EventResult.Running;
+ }
+
+ done = true;
+
+ int insn_size;
+ TargetAddress jump_target = sse.Architecture.GetJumpTarget (
+ inferior, frame.Address, out insn_size);
+
+ if (!jump_target.IsNull) {
+ sse.do_step_native ();
+ return EventResult.Running;
+ }
+
+ return EventResult.Completed;
+
+#if FIXME
+
+ if (TrampolineHandler != null) {
+ Method method = sse.Lookup (address);
+ Report.Debug (DebugFlags.SSE,
+ "{0} compiled method: {1} {2} {3} {4} {5}",
+ sse, address, method,
+ method != null ? method.Module : null,
+ sse.MethodHasSource (method), TrampolineHandler);
+
+ if (!TrampolineHandler (method)) {
+ sse.do_next_native ();
+ return EventResult.Running;
+ }
+ }
+
+ Report.Debug (DebugFlags.SSE, "{0} entering trampoline {1} at {2}",
+ sse, address, inferior.CurrentFrame);
+
+ sse.do_continue (address, true);
+ return EventResult.Running;
+#endif
+ }
+ }
+
+ protected class OperationCompileMethod : OperationCallback
+ {
+ public readonly TargetAddress Method;
+ public readonly MyTrampolineHandler MyTrampolineHandler;
+
+ public OperationCompileMethod (SingleSteppingEngine sse, TargetAddress method,
+ MyTrampolineHandler handler)
+ : base (sse)
+ {
+ this.Method = method;
+ this.MyTrampolineHandler = handler;
+ }
+
+ protected override void DoExecute ()
+ {
+ inferior.CallMethod (sse.MonoDebuggerInfo.CompileMethod, Method.Address, 0, ID);
+ }
+
+ protected override EventResult CallbackCompleted (long data1, long data2)
+ {
+ TargetAddress address = new TargetAddress (inferior.AddressDomain, data1);
+ MyTrampolineHandler (address);
+ RestoreStack ();
+ return EventResult.ResumeOperation;
+ }
+ }
+
+ protected class OperationRuntimeClassInit : OperationCallback
+ {
+ public readonly TargetAddress Method;
+
+ public OperationRuntimeClassInit (SingleSteppingEngine sse, TargetAddress method)
+ : base (sse)
+ {
+ this.Method = method;
+ }
+
+ protected override void DoExecute ()
+ {
+ TargetAddress klass = inferior.ReadAddress (Method + 8);
+ Report.Debug (DebugFlags.SSE, "{0} runtime class init: {1} {2}",
+ sse, Method, klass);
+ inferior.CallMethod (sse.MonoDebuggerInfo.RuntimeClassInit, klass.Address, 0, ID);
+ }
+
+ protected override EventResult CallbackCompleted (long data1, long data2)
+ {
+ Report.Debug (DebugFlags.SSE, "{0} runtime class init done", sse);
+ RestoreStack ();
+ return EventResult.ResumeOperation;
}
}
@@ -3381,7 +3595,6 @@ protected class OperationInsertBreakpoint : OperationCallback
public readonly Breakpoint Breakpoint;
public readonly MonoFunctionType Function;
- MonoLanguageBackend language;
TargetAddress method, address;
public OperationInsertBreakpoint (SingleSteppingEngine sse,
@@ -3394,16 +3607,11 @@ protected class OperationInsertBreakpoint : OperationCallback
protected override void DoExecute ()
{
- if (language == null)
- language = sse.process.MonoLanguage;
-
method = Function.GetMethodAddress (sse.Thread);
-
- inferior.CallMethod (language.CompileMethodFunc,
- method.Address, 0, ID);
+ inferior.CallMethod (sse.MonoDebuggerInfo.CompileMethod, method.Address, 0, ID);
}
- protected override bool CallbackCompleted (long data1, long data2)
+ protected override EventResult CallbackCompleted (long data1, long data2)
{