summaryrefslogtreecommitdiff
path: root/mcs/class/Mono.Debugger.Soft
diff options
context:
space:
mode:
Diffstat (limited to 'mcs/class/Mono.Debugger.Soft')
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs39
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ExceptionEventRequest.cs17
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs20
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StepEventRequest.cs4
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs14
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs58
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDeathEvent.cs13
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs18
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs3
-rw-r--r--mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs77
-rw-r--r--mcs/class/Mono.Debugger.Soft/Test/dtest.cs205
11 files changed, 364 insertions, 104 deletions
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
index 105ff4fb67..13096f0594 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
@@ -93,6 +93,7 @@ namespace Mono.Debugger.Soft
public long catch_type_id;
}
+ [Flags]
enum ExceptionClauseFlags {
None = 0x0,
Filter = 0x1,
@@ -149,6 +150,7 @@ namespace Mono.Debugger.Soft
VALUE_TYPE_ID_TYPE = 0xf1
}
+ [Flags]
enum InvokeFlags {
NONE = 0x0,
DISABLE_BREAKPOINTS = 0x1,
@@ -220,6 +222,7 @@ namespace Mono.Debugger.Soft
UNKNOWN = 4
}
+ [Flags]
enum StackFrameFlags {
NONE = 0,
DEBUGGER_INVOKE = 1,
@@ -285,6 +288,9 @@ namespace Mono.Debugger.Soft
public bool Uncaught {
get; set;
}
+ public bool Subclasses {
+ get; set;
+ }
}
class AssemblyModifier : Modifier {
@@ -342,6 +348,10 @@ namespace Mono.Debugger.Soft
get; set;
}
+ public int ExitCode {
+ get; set;
+ }
+
public EventInfo (EventType type, int req_id) {
EventType = type;
ReqId = req_id;
@@ -395,7 +405,7 @@ namespace Mono.Debugger.Soft
* with newer runtimes, and vice versa.
*/
internal const int MAJOR_VERSION = 2;
- internal const int MINOR_VERSION = 24;
+ internal const int MINOR_VERSION = 27;
enum WPSuspendPolicy {
NONE = 0,
@@ -546,6 +556,7 @@ namespace Mono.Debugger.Soft
IS_INITIALIZED = 18
}
+ [Flags]
enum BindingFlagsExtensions {
BINDING_FLAGS_IGNORE_CASE = 0x70000000,
}
@@ -1218,82 +1229,71 @@ namespace Mono.Debugger.Soft
EventType etype = (EventType)kind;
+ long thread_id = r.ReadId ();
if (kind == EventKind.VM_START) {
- long thread_id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id };
//EventHandler.VMStart (req_id, thread_id, null);
} else if (kind == EventKind.VM_DEATH) {
+ int exit_code = 0;
+ if (Version.AtLeast (2, 27))
+ exit_code = r.ReadInt ();
//EventHandler.VMDeath (req_id, 0, null);
- events [i] = new EventInfo (etype, req_id) { };
+ events [i] = new EventInfo (etype, req_id) { ExitCode = exit_code };
} else if (kind == EventKind.THREAD_START) {
- long thread_id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
//EventHandler.ThreadStart (req_id, thread_id, thread_id);
} else if (kind == EventKind.THREAD_DEATH) {
- long thread_id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
//EventHandler.ThreadDeath (req_id, thread_id, thread_id);
} else if (kind == EventKind.ASSEMBLY_LOAD) {
- long thread_id = r.ReadId ();
long id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
//EventHandler.AssemblyLoad (req_id, thread_id, id);
} else if (kind == EventKind.ASSEMBLY_UNLOAD) {
- long thread_id = r.ReadId ();
long id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
//EventHandler.AssemblyUnload (req_id, thread_id, id);
} else if (kind == EventKind.TYPE_LOAD) {
- long thread_id = r.ReadId ();
long id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
//EventHandler.TypeLoad (req_id, thread_id, id);
} else if (kind == EventKind.METHOD_ENTRY) {
- long thread_id = r.ReadId ();
long id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
//EventHandler.MethodEntry (req_id, thread_id, id);
} else if (kind == EventKind.METHOD_EXIT) {
- long thread_id = r.ReadId ();
long id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
//EventHandler.MethodExit (req_id, thread_id, id);
} else if (kind == EventKind.BREAKPOINT) {
- long thread_id = r.ReadId ();
long id = r.ReadId ();
long loc = r.ReadLong ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
//EventHandler.Breakpoint (req_id, thread_id, id, loc);
} else if (kind == EventKind.STEP) {
- long thread_id = r.ReadId ();
long id = r.ReadId ();
long loc = r.ReadLong ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
//EventHandler.Step (req_id, thread_id, id, loc);
} else if (kind == EventKind.EXCEPTION) {
- long thread_id = r.ReadId ();
long id = r.ReadId ();
long loc = 0; // FIXME
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
//EventHandler.Exception (req_id, thread_id, id, loc);
} else if (kind == EventKind.APPDOMAIN_CREATE) {
- long thread_id = r.ReadId ();
long id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
//EventHandler.AppDomainCreate (req_id, thread_id, id);
} else if (kind == EventKind.APPDOMAIN_UNLOAD) {
- long thread_id = r.ReadId ();
long id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
//EventHandler.AppDomainUnload (req_id, thread_id, id);
} else if (kind == EventKind.USER_BREAK) {
- long thread_id = r.ReadId ();
long id = 0;
long loc = 0;
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
//EventHandler.Exception (req_id, thread_id, id, loc);
} else if (kind == EventKind.USER_LOG) {
- long thread_id = r.ReadId ();
int level = r.ReadInt ();
string category = r.ReadString ();
string message = r.ReadString ();
@@ -2174,6 +2174,11 @@ namespace Mono.Debugger.Soft
} else if (!em.Caught || !em.Uncaught) {
throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
}
+ if (Version.MajorVersion > 2 || Version.MinorVersion > 24) {
+ w.WriteBool (em.Subclasses);
+ } else if (!em.Subclasses) {
+ throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
+ }
} else if (mod is AssemblyModifier) {
w.WriteByte ((byte)ModifierKind.ASSEMBLY_ONLY);
var amod = (mod as AssemblyModifier);
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ExceptionEventRequest.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ExceptionEventRequest.cs
index 07d4d8ccdd..906b43fd83 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ExceptionEventRequest.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ExceptionEventRequest.cs
@@ -6,7 +6,7 @@ namespace Mono.Debugger.Soft
public sealed class ExceptionEventRequest : EventRequest {
TypeMirror exc_type;
- bool caught, uncaught;
+ bool caught, uncaught, subclasses;
internal ExceptionEventRequest (VirtualMachine vm, TypeMirror exc_type, bool caught, bool uncaught) : base (vm, EventType.Exception) {
if (exc_type != null) {
@@ -18,6 +18,7 @@ namespace Mono.Debugger.Soft
this.exc_type = exc_type;
this.caught = caught;
this.uncaught = uncaught;
+ this.subclasses = true;
}
public TypeMirror ExceptionType {
@@ -26,9 +27,21 @@ namespace Mono.Debugger.Soft
}
}
+ // Defaults to true
+ // Supported since protocol version 2.25
+ public bool IncludeSubclasses {
+ get {
+ return subclasses;
+ }
+ set {
+ vm.CheckProtocolVersion (2, 25);
+ subclasses = value;
+ }
+ }
+
public override void Enable () {
var mods = new List <Modifier> ();
- mods.Add (new ExceptionModifier () { Type = exc_type != null ? exc_type.Id : 0, Caught = caught, Uncaught = uncaught });
+ mods.Add (new ExceptionModifier () { Type = exc_type != null ? exc_type.Id : 0, Caught = caught, Uncaught = uncaught, Subclasses = subclasses });
SendReq (mods);
}
}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs
index 18611ba327..8a060a2df9 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs
@@ -2,6 +2,9 @@ using System;
using System.Collections.Generic;
using System.Runtime.Remoting.Messaging;
using System.Threading;
+#if NET_4_5
+using System.Threading.Tasks;
+#endif
namespace Mono.Debugger.Soft
{
@@ -144,6 +147,23 @@ namespace Mono.Debugger.Soft
return EndInvokeMethodInternal (asyncResult);
}
+#if NET_4_5
+ public Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) {
+ var tcs = new TaskCompletionSource<Value> ();
+ BeginInvokeMethod (thread, method, arguments, options, iar =>
+ {
+ try {
+ tcs.SetResult (EndInvokeMethod (iar));
+ } catch (OperationCanceledException) {
+ tcs.TrySetCanceled ();
+ } catch (Exception ex) {
+ tcs.TrySetException (ex);
+ }
+ }, null);
+ return tcs.Task;
+ }
+#endif
+
//
// Invoke the members of METHODS one-by-one, calling CALLBACK after each invoke was finished. The IAsyncResult will be marked as completed after all invokes have
// finished. The callback will be called with a different IAsyncResult that represents one method invocation.
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StepEventRequest.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StepEventRequest.cs
index cb3c79231b..035fbcee56 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StepEventRequest.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StepEventRequest.cs
@@ -23,7 +23,11 @@ namespace Mono.Debugger.Soft
StaticCtor = 1,
/* Since protocol version 2.20 */
/* Methods which have the [DebuggerHidden] attribute */
+ /* Before protocol version 2.26, this includes [DebuggerStepThrough] as well */
DebuggerHidden = 2,
+ /* Since protocol version 2.26 */
+ /* Methods which have the [DebuggerStepThrough] attribute */
+ DebuggerStepThrough = 4,
}
public sealed class StepEventRequest : EventRequest {
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs
index 1db6037972..7307b0ea89 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs
@@ -41,6 +41,20 @@ namespace Mono.Debugger.Soft
}
throw new ArgumentException ("Unknown struct field '" + field + "'.", "field");
}
+ set {
+ FieldInfoMirror[] field_info = Type.GetFields ();
+ int nf = 0;
+ for (int i = 0; i < field_info.Length; ++i) {
+ if (!field_info [i].IsStatic) {
+ if (field_info [i].Name == field) {
+ fields [nf] = value;
+ return;
+ }
+ nf++;
+ }
+ }
+ throw new ArgumentException ("Unknown struct field '" + field + "'.", "field");
+ }
}
internal void SetField (int index, Value value) {
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs
index 3cd1edeadf..e7baa44fae 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs
@@ -3,6 +3,9 @@ using System.Collections.Generic;
using System.Reflection;
using C = Mono.Cecil;
using Mono.Cecil.Metadata;
+#if NET_4_5
+using System.Threading.Tasks;
+#endif
namespace Mono.Debugger.Soft
{
@@ -26,6 +29,7 @@ namespace Mono.Debugger.Soft
TypeMirror[] ifaces;
Dictionary<TypeMirror, InterfaceMappingMirror> iface_map;
TypeMirror[] type_args;
+ bool cached_base_type;
bool inited;
internal const BindingFlags DefaultBindingFlags =
@@ -78,9 +82,9 @@ namespace Mono.Debugger.Soft
public TypeMirror BaseType {
get {
- // FIXME: base_type could be null for object/interfaces
- if (base_type == null) {
+ if (!cached_base_type) {
base_type = vm.GetType (GetInfo ().base_type);
+ cached_base_type = true;
}
return base_type;
}
@@ -591,11 +595,11 @@ namespace Mono.Debugger.Soft
string[] source_files;
string[] source_files_full_path;
- public string[] GetSourceFiles (bool return_full_paths) {
- string[] res = return_full_paths ? source_files_full_path : source_files;
+ public string[] GetSourceFiles (bool returnFullPaths) {
+ string[] res = returnFullPaths ? source_files_full_path : source_files;
if (res == null) {
- res = vm.conn.Type_GetSourceFiles (id, return_full_paths);
- if (return_full_paths)
+ res = vm.conn.Type_GetSourceFiles (id, returnFullPaths);
+ if (returnFullPaths)
source_files_full_path = res;
else
source_files = res;
@@ -684,29 +688,38 @@ namespace Mono.Debugger.Soft
* used by the reflection-only functionality on .net.
*/
public CustomAttributeDataMirror[] GetCustomAttributes (bool inherit) {
- return GetCAttrs (null, inherit);
+ return GetCustomAttrs (null, inherit);
}
public CustomAttributeDataMirror[] GetCustomAttributes (TypeMirror attributeType, bool inherit) {
if (attributeType == null)
throw new ArgumentNullException ("attributeType");
- return GetCAttrs (attributeType, inherit);
+ return GetCustomAttrs (attributeType, inherit);
}
- CustomAttributeDataMirror[] GetCAttrs (TypeMirror type, bool inherit) {
+ void AppendCustomAttrs (IList<CustomAttributeDataMirror> attrs, TypeMirror type, bool inherit)
+ {
if (cattrs == null && Metadata != null && !Metadata.HasCustomAttributes)
cattrs = new CustomAttributeDataMirror [0];
- // FIXME: Handle inherit
if (cattrs == null) {
CattrInfo[] info = vm.conn.Type_GetCustomAttributes (id, 0, false);
cattrs = CustomAttributeDataMirror.Create (vm, info);
}
- var res = new List<CustomAttributeDataMirror> ();
- foreach (var attr in cattrs)
+
+ foreach (var attr in cattrs) {
if (type == null || attr.Constructor.DeclaringType == type)
- res.Add (attr);
- return res.ToArray ();
+ attrs.Add (attr);
+ }
+
+ if (inherit && BaseType != null)
+ BaseType.AppendCustomAttrs (attrs, type, inherit);
+ }
+
+ CustomAttributeDataMirror[] GetCustomAttrs (TypeMirror type, bool inherit) {
+ var attrs = new List<CustomAttributeDataMirror> ();
+ AppendCustomAttrs (attrs, type, inherit);
+ return attrs.ToArray ();
}
public MethodMirror[] GetMethodsByNameFlags (string name, BindingFlags flags, bool ignoreCase) {
@@ -785,6 +798,23 @@ namespace Mono.Debugger.Soft
return ObjectMirror.EndInvokeMethodInternal (asyncResult);
}
+#if NET_4_5
+ public Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) {
+ var tcs = new TaskCompletionSource<Value> ();
+ BeginInvokeMethod (thread, method, arguments, options, iar =>
+ {
+ try {
+ tcs.SetResult (EndInvokeMethod (iar));
+ } catch (OperationCanceledException) {
+ tcs.TrySetCanceled ();
+ } catch (Exception ex) {
+ tcs.TrySetException (ex);
+ }
+ }, null);
+ return tcs.Task;
+ }
+#endif
+
public Value NewInstance (ThreadMirror thread, MethodMirror method, IList<Value> arguments) {
return ObjectMirror.InvokeMethod (vm, thread, method, null, arguments, InvokeOptions.None);
}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDeathEvent.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDeathEvent.cs
index 18eeb92ca7..40e60ad091 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDeathEvent.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDeathEvent.cs
@@ -4,7 +4,18 @@ namespace Mono.Debugger.Soft
{
public class VMDeathEvent : Event
{
- public VMDeathEvent (VirtualMachine vm, int req_id) : base (EventType.VMDeath, vm, req_id, -1) {
+ int exit_code;
+
+ public VMDeathEvent (VirtualMachine vm, int req_id, int exit_code) : base (EventType.VMDeath, vm, req_id, -1) {
+ this.exit_code = exit_code;
+ }
+
+ // Since protocol version 2.27
+ public int ExitCode {
+ get {
+ vm.CheckProtocolVersion (2, 27);
+ return exit_code;
+ }
}
}
}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
index b77458b441..cb2cafdb71 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
@@ -137,7 +137,7 @@ namespace Mono.Debugger.Soft
public void Detach () {
conn.VM_Dispose ();
conn.Close ();
- notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, 0, 0, null);
+ notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, 0, 0, null, 0);
}
[Obsolete ("This method was poorly named; use the Detach() method instead")]
@@ -227,10 +227,14 @@ namespace Mono.Debugger.Soft
}
public void EnableEvents (params EventType[] events) {
+ EnableEvents (events, SuspendPolicy.All);
+ }
+
+ public void EnableEvents (EventType[] events, SuspendPolicy suspendPolicy) {
foreach (EventType etype in events) {
if (etype == EventType.Breakpoint)
throw new ArgumentException ("Breakpoint events cannot be requested using EnableEvents", "events");
- conn.EnableEvent (etype, SuspendPolicy.All, null);
+ conn.EnableEvent (etype, suspendPolicy, null);
}
}
@@ -315,7 +319,7 @@ namespace Mono.Debugger.Soft
root_domain = GetDomain (root_domain_id);
}
- internal void notify_vm_event (EventType evtype, SuspendPolicy spolicy, int req_id, long thread_id, string vm_uri) {
+ internal void notify_vm_event (EventType evtype, SuspendPolicy spolicy, int req_id, long thread_id, string vm_uri, int exit_code) {
//Console.WriteLine ("Event: " + evtype + "(" + vm_uri + ")");
switch (evtype) {
@@ -327,7 +331,7 @@ namespace Mono.Debugger.Soft
queue_event_set (new EventSet (this, spolicy, new Event[] { new VMStartEvent (vm, req_id, thread_id) }));
break;
case EventType.VMDeath:
- queue_event_set (new EventSet (this, spolicy, new Event[] { new VMDeathEvent (vm, req_id) }));
+ queue_event_set (new EventSet (this, spolicy, new Event[] { new VMDeathEvent (vm, req_id, exit_code) }));
break;
case EventType.VMDisconnect:
queue_event_set (new EventSet (this, spolicy, new Event[] { new VMDisconnectEvent (vm, req_id) }));
@@ -620,10 +624,10 @@ namespace Mono.Debugger.Soft
switch (ei.EventType) {
case EventType.VMStart:
- vm.notify_vm_event (EventType.VMStart, suspend_policy, req_id, thread_id, null);
+ vm.notify_vm_event (EventType.VMStart, suspend_policy, req_id, thread_id, null, 0);
break;
case EventType.VMDeath:
- vm.notify_vm_event (EventType.VMDeath, suspend_policy, req_id, thread_id, null);
+ vm.notify_vm_event (EventType.VMDeath, suspend_policy, req_id, thread_id, null, ei.ExitCode);
break;
case EventType.ThreadStart:
l.Add (new ThreadStartEvent (vm, req_id, id));
@@ -677,7 +681,7 @@ namespace Mono.Debugger.Soft
}
public void VMDisconnect (int req_id, long thread_id, string vm_uri) {
- vm.notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, req_id, thread_id, vm_uri);
+ vm.notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, req_id, thread_id, vm_uri, 0);
}
}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs
index a5bdf4fc39..211a0df302 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs
@@ -93,7 +93,8 @@ namespace Mono.Debugger.Soft
if (options != null && options.Valgrind)
info.FileName = "valgrind";
-
+ info.UseShellExecute = false;
+
ITargetProcess p;
if (options != null && options.CustomProcessLauncher != null)
p = new ProcessWrapper (options.CustomProcessLauncher (info));
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
index 7cf688c0d2..e1d912ec4e 100644
--- a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
+++ b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
@@ -132,6 +132,13 @@ public struct GStruct<T> {
}
}
+public struct NestedStruct {
+ NestedInner nested1, nested2;
+}
+
+public struct NestedInner {
+}
+
interface ITest
{
void Foo ();
@@ -202,6 +209,7 @@ public class Tests : TestsBase, ITest2
[ThreadStatic]
public static int tls_i;
public static bool is_attached = Debugger.IsAttached;
+ public NestedStruct nested_struct;
#pragma warning restore 0414
@@ -349,7 +357,10 @@ public class Tests : TestsBase, ITest2
} catch {
}
ss7 ();
+ ss_nested ();
ss_regress_654694 ();
+ ss_step_through ();
+ ss_recursive (1);
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
@@ -424,6 +435,57 @@ public class Tests : TestsBase, ITest2
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_nested () {
+ ss_nested_1 (ss_nested_2 ());
+ ss_nested_1 (ss_nested_2 ());
+ ss_nested_3 ();
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_nested_1 (int i) {
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static int ss_nested_2 () {
+ return 0;
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_nested_3 () {
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_step_through () {
+ step_through_1 ();
+ StepThroughClass.step_through_2 ();
+ step_through_3 ();
+ }
+
+ [DebuggerStepThrough]
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void step_through_1 () {
+ }
+
+ [DebuggerStepThrough]
+ class StepThroughClass {
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void step_through_2 () {
+ }
+ }
+
+ [DebuggerStepThrough]
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void step_through_3 () {
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_recursive (int n) {
+ if (n == 10)
+ return;
+ ss_recursive (n + 1);
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
public static bool is_even (int i) {
return i % 2 == 0;
}
@@ -535,8 +597,9 @@ public class Tests : TestsBase, ITest2
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public static void locals () {
string s = null;
+ var astruct = new AStruct () { i = 42 };
locals1 (null);
- locals2<string> (null, 5, "ABC", ref s);
+ locals2<string> (null, 5, "ABC", ref s, ref astruct);
locals3 ();
locals6 ();
locals7<int> (22);
@@ -562,7 +625,7 @@ public class Tests : TestsBase, ITest2
#if NET_4_5
[StateMachine (typeof (int))]
#endif
- public static void locals2<T> (string[] args, int arg, T t, ref string rs) {
+ public static void locals2<T> (string[] args, int arg, T t, ref string rs, ref AStruct astruct) {
long i = 42;
string s = "AB";
@@ -571,6 +634,7 @@ public class Tests : TestsBase, ITest2
i ++;
if (t != null)
i ++;
+ astruct = new AStruct ();
}
rs = "A";
}
@@ -840,6 +904,15 @@ public class Tests : TestsBase, ITest2
throw new OverflowException ();
} catch (Exception) {
}
+ // no subclasses
+ try {
+ throw new OverflowException ();
+ } catch (Exception) {
+ }
+ try {
+ throw new Exception ();
+ } catch (Exception) {
+ }
object o = null;
try {
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
index c8302274db..cc13107513 100644
--- a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
+++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
@@ -105,7 +105,7 @@ public class DebuggerTests
MethodMirror m = entry_point.DeclaringType.GetMethod (name);
Assert.IsNotNull (m);
//Console.WriteLine ("X: " + name + " " + m.ILOffsets.Count + " " + m.Locations.Count);
- vm.SetBreakpoint (m, m.ILOffsets [0]);
+ var req = vm.SetBreakpoint (m, m.ILOffsets [0]);
Event e = null;
@@ -116,6 +116,8 @@ public class DebuggerTests
break;
}
+ req.Disable ();
+
Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
@@ -375,15 +377,19 @@ public class DebuggerTests
Assert.AreEqual (method, (e as StepEvent).Method.Name);
}
+ StepEventRequest create_step (Event e) {
+ var req = vm.CreateStepRequest (e.Thread);
+ step_req = req;
+ return req;
+ }
+
[Test]
public void SingleStepping () {
Event e = run_until ("single_stepping");
- var req = vm.CreateStepRequest (e.Thread);
+ var req = create_step (e);
req.Enable ();
- step_req = req;
-
// Step over 'bool b = true'
e = step_once ();
assert_location (e, "single_stepping");
@@ -402,49 +408,24 @@ public class DebuggerTests
e = step_once ();
assert_location (e, "single_stepping");
- // Change to step over
- req.Disable ();
- req.Depth = StepDepth.Over;
- req.Enable ();
-
// Step over ss2
- e = step_once ();
+ e = step_over ();
assert_location (e, "single_stepping");
- // Change to step into
- req.Disable ();
- req.Depth = StepDepth.Into;
- req.Enable ();
-
// Step into ss3
- e = step_once ();
+ e = step_into ();
assert_location (e, "ss3");
- // Change to step out
- req.Disable ();
- req.Depth = StepDepth.Out;
- req.Enable ();
-
// Step back into single_stepping
- e = step_once ();
+ e = step_out ();
assert_location (e, "single_stepping");
- // Change to step into
- req.Disable ();
- req.Depth = StepDepth.Into;
- req.Enable ();
-
// Step into ss3_2 ()
- e = step_once ();
+ e = step_into ();
assert_location (e, "ss3_2");
- // Change to step over
- req.Disable ();
- req.Depth = StepDepth.Over;
- req.Enable ();
-
// Step over ss3_2_2 ()
- e = step_once ();
+ e = step_over ();
assert_location (e, "ss3_2");
// Recreate the request
@@ -458,13 +439,8 @@ public class DebuggerTests
e = step_once ();
assert_location (e, "single_stepping");
- // Change to step into
- req.Disable ();
- req.Depth = StepDepth.Into;
- req.Enable ();
-
// Step into ss4 ()
- e = step_once ();
+ e = step_into ();
assert_location (e, "ss4");
// Skip nop
@@ -504,13 +480,12 @@ public class DebuggerTests
assert_location (e, "is_even");
// FIXME: Check that single stepping works with lock (obj)
-
req.Disable ();
// Run until ss6
e = run_until ("ss6");
- req = vm.CreateStepRequest (e.Thread);
+ req = create_step (e);
req.Depth = StepDepth.Over;
req.Enable ();
@@ -522,18 +497,62 @@ public class DebuggerTests
// Check that a step over stops at an EH clause
e = run_until ("ss7_2");
- req = vm.CreateStepRequest (e.Thread);
+ req = create_step (e);
req.Depth = StepDepth.Out;
req.Enable ();
e = step_once ();
assert_location (e, "ss7");
req.Disable ();
- req = vm.CreateStepRequest (e.Thread);
+ req = create_step (e);
req.Depth = StepDepth.Over;
req.Enable ();
e = step_once ();
assert_location (e, "ss7");
req.Disable ();
+
+ // Check that stepping stops between nested calls
+ e = run_until ("ss_nested_2");
+ e = step_out ();
+ assert_location (e, "ss_nested");
+ e = step_into ();
+ assert_location (e, "ss_nested_1");
+ e = step_out ();
+ assert_location (e, "ss_nested");
+ // Check that step over steps over nested calls
+ e = step_over ();
+ assert_location (e, "ss_nested");
+ e = step_into ();
+ assert_location (e, "ss_nested_3");
+ req.Disable ();
+
+ // Check DebuggerStepThrough support
+ e = run_until ("ss_step_through");
+ req = create_step (e);
+ req.Filter = StepFilter.DebuggerStepThrough;
+ e = step_into ();
+ // Step through step_through_1 ()
+ e = step_into ();
+ assert_location (e, "ss_step_through");
+ // Step through StepThroughClass.step_through_2 ()
+ e = step_into ();
+ assert_location (e, "ss_step_through");
+ req.Disable ();
+ req.Filter = StepFilter.None;
+ e = step_into ();
+ assert_location (e, "step_through_3");
+ req.Disable ();
+
+ // Check that step-over doesn't stop at inner frames with recursive functions
+ e = run_until ("ss_recursive");
+ req = create_step (e);
+ e = step_over ();
+ e = step_over ();
+ e = step_over ();
+ var f = e.Thread.GetFrames () [0];
+ assert_location (e, "ss_recursive");
+ AssertValue (1, f.GetValue (f.Method.GetLocal ("n")));
+
+ req.Disable ();
}
[Test]
@@ -1113,7 +1132,7 @@ public class DebuggerTests
t = frame.Method.GetParameters ()[8].ParameterType;
Assert.AreEqual ("Tests2", t.Name);
var attrs = t.GetCustomAttributes (true);
- Assert.AreEqual (3, attrs.Length);
+ Assert.AreEqual (5, attrs.Length);
foreach (var attr in attrs) {
if (attr.Constructor.DeclaringType.Name == "DebuggerDisplayAttribute") {
Assert.AreEqual (1, attr.ConstructorArguments.Count);
@@ -1132,6 +1151,12 @@ public class DebuggerTests
Assert.AreEqual (2, attr.NamedArguments.Count);
Assert.AreEqual ("afield", attr.NamedArguments [0].Field.Name);
Assert.AreEqual ("bfield", attr.NamedArguments [1].Field.Name);
+ } else if (attr.Constructor.DeclaringType.Name == "ClassInterfaceAttribute") {
+ // inherited from System.Object
+ //} else if (attr.Constructor.DeclaringType.Name == "Serializable") {
+ // inherited from System.Object
+ } else if (attr.Constructor.DeclaringType.Name == "ComVisibleAttribute") {
+ // inherited from System.Object
} else {
Assert.Fail (attr.Constructor.DeclaringType.Name);
}
@@ -1335,6 +1360,10 @@ public class DebuggerTests
Assert.AreEqual ("AStruct", s.Type.Name);
AssertValue (42, s ["i"]);
+ // Check decoding of nested structs (#14942)
+ obj = o.GetValue (o.Type.GetField ("nested_struct"));
+ o.SetValue (o.Type.GetField ("nested_struct"), obj);
+
// Check round tripping of boxed struct fields (#12354)
obj = o.GetValue (o.Type.GetField ("boxed_struct_field"));
o.SetValue (o.Type.GetField ("boxed_struct_field"), obj);
@@ -1438,8 +1467,8 @@ public class DebuggerTests
StackFrame frame = e.Thread.GetFrames () [0];
var locals = frame.Method.GetLocals ();
- Assert.AreEqual (7, locals.Length);
- for (int i = 0; i < 7; ++i) {
+ Assert.AreEqual (8, locals.Length);
+ for (int i = 0; i < 8; ++i) {
if (locals [i].Name == "args") {
Assert.IsTrue (locals [i].IsArg);
Assert.AreEqual ("String[]", locals [i].Type.Name);
@@ -1462,6 +1491,7 @@ public class DebuggerTests
} else if (locals [i].Name == "rs") {
Assert.IsTrue (locals [i].IsArg);
Assert.AreEqual ("String", locals [i].Type.Name);
+ } else if (locals [i].Name == "astruct") {
} else {
Assert.Fail ();
}
@@ -1475,6 +1505,27 @@ public class DebuggerTests
return e;
}
+ Event step_into () {
+ step_req.Disable ();
+ step_req.Depth = StepDepth.Into;
+ step_req.Enable ();
+ return step_once ();
+ }
+
+ Event step_over () {
+ step_req.Disable ();
+ step_req.Depth = StepDepth.Over;
+ step_req.Enable ();
+ return step_once ();
+ }
+
+ Event step_out () {
+ step_req.Disable ();
+ step_req.Depth = StepDepth.Out;
+ step_req.Enable ();
+ return step_once ();
+ }
+
[Test]
public void Locals () {
var be = run_until ("locals1");
@@ -1496,9 +1547,8 @@ public class DebuggerTests
object val = frame.GetValue (frame.Method.GetLocal ("i"));
AssertValue (0, val);
- var req = vm.CreateStepRequest (be.Thread);
+ var req = create_step (be);
req.Enable ();
- step_req = req;
// Skip nop
step_once ();
@@ -1580,9 +1630,8 @@ public class DebuggerTests
// gsharedvt
be = run_until ("locals7");
- req = vm.CreateStepRequest (be.Thread);
+ req = create_step (be);
req.Enable ();
- step_req = req;
// Skip nop
e = step_once ();
@@ -1653,6 +1702,8 @@ public class DebuggerTests
var e = GetNextEvent ();
Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
+ Assert.AreEqual (5, (e as VMDeathEvent).ExitCode);
+
var p = vm.Process;
/* Could be a remote vm with no process */
if (p != null) {
@@ -1698,7 +1749,7 @@ public class DebuggerTests
// FIXME: Merge this with LineNumbers () when its fixed
- step_req = vm.CreateStepRequest (e.Thread);
+ step_req = create_step (e);
step_req.Depth = StepDepth.Into;
step_req.Enable ();
@@ -1734,7 +1785,7 @@ public class DebuggerTests
public void LineNumbers () {
Event e = run_until ("line_numbers");
- step_req = vm.CreateStepRequest (e.Thread);
+ step_req = create_step (e);
step_req.Depth = StepDepth.Into;
step_req.Enable ();
@@ -2035,6 +2086,18 @@ public class DebuggerTests
v = this_obj.InvokeMethod (e.Thread, m, null);
AssertValue (42, v);
+#if NET_4_5
+ // instance
+ m = t.GetMethod ("invoke_pass_ref");
+ var task = this_obj.InvokeMethodAsync (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
+ AssertValue ("ABC", task.Result);
+
+ // static
+ m = t.GetMethod ("invoke_static_pass_ref");
+ task = t.InvokeMethodAsync (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
+ AssertValue ("ABC", task.Result);
+#endif
+
// Argument checking
// null thread
@@ -2258,8 +2321,13 @@ public class DebuggerTests
while (invoke_results.Count < 2) {
Thread.Sleep (100);
}
- AssertValue ("ABC", invoke_results [0]);
- AssertValue (42, invoke_results [1]);
+ if (invoke_results [0] is PrimitiveValue) {
+ AssertValue ("ABC", invoke_results [1]);
+ AssertValue (42, invoke_results [0]);
+ } else {
+ AssertValue ("ABC", invoke_results [0]);
+ AssertValue (42, invoke_results [1]);
+ }
}
void invoke_multiple_cb (IAsyncResult ar) {
@@ -2337,6 +2405,14 @@ public class DebuggerTests
frame.SetValue (p, vm.RootDomain.CreateString ("DEF2"));
AssertValue ("DEF2", frame.GetValue (p));
+ // byref struct
+ p = frame.Method.GetParameters ()[4];
+ var v = frame.GetValue (p) as StructMirror;
+ v ["i"] = vm.CreateValue (43);
+ frame.SetValue (p, v);
+ v = frame.GetValue (p) as StructMirror;
+ AssertValue (43, v ["i"]);
+
// argument checking
// variable null
@@ -2426,13 +2502,11 @@ public class DebuggerTests
Assert.IsNull (v);
// Try a single step after the invoke
- var req = vm.CreateStepRequest (e.Thread);
+ var req = create_step (e);
req.Depth = StepDepth.Into;
req.Size = StepSize.Line;
req.Enable ();
- step_req = req;
-
// Skip nop
step_once ();
@@ -2487,6 +2561,17 @@ public class DebuggerTests
Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
req.Disable ();
+ // no subclasses
+ req.IncludeSubclasses = false;
+ req.Enable ();
+
+ vm.Resume ();
+
+ e = GetNextEvent ();
+ Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
+ Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
+ req.Disable ();
+
// Implicit exceptions
req = vm.CreateExceptionRequest (null);
req.Enable ();
@@ -2511,7 +2596,7 @@ public class DebuggerTests
Assert.AreEqual ("exceptions2", frames [0].Method.Name);
req.Disable ();
- var sreq = vm.CreateStepRequest (e.Thread);
+ var sreq = create_step (e);
sreq.Depth = StepDepth.Over;
sreq.Size = StepSize.Line;
sreq.Enable ();
@@ -2915,7 +3000,7 @@ public class DebuggerTests
e = GetNextEvent ();
Assert.IsTrue (e is BreakpointEvent);
- var req = vm.CreateStepRequest (e.Thread);
+ var req = create_step (e);
req.Depth = StepDepth.Over;
req.Size = StepSize.Line;
req.Enable ();