Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Released version 0.20 "Bruxelles" of the Mono Debugger :-)

svn path=/tags/debugger-0-20/; revision=61057
  • Loading branch information...
commit 44e9063a19f05b4d43706e3b5c7d6e52e8210cbf 12 parents 939d714 + 0c61b27 + dac2712 + edf0806 + 4bb220a + 5cfba94 + 9feaebe + 173718d + 3871c9e + 192b7ba + 6eb1c0a + cb3a15c
Martin Baulig authored
View
118 ChangeLog
@@ -1,3 +1,121 @@
+2006-05-24 Martin Baulig <martin@ximian.com>
+
+ Released version 0.20 "Bruxelles" of the Mono Debugger :-)
+
+2006-05-24 Martin Baulig <martin@ximian.com>
+
+ * backends/server/library.c
+ (mono_debugger_server_set_notification): This is no longer a
+ "static" method - different processes may have different
+ notification addresses, so we need to make this per-target.
+
+ * backends/server/x86-ptrace.c
+ (InferiorHandle): Added `guint64 nofification_address'; replaces
+ the static variable in x86_64-arch.c/i386-arch.c.
+ (server_ptrace_set_notification): Moved here from x86_64-arch.c.
+
+ * backends/Inferior.cs
+ (Inferior.SetNotificationAddress): New internal method; call
+ mono_debugger_server_set_notification().
+
+ * backends/MonoThreadManager.cs
+ (MonoThreadManager.ThreadCreated): Call SetNotificationAddress()
+ on each newly created inferior.
+
+2006-05-24 Martin Baulig <martin@ximian.com>
+
+ * arch/bfdglue.c
+ (bfd_glue_get_section_size): Added `raw_size' argument.
+ (bfd_glue_get_section_contents): Take a pre-alloced buffer as
+ argument rather than allocating it here.
+
+2006-05-24 Martin Baulig <martin@ximian.com>
+
+ * backends/ProcessServant.cs
+ (ProcessServant.Kill): Don't call Dispose().
+
+ * backends/server/x86-linux-ptrace.c
+ (server_ptrace_initialize_process): Don't use PTRACE_O_TRACEEXIT;
+ we don't need this.
+
+2006-05-24 Martin Baulig <martin@ximian.com>
+
+ * backends/MonoThreadManager.cs
+ (MonoThreadManager.HandleChildEvent): Clear the `csharp_language' on
+ `NofitifactionType.FinalizeManagedCode'.
+
+2006-05-24 Martin Baulig <martin@ximian.com>
+
+ * configure.in: Check whether the Mono we're using is recent enough.
+
+2006-05-24 Martin Baulig <martin@ximian.com>
+
+ * frontend/Command.cs
+ (BreakCommand.DoResolve): If our base class'es DoResolve() failed,
+ try resolving the expression as an address.
+
+ * frontend/Interpreter.cs
+ (Interpreter.InsertBreakpoint): Added overloaded version which
+ takes a `TargetAddress'.
+
+ * classes/Process.cs
+ (Process.InsertBreakpoint): Added overloaded version which takes a
+ `TargetAddress'.
+
+2006-05-24 Martin Baulig <martin@ximian.com>
+
+ * backends/server/server.h
+ (ServerStatusMessageType): Added `MESSAGE_CHILD_CALLED_EXIT'.
+
+ * backends/server/x86-ptrace.c
+ (server_ptrace_dispatch_event): Use `MESSAGE_CHILD_CALLED_EXIT'
+ for `PTRACE_EVENT_EXIT'.
+
+2006-05-23 Martin Baulig <martin@ximian.com>
+
+ * backends/Inferior.cs
+ (Inferior.PushRegisters): New public method.
+ (Inferior.PopRegisters): New public method.
+
+ * backends/SingleSteppingEngine.cs
+ (SingleSteppingEngine.AcquireThreadLock): Call
+ inferior.PushRegisters() to push all registers onto the stack so
+ the GC will see them.
+ (SingleSteppingEngine.ReleaseThreadLock): Call
+ inferior.PopRegisters() to remove them from the stack again.
+
+ * backends/server/x86-linux-ptrace.c
+ (server_ptrace_initialize_process): Add `PTRACE_O_TRACEEXIT'.
+
+ * backends/server/x86_64-arch.c
+ (server_ptrace_push_registers): New method.
+ (server_ptrace_pop_registers): New method.
+
+ * backends/server/i386-arch.c
+ (server_ptrace_push_registers): New method.
+ (server_ptrace_pop_registers): New method.
+
+ * backends/server/library.c
+ (mono_debugger_server_push_registers): New public method.
+ (mono_debugger_server_pop_registers): New public method.
+
+2006-05-20 Martin Baulig <martin@ximian.com>
+
+ * arch/DwarfReader.cs
+ (DwarfReader.DwarfTargetVariable.GetLocation): Add support for
+ location lists.
+
+2006-05-20 Martin Baulig <martin@ximian.com>
+
+ * arch/DwarfFrameReader.cs: More 64-bit updates.
+
+2006-05-20 Martin Baulig <martin@ximian.com>
+
+ * frontend/Command.cs
+ (SourceCommand.DoResolve): Also lookup native methods.
+ (BreakCommand): Add `-global' argument as a shortcut for
+ `-group global'.
+
2006-05-17 Martin Baulig <martin@ximian.com>
* frontend/Interpreter.cs
View
11 NEWS
@@ -1,4 +1,4 @@
-May 12th, 2006 - Martin Baulig
+May 24th, 2006 - Martin Baulig
------------------------------
Released version 0.20 "Bruxelles" of the Mono Debugger :-)
@@ -14,6 +14,13 @@ Released version 0.20 "Bruxelles" of the Mono Debugger :-)
- Cleaned up method lookups; there's a very complex test for them
in test/testsuite/TestMethodLookup.cs.
+- Lots of stability improvements.
+
+- Fixed a very old GC bug which was preventing us from running
+ xsp inside the debugger.
+
+- Fixed a very old race condition which was causing crashes at exit.
+
- Fixed line numbers in stack traces.
- Added experimental support for hardware watchpoints - I needed
@@ -23,6 +30,8 @@ Released version 0.20 "Bruxelles" of the Mono Debugger :-)
than before; I'm still investigating the issue.
I'm currently using `ulimit -Sm 1000000 -Sv 1000000'.
+- The next releases will be "Dublin", "Sidney" and "Cologne".
+
April 10th, 2006 - Martin Baulig
--------------------------------
View
28 arch/Bfd.cs
@@ -65,7 +65,7 @@ internal Section (Bfd bfd, IntPtr section)
this.name = bfd_glue_get_section_name (section);
this.vma = bfd_glue_get_section_vma (section);
- this.size = bfd_glue_get_section_size (section);
+ this.size = bfd_glue_get_section_size (section, true);
this.flags = bfd_glue_get_section_flags (section);
contents = new ObjectCache (
@@ -131,7 +131,7 @@ public override string ToString ()
extern static int bfd_glue_get_dynamic_symbols (IntPtr bfd, out IntPtr symtab);
[DllImport("monodebuggerserver")]
- extern static bool bfd_glue_get_section_contents (IntPtr bfd, IntPtr section, bool raw_section, out IntPtr data, out int size);
+ extern static bool bfd_glue_get_section_contents (IntPtr bfd, IntPtr section, IntPtr data, int size);
[DllImport("monodebuggerserver")]
extern static IntPtr bfd_glue_get_first_section (IntPtr bfd);
@@ -146,7 +146,7 @@ public override string ToString ()
extern static string bfd_glue_get_section_name (IntPtr section);
[DllImport("monodebuggerserver")]
- extern static long bfd_glue_get_section_size (IntPtr section);
+ extern static int bfd_glue_get_section_size (IntPtr section, bool raw_section);
[DllImport("monodebuggerserver")]
extern static SectionFlags bfd_glue_get_section_flags (IntPtr section);
@@ -793,16 +793,18 @@ public TargetReader GetSectionReader (string name, bool raw_section)
byte[] GetSectionContents (IntPtr section, bool raw_section)
{
- IntPtr data;
- int size;
-
- if (!bfd_glue_get_section_contents (bfd, section, raw_section, out data, out size))
- return null;
-
- byte[] retval = new byte [size];
- Marshal.Copy (data, retval, 0, size);
- g_free (data);
- return retval;
+ int size = bfd_glue_get_section_size (section, raw_section);
+ IntPtr data = IntPtr.Zero;
+ try {
+ data = Marshal.AllocHGlobal (size);
+ if (!bfd_glue_get_section_contents (bfd, section, data, size))
+ return null;
+ byte[] retval = new byte [size];
+ Marshal.Copy (data, retval, 0, size);
+ return retval;
+ } finally {
+ Marshal.FreeHGlobal (data);
+ }
}
public bool HasSection (string name)
View
13 arch/DwarfFrameReader.cs
@@ -48,7 +48,7 @@ protected CIE find_cie (long offset)
break;
long end_pos = reader.Position + length;
- int cie_pointer = reader.ReadInt32 ();
+ long cie_pointer = reader.ReadOffset ();
bool is_cie;
if (is_ehframe)
is_cie = cie_pointer == 0;
@@ -61,12 +61,13 @@ protected CIE find_cie (long offset)
}
if (is_ehframe)
- cie_pointer = (int) reader.Position - cie_pointer - 4;
+ cie_pointer = reader.Position - cie_pointer -
+ target.TargetInfo.TargetAddressSize;
CIE cie = find_cie (cie_pointer);
- long initial = ReadEncodedValue (reader, cie.Encoding);
- long range = ReadEncodedValue (reader, cie.Encoding & 0x0f);
+ long initial = reader.ReadAddress ();
+ long range = reader.ReadAddress ();
TargetAddress start = new TargetAddress (
target.TargetInfo.AddressDomain, initial);
@@ -372,7 +373,7 @@ protected class CIE
int code_alignment;
int data_alignment;
int return_register;
- // bool has_z_augmentation;
+ // bool has_z_augmentation;
byte encoding = (byte) DW_EH_PE.udata4;
Column[] columns;
@@ -453,7 +454,7 @@ void read_cie (DwarfBinaryReader reader)
for (int pos = 0; pos < augmentation.Length; pos++) {
if (augmentation [pos] == 'z') {
reader.ReadLeb128 ();
- // has_z_augmentation = true;
+ // has_z_augmentation = true;
continue;
}
View
147 arch/DwarfReader.cs
@@ -98,6 +98,7 @@ internal class DwarfReader : DebuggerMarshalByRefObject
bool is64bit;
byte address_size;
+ ObjectCache debug_loc_reader;
ObjectCache debug_info_reader;
ObjectCache debug_abbrev_reader;
ObjectCache debug_line_reader;
@@ -148,6 +149,7 @@ public DwarfReader (Bfd bfd, Module module, SourceFileFactory factory)
debug_pubnames_reader = create_reader (".debug_pubnames");
debug_pubtypes_reader = create_reader (".debug_pubtypes");
debug_str_reader = create_reader (".debug_str");
+ debug_loc_reader = create_reader (".debug_loc");
compile_unit_hash = Hashtable.Synchronized (new Hashtable ());
method_source_hash = Hashtable.Synchronized (new Hashtable ());
@@ -765,6 +767,13 @@ ObjectCache create_reader (string section_name)
}
}
+ public DwarfBinaryReader DebugLocationReader {
+ get {
+ return new DwarfBinaryReader (
+ bfd, (TargetBlob) debug_loc_reader.Data, Is64Bit);
+ }
+ }
+
public string FileName {
get {
return filename;
@@ -2623,28 +2632,34 @@ public override string ToString ()
protected class DwarfTargetVariable : TargetVariable
{
- DwarfReader dwarf;
- string name;
+ readonly DieSubprogram subprog;
+ readonly string name;
readonly TargetType type;
- TargetBinaryReader locreader;
+ readonly byte[] location_block;
+ readonly long location_offset;
int offset;
- public DwarfTargetVariable (DwarfReader dwarf, string name, TargetType type,
- TargetBinaryReader locreader)
+ protected DwarfTargetVariable (DieSubprogram subprog, string name, TargetType type)
{
- this.dwarf = dwarf;
+ this.subprog = subprog;
this.name = name;
this.type = type;
- this.locreader = locreader;
}
- public DwarfTargetVariable (DwarfReader dwarf, string name, TargetType type,
- int offset)
+ public DwarfTargetVariable (DieSubprogram subprog, string name, TargetType type,
+ byte[] location_block)
+ : this (subprog, name, type)
{
- this.dwarf = dwarf;
- this.name = name;
- this.type = type;
- this.offset = offset;
+ this.location_block = location_block;
+ this.location_offset = -1;
+ }
+
+ public DwarfTargetVariable (DieSubprogram subprog, string name, TargetType type,
+ long location_offset)
+ : this (subprog, name, type)
+ {
+ this.location_block = null;
+ this.location_offset = location_offset;
}
public override string Name {
@@ -2665,37 +2680,44 @@ public bool CheckValid (StackFrame frame)
return true;
}
- public TargetLocation GetLocation (StackFrame frame)
+ TargetLocation GetLocation (StackFrame frame, byte[] data)
{
- if (locreader == null)
- return null;
+ TargetBinaryReader locreader = new TargetBinaryReader (
+ data, subprog.dwarf.TargetInfo);
- locreader.Position = 0;
byte opcode = locreader.ReadByte ();
-
+ bool is_regoffset;
int reg, off;
- if ((opcode >= 0x70) && (opcode <= 0x8f)) { // DW_OP_breg0
+ if ((opcode >= 0x50) && (opcode <= 0x6f)) { // DW_OP_reg
+ reg = opcode - 0x50 + 3;
+ off = 0;
+ is_regoffset = false;
+ } else if ((opcode >= 0x70) && (opcode <= 0x8f)) { // DW_OP_breg
reg = opcode - 0x70 + 3;
off = locreader.ReadSLeb128 ();
+ is_regoffset = true;
} else if (opcode == 0x90) { // DW_OP_regx
reg = locreader.ReadLeb128 () + 3;
off = 0;
+ is_regoffset = false;
} else if (opcode == 0x91) { // DW_OP_fbreg
reg = 3;
off = locreader.ReadSLeb128 ();
+ is_regoffset = true;
} else if (opcode == 0x92) { // DW_OP_bregx
reg = locreader.ReadLeb128 () + 3;
off = locreader.ReadSLeb128 ();
+ is_regoffset = true;
} else {
Console.WriteLine ("UNKNOWN OPCODE: {0:x}", opcode);
return null;
}
- reg = dwarf.bfd.Architecture.DwarfFrameRegisterMap [reg];
+ reg = subprog.dwarf.bfd.Architecture.DwarfFrameRegisterMap [reg];
MonoVariableLocation loc = new MonoVariableLocation (
- frame.Thread, true, frame.Registers [reg],
+ frame.Thread, is_regoffset, frame.Registers [reg],
off + offset, type.IsByRef);
if (!locreader.IsEof)
@@ -2704,6 +2726,42 @@ public TargetLocation GetLocation (StackFrame frame)
return loc;
}
+ public TargetLocation GetLocation (StackFrame frame)
+ {
+ if (location_block != null)
+ return GetLocation (frame, location_block);
+
+ DwarfBinaryReader reader = subprog.dwarf.DebugLocationReader;
+ reader.Position = location_offset;
+
+ long address = frame.TargetAddress.Address;
+ long base_address = subprog.DieCompileUnit.StartAddress;
+
+ while (true) {
+ long start = reader.ReadAddress ();
+ long end = reader.ReadAddress ();
+
+ if (start == -1) {
+ Console.WriteLine ("BASE SELECTION: {0:x}", end);
+ base_address = end;
+ continue;
+ }
+
+ if ((start == 0) && (end == 0))
+ break;
+
+ int size = reader.ReadInt16 ();
+ byte[] data = reader.ReadBuffer (size);
+
+ if ((address < base_address+start) || (address >= base_address+end))
+ continue;
+
+ return GetLocation (frame, data);
+ }
+
+ return null;
+ }
+
public override TargetObject GetObject (StackFrame frame)
{
TargetLocation location = GetLocation (frame);
@@ -3547,7 +3605,8 @@ protected abstract class DieVariableBase : Die
string name;
long type_offset;
- public DieVariableBase (DwarfBinaryReader reader, CompilationUnit comp_unit, AbbrevEntry abbrev)
+ public DieVariableBase (DwarfBinaryReader reader, CompilationUnit comp_unit,
+ AbbrevEntry abbrev)
: base (reader, comp_unit, abbrev)
{ }
@@ -3583,17 +3642,19 @@ protected override void ProcessAttribute (Attribute attribute)
protected abstract class DieMethodVariable : DieVariableBase
{
- public DieMethodVariable (DieSubprogram parent, DwarfBinaryReader reader,
- CompilationUnit comp_unit, AbbrevEntry abbrev, bool is_local)
+ public DieMethodVariable (DieSubprogram subprog, DwarfBinaryReader reader,
+ CompilationUnit comp_unit, AbbrevEntry abbrev,
+ bool is_local)
: base (reader, comp_unit, abbrev)
{
this.target_info = reader.TargetInfo;
+ this.subprog = subprog;
- if (parent != null) {
+ if (subprog != null) {
if (is_local)
- parent.AddLocal (this);
+ subprog.AddLocal (this);
else
- parent.AddParameter (this);
+ subprog.AddParameter (this);
}
}
@@ -3604,17 +3665,17 @@ protected override void ProcessAttribute (Attribute attribute)
switch (attribute.DwarfForm) {
case DwarfForm.block1:
location_block = (byte []) attribute.Data;
- use_constant = false;
break;
case DwarfForm.data1:
case DwarfForm.data2:
case DwarfForm.data4:
case DwarfForm.data8:
- location_constant = (long) attribute.Data;
- use_constant = true;
+ loclist_offset = (long) attribute.Data;
+ has_loclist = true;
break;
}
break;
+
default:
base.ProcessAttribute (attribute);
break;
@@ -3623,15 +3684,17 @@ protected override void ProcessAttribute (Attribute attribute)
byte[] location_block;
- long location_constant;
- bool use_constant;
+ long loclist_offset;
+ bool has_loclist;
TargetVariable variable;
TargetInfo target_info;
+ DieSubprogram subprog;
bool resolved;
protected bool DoResolve ()
{
- if ((TypeOffset == 0) || (!use_constant && location_block == null) || (Name == null))
+ if ((TypeOffset == 0) || (Name == null) || (subprog == null) ||
+ (!has_loclist && (location_block == null)))
return false;
DieType reference = comp_unit.GetType (TypeOffset);
@@ -3639,16 +3702,15 @@ protected bool DoResolve ()
return false;
TargetType type = reference.ResolveType ();
- if (!use_constant) {
- TargetBinaryReader locreader = new TargetBinaryReader (
- location_block, target_info);
+ if (type == null)
+ return false;
+
+ if (has_loclist)
variable = new DwarfTargetVariable (
- dwarf, Name, type, locreader);
- }
- else {
+ subprog, Name, type, loclist_offset);
+ else
variable = new DwarfTargetVariable (
- dwarf, Name, type, (int)location_constant);
- }
+ subprog, Name, type, location_block);
return true;
}
@@ -3682,7 +3744,8 @@ protected class DieVariable : DieMethodVariable
protected class DieMember : DieVariableBase
{
- public DieMember (DwarfBinaryReader reader, CompilationUnit comp_unit, AbbrevEntry abbrev)
+ public DieMember (DwarfBinaryReader reader, CompilationUnit comp_unit,
+ AbbrevEntry abbrev)
: base (reader, comp_unit, abbrev)
{
this.target_info = reader.TargetInfo;
View
26 arch/bfdglue.c
@@ -190,25 +190,9 @@ bfd_glue_disassemble_insn (disassembler_ftype dis, struct disassemble_info *info
}
gboolean
-bfd_glue_get_section_contents (bfd *abfd, asection *section, int raw_section,
- gpointer *data, guint32 *size)
+bfd_glue_get_section_contents (bfd *abfd, asection *section, gpointer data, guint32 size)
{
- gboolean retval;
-
- if (raw_section)
- *size = section->_raw_size;
- else
- *size = section->_cooked_size;
-
- *data = g_malloc0 (*size);
-
- retval = bfd_get_section_contents (abfd, section, *data, 0, *size);
- if (!retval) {
- g_free (*data);
- *data = NULL;
- }
-
- return retval;
+ return bfd_get_section_contents (abfd, section, data, 0, size);
}
asection *
@@ -235,10 +219,10 @@ bfd_glue_get_section_name (asection *p)
return g_strdup (p->name);
}
-guint64
-bfd_glue_get_section_size (asection *p)
+guint32
+bfd_glue_get_section_size (asection *p, gboolean raw_section)
{
- return p->_raw_size;
+ return raw_section ? p->_raw_size : p->_cooked_size;
}
BfdGlueSectionFlags
View
7 arch/bfdglue.h
@@ -58,8 +58,7 @@ extern int
bfd_glue_disassemble_insn (disassembler_ftype dis, struct disassemble_info *info, guint64 address);
extern gboolean
-bfd_glue_get_section_contents (bfd *abfd, asection *section, int raw_section,
- gpointer *data, guint32 *size);
+bfd_glue_get_section_contents (bfd *abfd, asection *section, gpointer data, guint32 size);
extern guint64
bfd_glue_get_section_vma (asection *p);
@@ -67,8 +66,8 @@ bfd_glue_get_section_vma (asection *p);
extern gchar *
bfd_glue_get_section_name (asection *p);
-extern guint64
-bfd_glue_get_section_size (asection *p);
+extern guint32
+bfd_glue_get_section_size (asection *p, gboolean raw_section);
extern BfdGlueSectionFlags
bfd_glue_get_section_flags (asection *p);
View
3  backends/ILanguageBackend.cs
@@ -20,7 +20,8 @@ internal enum NotificationType {
ThreadExited,
ThrowException,
HandleException,
- ReachedMain
+ ReachedMain,
+ FinalizeManagedCode
}
internal interface ILanguageBackend : IDisposable
View
32 backends/Inferior.cs
@@ -39,6 +39,7 @@ internal class Inferior : TargetMemoryAccess, ITargetNotification, IDisposable
int child_pid;
bool initialized;
bool has_target;
+ bool pushed_regs;
TargetInfo target_info;
Architecture arch;
@@ -164,6 +165,15 @@ internal class Inferior : TargetMemoryAccess, ITargetNotification, IDisposable
[DllImport("monodebuggerserver")]
static extern TargetError mono_debugger_server_init_after_fork (IntPtr handle);
+ [DllImport("monodebuggerserver")]
+ static extern TargetError mono_debugger_server_push_registers (IntPtr handle, out long new_rsp);
+
+ [DllImport("monodebuggerserver")]
+ static extern TargetError mono_debugger_server_pop_registers (IntPtr handle);
+
+ [DllImport("monodebuggerserver")]
+ static extern void mono_debugger_server_set_notification (IntPtr handle, long address);
+
internal enum ChildEventType {
NONE = 0,
UNKNOWN_ERROR = 1,
@@ -177,6 +187,7 @@ internal enum ChildEventType {
CHILD_CREATED_THREAD,
CHILD_FORKED,
CHILD_EXECD,
+ CHILD_CALLED_EXIT,
CHILD_NOTIFICATION,
UNHANDLED_EXCEPTION,
THROW_EXCEPTION,
@@ -1065,6 +1076,8 @@ public void SetSignal (int signal, bool send_it)
public void Detach ()
{
check_disposed ();
+ if (pushed_regs)
+ mono_debugger_server_pop_registers (server_handle);
check_error (mono_debugger_server_detach (server_handle));
}
@@ -1201,6 +1214,25 @@ public void InitializeAfterFork ()
breakpoint_manager.InitializeAfterFork (this);
}
+ public TargetAddress PushRegisters ()
+ {
+ long new_rsp;
+ check_error (mono_debugger_server_push_registers (server_handle, out new_rsp));
+ pushed_regs = true;
+ return new TargetAddress (AddressDomain, new_rsp);
+ }
+
+ public void PopRegisters ()
+ {
+ pushed_regs = false;
+ check_error (mono_debugger_server_pop_registers (server_handle));
+ }
+
+ internal void SetNotificationAddress (TargetAddress notification)
+ {
+ mono_debugger_server_set_notification (server_handle, notification.Address);
+ }
+
internal struct ServerStackFrame
{
public long Address;
View
19 backends/MonoThreadManager.cs
@@ -22,12 +22,10 @@ internal class MonoThreadManager
{
ThreadManager thread_manager;
MonoDebuggerInfo debugger_info;
+ TargetAddress notification_address = TargetAddress.Null;
Inferior inferior;
bool stop_in_main;
- [DllImport("monodebuggerserver")]
- static extern void mono_debugger_server_set_notification (long address);
-
public static MonoThreadManager Initialize (ThreadManager thread_manager,
Inferior inferior, bool attach,
bool stop_in_main)
@@ -79,10 +77,8 @@ internal class MonoThreadManager
protected void initialize_notifications (Inferior inferior)
{
- TargetAddress notification = inferior.ReadAddress (
- debugger_info.NotificationAddress);
-
- mono_debugger_server_set_notification (notification.Address);
+ notification_address = inferior.ReadAddress (debugger_info.NotificationAddress);
+ inferior.SetNotificationAddress (notification_address);
if (notification_bpt > 0) {
inferior.BreakpointManager.RemoveBreakpoint (inferior, notification_bpt);
@@ -135,6 +131,7 @@ protected override Breakpoint Clone ()
int index;
internal void ThreadCreated (SingleSteppingEngine sse)
{
+ sse.Inferior.SetNotificationAddress (notification_address);
if (++index < 3)
sse.SetDaemon ();
}
@@ -223,6 +220,10 @@ internal void ThreadCreated (SingleSteppingEngine sse)
0, cevent.Data1, cevent.Data2);
return false;
+ case NotificationType.FinalizeManagedCode:
+ csharp_language = null;
+ break;
+
default: {
TargetAddress data = new TargetAddress (
inferior.AddressDomain, cevent.Data1);
@@ -254,8 +255,8 @@ 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 = 56;
- public const int MaxDynamicVersion = 56;
+ public const int MinDynamicVersion = 57;
+ public const int MaxDynamicVersion = 57;
public const long DynamicMagic = 0x7aff65af4253d427;
public readonly TargetAddress NotificationAddress;
View
9 backends/ProcessServant.cs
@@ -384,7 +384,6 @@ internal void WaitForApplication ()
public void Kill ()
{
main_thread.Kill ();
- Dispose ();
}
public void Detach ()
@@ -689,6 +688,14 @@ public void DeleteEvent (Thread thread, Event handle)
return handle;
}
+ public Event InsertBreakpoint (Thread target, ThreadGroup group,
+ TargetAddress address)
+ {
+ Event handle = new Breakpoint (address.ToString (), group, address);
+ events.Add (handle.Index, handle);
+ return handle;
+ }
+
public Event InsertExceptionCatchPoint (Thread target, ThreadGroup group,
TargetType exception)
{
View
10 backends/SingleSteppingEngine.cs
@@ -1322,15 +1322,17 @@ internal override void AcquireThreadLock ()
((stop_event.Type == Inferior.ChildEventType.CHILD_SIGNALED))))
return;
+ TargetAddress new_rsp = inferior.PushRegisters ();
+
Inferior.StackFrame frame = inferior.GetCurrentFrame ();
Report.Debug (DebugFlags.Threads,
- "{0} acquired thread lock: {1} {2} {3} {4} {5}",
+ "{0} acquired thread lock: {1} {2} {3} {4}",
this, stopped, stop_event, EndStackAddress,
- frame.StackPointer, frame.Address);
+ new_rsp);
if (!EndStackAddress.IsNull)
- inferior.WriteAddress (EndStackAddress, frame.StackPointer);
+ inferior.WriteAddress (EndStackAddress, new_rsp);
}
internal override void ReleaseThreadLock ()
@@ -1341,6 +1343,8 @@ internal override void ReleaseThreadLock ()
has_thread_lock = false;
+ inferior.PopRegisters ();
+
// If the target was already stopped, there's nothing to do for us.
if (!stopped)
return;
View
45 backends/server/i386-arch.c
@@ -38,8 +38,6 @@ typedef struct
guint64 callback_argument;
} RuntimeInvokeData;
-static guint32 notification_address;
-
ArchInfo *
x86_arch_initialize (void)
{
@@ -59,12 +57,6 @@ x86_arch_finalize (ArchInfo *arch)
g_free (arch);
}
-static void
-server_ptrace_set_notification (guint64 addr)
-{
- notification_address = (guint32) addr;
-}
-
static ServerCommandError
server_ptrace_current_insn_is_bpt (ServerHandle *handle, guint32 *is_breakpoint)
{
@@ -414,7 +406,7 @@ x86_arch_child_stopped (ServerHandle *handle, int stopsig,
x86_arch_get_registers (handle);
- if (INFERIOR_REG_EIP (arch->current_regs) - 1 == notification_address) {
+ if (INFERIOR_REG_EIP (arch->current_regs) - 1 == inferior->notification_address) {
guint32 addr = (guint32) INFERIOR_REG_ESP (arch->current_regs) + 4;
guint64 data [3];
@@ -586,6 +578,41 @@ server_ptrace_set_registers (ServerHandle *handle, guint64 *values)
}
static ServerCommandError
+server_ptrace_push_registers (ServerHandle *handle, guint64 *new_esp)
+{
+ ArchInfo *arch = handle->arch;
+ ServerCommandError result;
+
+ INFERIOR_REG_ESP (arch->current_regs) -= sizeof (arch->current_regs);
+ result = _server_ptrace_set_registers (handle->inferior, &arch->current_regs);
+ if (result != COMMAND_ERROR_NONE)
+ return result;
+
+ *new_esp = INFERIOR_REG_ESP (arch->current_regs);
+
+ result = server_ptrace_write_memory (
+ handle, *new_esp, sizeof (arch->current_regs), &arch->current_regs);
+ if (result != COMMAND_ERROR_NONE)
+ return result;
+
+ return COMMAND_ERROR_NONE;
+}
+
+static ServerCommandError
+server_ptrace_pop_registers (ServerHandle *handle)
+{
+ ArchInfo *arch = handle->arch;
+ ServerCommandError result;
+
+ INFERIOR_REG_ESP (arch->current_regs) += sizeof (arch->current_regs);
+ result = _server_ptrace_set_registers (handle->inferior, &arch->current_regs);
+ if (result != COMMAND_ERROR_NONE)
+ return result;
+
+ return COMMAND_ERROR_NONE;
+}
+
+static ServerCommandError
do_enable (ServerHandle *handle, BreakpointInfo *breakpoint)
{
ServerCommandError result;
View
22 backends/server/library.c
@@ -362,10 +362,10 @@ mono_debugger_server_get_signal_info (ServerHandle *handle, SignalInfo **sinfo)
}
void
-mono_debugger_server_set_notification (guint64 notification)
+mono_debugger_server_set_notification (ServerHandle *handle, guint64 notification)
{
if (global_vtable->set_notification)
- return (* global_vtable->set_notification) (notification);
+ return (* global_vtable->set_notification) (handle,notification);
}
ServerCommandError
@@ -396,6 +396,24 @@ mono_debugger_server_init_after_fork (ServerHandle *handle)
return (* global_vtable->init_after_fork) (handle);
}
+ServerCommandError
+mono_debugger_server_push_registers (ServerHandle *handle, guint64 *new_rsp)
+{
+ if (!global_vtable->push_registers)
+ return COMMAND_ERROR_NOT_IMPLEMENTED;
+
+ return (* global_vtable->push_registers) (handle, new_rsp);
+}
+
+ServerCommandError
+mono_debugger_server_pop_registers (ServerHandle *handle)
+{
+ if (!global_vtable->pop_registers)
+ return COMMAND_ERROR_NOT_IMPLEMENTED;
+
+ return (* global_vtable->pop_registers) (handle);
+}
+
static gboolean initialized = FALSE;
static sem_t manager_semaphore;
static int pending_sigint = 0;
View
19 backends/server/server.h
@@ -43,6 +43,7 @@ typedef enum {
MESSAGE_CHILD_CREATED_THREAD,
MESSAGE_CHILD_FORKED,
MESSAGE_CHILD_EXECD,
+ MESSAGE_CHILD_CALLED_EXIT,
MESSAGE_CHILD_NOTIFICATION
} ServerStatusMessageType;
@@ -308,7 +309,8 @@ struct InferiorVTable {
ServerCommandError (* get_signal_info) (ServerHandle *handle,
SignalInfo **sinfo);
- void (* set_notification) (guint64 notification);
+ void (* set_notification) (ServerHandle *handle,
+ guint64 notification);
ServerCommandError (* get_threads) (ServerHandle *handle,
guint32 *count,
@@ -321,6 +323,11 @@ struct InferiorVTable {
gchar **cmdline_args);
ServerCommandError (* init_after_fork) (ServerHandle *handle);
+
+ ServerCommandError (* push_registers) (ServerHandle *handle,
+ guint64 *new_rsp);
+
+ ServerCommandError (* pop_registers) (ServerHandle *handle);
};
/*
@@ -500,7 +507,8 @@ mono_debugger_server_get_signal_info (ServerHandle *handle,
SignalInfo **sinfo);
void
-mono_debugger_server_set_notification (guint64 notification);
+mono_debugger_server_set_notification (ServerHandle *handle,
+ guint64 notification);
ServerCommandError
mono_debugger_server_get_threads (ServerHandle *handle,
@@ -517,6 +525,13 @@ mono_debugger_server_get_application (ServerHandle *handle,
ServerCommandError
mono_debugger_server_init_after_fork (ServerHandle *handle);
+ServerCommandError
+mono_debugger_server_push_registers (ServerHandle *handle,
+ guint64 *new_rsp);
+
+ServerCommandError
+mono_debugger_server_pop_registers (ServerHandle *handle);
+
/* POSIX semaphores */
void mono_debugger_server_sem_init (void);
View
2  backends/server/x86-linux-ptrace.c
@@ -130,7 +130,7 @@ do_wait (int pid, guint32 *status)
#endif
ret = waitpid (pid, status, WUNTRACED | __WALL | __WCLONE);
#if DEBUG_WAIT
- g_message (G_STRLOC ": do_wait (%d) finished: %d - %x", pid, ret, status);
+ g_message (G_STRLOC ": do_wait (%d) finished: %d - %x", pid, ret, *status);
#endif
if (ret < 0) {
if (errno == EINTR)
View
24 backends/server/x86-ptrace.c
@@ -53,6 +53,7 @@ struct InferiorHandle
int last_signal;
int output_fd [2], error_fd [2];
int is_thread, is_initialized;
+ guint64 notification_address;
};
typedef struct
@@ -202,6 +203,19 @@ server_ptrace_dispatch_event (ServerHandle *handle, guint32 status, guint64 *arg
case PTRACE_EVENT_EXEC:
return MESSAGE_CHILD_EXECD;
+ case PTRACE_EVENT_EXIT: {
+ int exitcode;
+
+ if (ptrace (PTRACE_GETEVENTMSG, handle->inferior->pid, 0, &exitcode)) {
+ g_warning (G_STRLOC ": %d - %s", handle->inferior->pid,
+ g_strerror (errno));
+ return FALSE;
+ }
+
+ *arg = 0;
+ return MESSAGE_CHILD_CALLED_EXIT;
+ }
+
default:
g_warning (G_STRLOC ": Received unknown wait result %x on child %d",
status, handle->inferior->pid);
@@ -467,6 +481,12 @@ server_ptrace_set_signal (ServerHandle *handle, guint32 sig, guint32 send_it)
return COMMAND_ERROR_NONE;
}
+static void
+server_ptrace_set_notification (ServerHandle *handle, guint64 addr)
+{
+ handle->inferior->notification_address = addr;
+}
+
extern void GC_start_blocking (void);
extern void GC_end_blocking (void);
@@ -526,5 +546,7 @@ InferiorVTable i386_ptrace_inferior = {
server_ptrace_set_notification,
server_ptrace_get_threads,
server_ptrace_get_application,
- server_ptrace_init_after_fork
+ server_ptrace_init_after_fork,
+ server_ptrace_push_registers,
+ server_ptrace_pop_registers
};
View
45 backends/server/x86_64-arch.c
@@ -38,8 +38,6 @@ typedef struct
guint64 callback_argument;
} RuntimeInvokeData;
-static guint64 notification_address;
-
ArchInfo *
x86_arch_initialize (void)
{
@@ -59,12 +57,6 @@ x86_arch_finalize (ArchInfo *arch)
g_free (arch);
}
-static void
-server_ptrace_set_notification (guint64 addr)
-{
- notification_address = addr;
-}
-
static ServerCommandError
server_ptrace_current_insn_is_bpt (ServerHandle *handle, guint32 *is_breakpoint)
{
@@ -177,7 +169,7 @@ x86_arch_child_stopped (ServerHandle *handle, int stopsig,
x86_arch_get_registers (handle);
- if (INFERIOR_REG_RIP (arch->current_regs) - 1 == notification_address) {
+ if (INFERIOR_REG_RIP (arch->current_regs) - 1 == inferior->notification_address) {
*callback_arg = INFERIOR_REG_RDI (arch->current_regs);
*retval = INFERIOR_REG_RSI (arch->current_regs);
*retval2 = INFERIOR_REG_RDX (arch->current_regs);
@@ -361,6 +353,41 @@ server_ptrace_set_registers (ServerHandle *handle, guint64 *values)
}
static ServerCommandError
+server_ptrace_push_registers (ServerHandle *handle, guint64 *new_rsp)
+{
+ ArchInfo *arch = handle->arch;
+ ServerCommandError result;
+
+ INFERIOR_REG_RSP (arch->current_regs) -= sizeof (arch->current_regs);
+ result = _server_ptrace_set_registers (handle->inferior, &arch->current_regs);
+ if (result != COMMAND_ERROR_NONE)
+ return result;
+
+ *new_rsp = INFERIOR_REG_RSP (arch->current_regs);
+
+ result = server_ptrace_write_memory (
+ handle, *new_rsp, sizeof (arch->current_regs), &arch->current_regs);
+ if (result != COMMAND_ERROR_NONE)
+ return result;
+
+ return COMMAND_ERROR_NONE;
+}
+
+static ServerCommandError
+server_ptrace_pop_registers (ServerHandle *handle)
+{
+ ArchInfo *arch = handle->arch;
+ ServerCommandError result;
+
+ INFERIOR_REG_RSP (arch->current_regs) += sizeof (arch->current_regs);
+ result = _server_ptrace_set_registers (handle->inferior, &arch->current_regs);
+ if (result != COMMAND_ERROR_NONE)
+ return result;
+
+ return COMMAND_ERROR_NONE;
+}
+
+static ServerCommandError
do_enable (ServerHandle *handle, BreakpointInfo *breakpoint)
{
ServerCommandError result;
View
6 classes/Process.cs
@@ -173,6 +173,12 @@ public void DeleteEvent (Thread thread, Event handle)
}
public Event InsertBreakpoint (Thread target, ThreadGroup group,
+ TargetAddress address)
+ {
+ return servant.InsertBreakpoint (target, group, address);
+ }
+
+ public Event InsertBreakpoint (Thread target, ThreadGroup group,
TargetFunctionType func)
{
return servant.InsertBreakpoint (target, group, func);
View
15 configure.in
@@ -216,6 +216,21 @@ AC_CHECK_FUNCS(strlcpy strlcat)
CHECK_READLINE
+AC_MSG_CHECKING([Whether your Mono is working])
+old_CFLAGS=$cflags
+CFLAGS=$WRAPPER_CFLAGS
+AC_TRY_COMPILE([#include <mono/metadata/mono-debug.h>
+], [
+#if MONO_DEBUGGER_VERSION < 57
+#error "Your mono is too old for this version of the debugger."
+#endif
+], mono_working=yes, mono_working=no)
+AC_MSG_RESULT($mono_working)
+CFLAGS=$old_CFLAGS
+if test x$mono_working != xyes; then
+ AC_MSG_ERROR([*** Your Mono is too old for this version of the debugger.])
+fi
+
AM_CONDITIONAL(DISABLED, false)
AC_OUTPUT([
View
68 frontend/Command.cs
@@ -1,3 +1,4 @@
+
using System;
using System.Text;
using System.IO;
@@ -2025,15 +2026,21 @@ protected override bool DoResolve (ScriptingContext context)
} catch {
}
- Expression expr = ParseExpression (context);
- if (expr == null)
- return false;
+ MethodExpression mexpr;
+ try {
+ Expression expr = ParseExpression (context);
+ if (expr == null)
+ return false;
- MethodExpression mexpr = expr.ResolveMethod (context, type);
- if (mexpr == null)
- return false;
+ mexpr = expr.ResolveMethod (context, type);
+ } catch {
+ mexpr = null;
+ }
- location = mexpr.EvaluateSource (context);
+ if (mexpr != null)
+ location = mexpr.EvaluateSource (context);
+ else
+ location = context.FindMethod (Argument);
return location != null;
}
}
@@ -2077,7 +2084,7 @@ protected override object DoExecute (ScriptingContext context)
source_code = buffer.Contents;
if (Location.HasMethod && !Location.HasLine)
- count = Location.Method.EndRow - Location.Method.StartRow + 2;
+ count = Location.Method.EndRow - Location.Method.StartRow + 4;
if (count < 0)
last_line = System.Math.Max (Location.Line + 2, 0);
@@ -2132,14 +2139,21 @@ protected override object DoExecute (ScriptingContext context)
public class BreakCommand : SourceCommand, IDocumentableCommand
{
string group;
+ bool global;
int domain = 0;
ThreadGroup tgroup;
+ TargetAddress address = TargetAddress.Null;
public string Group {
get { return group; }
set { group = value; }
}
+ public bool Global {
+ get { return global; }
+ set { global = value; }
+ }
+
public int Domain {
get { return domain; }
set { domain = value; }
@@ -2147,17 +2161,45 @@ public class BreakCommand : SourceCommand, IDocumentableCommand
protected override bool DoResolve (ScriptingContext context)
{
+ if (global) {
+ if (Group != null)
+ throw new ScriptingException (
+ "Cannot use both -group and -global.");
+
+ tgroup = ThreadGroup.Global;
+ } else {
+ tgroup = context.Interpreter.GetThreadGroup (Group, false);
+ }
+
bool resolved = base.DoResolve (context);
- if (!resolved)
- throw new ScriptingException ("No such method: `{0}'", Argument);
+ if (resolved)
+ return true;
- tgroup = context.Interpreter.GetThreadGroup (Group, false);
- return true;
+ try {
+ PointerExpression pexpr = ParseExpression (context) as PointerExpression;
+ if (pexpr != null) {
+ address = pexpr.EvaluateAddress (context);
+ return true;
+ }
+ } catch {
+ }
+
+ throw new ScriptingException ("No such method: `{0}'", Argument);
}
protected override object DoExecute (ScriptingContext context)
{
- if (Location.HasFunction) {
+ if (!address.IsNull) {
+ if (domain != 0)
+ throw new ScriptingException (
+ "Can't specifcy an appdomain when inserting a " +
+ "breakpoint on an address");
+
+ int index = context.Interpreter.InsertBreakpoint (
+ context.CurrentThread, tgroup, address);
+ context.Print ("Breakpoint {0} at {1}", index, address);
+ return index;
+ } else if (Location.HasFunction) {
if (domain != 0)
throw new ScriptingException (
"Can't insert function breakpoints in " +
View
9 frontend/Interpreter.cs
@@ -663,6 +663,15 @@ public void RemoveFromThreadGroup (string name, Thread[] threads)
}
public int InsertBreakpoint (Thread target, ThreadGroup group,
+ TargetAddress address)
+ {
+ Event handle = target.Process.InsertBreakpoint (
+ target, group, address);
+ handle.Enable (target);
+ return handle.Index;
+ }
+
+ public int InsertBreakpoint (Thread target, ThreadGroup group,
TargetFunctionType func)
{
Event handle = target.Process.InsertBreakpoint (target, group, func);
View
3  test/src/TestChild.cs
@@ -2,8 +2,9 @@
class X
{
- static void Main ()
+ static int Main ()
{
Console.WriteLine ("Hello World");
+ return 0;
}
}
View
2  test/src/TestExec.cs
@@ -9,6 +9,8 @@ static int Main (string[] args)
Array.Copy (args, 1, new_args, 0, args.Length - 1);
Process process = Process.Start (args [0], String.Join (" ", new_args));
process.WaitForExit ();
+ if (process.ExitCode != 0)
+ Console.WriteLine ("ERROR: {0}", process.ExitCode);
return process.ExitCode;
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.