Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kyte <alexmkyte@gmail.com>2018-10-19 03:39:03 +0300
committerAlexander Köplinger <alex.koeplinger@outlook.com>2018-10-19 03:39:03 +0300
commit9aab5273dd8f1a516c4f072b350487a50cc0bced (patch)
treef538100ae4e9f7d06421595970be7f9a40cceb37 /mcs/class/Mono.Debugger.Soft
parent4844ab019dc4c04eb5b96dceca32a84a6256dff5 (diff)
Add crash reporting debugger event (#10628)
This should help get information on native crashes that happen in hard-to-debug environments. To quote https://github.com/mono/mono/issues/10157 : When a mono runtime is attached to a managed debugger and the debugged runtime is induced to cause a crash, the state of that crash is not communicated to the managed debugger. This, combined with the difficulty in having the debugged runtime both attached to the managed debugger and lldb, makes this type of crash difficult to interactively debug. When the managed debugger is the only connection someone has with the runtime because it is embedded in a way that is resistant to unmanaged debugging (watchOS application on-device, for instance), this is an even more difficult problem. By adding an SDB protocol event that sends a type of "runtime death" and a blob of opaque json (version dependent, no protocol guarantees), people can report these crashes without having to assist a mono runtime engineer in observing a crash on device. In the case that spurious bugs in this manner are submitted, it will require less effort as well to spot stack frames that indicate misuse of mixed managed-unmanaged APIs (which offer the ability to drive a segfault or g_assert
Diffstat (limited to 'mcs/class/Mono.Debugger.Soft')
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.csproj3
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources1
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs40
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/CrashEvent.cs25
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs2
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDisconnectedException.cs10
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs3
-rw-r--r--mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs9
-rw-r--r--mcs/class/Mono.Debugger.Soft/Test/dtest.cs33
9 files changed, 118 insertions, 8 deletions
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.csproj b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.csproj
index b73e91c40a2..af6eba5272a 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.csproj
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.csproj
@@ -4,7 +4,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">net_4_x</Platform>
- <ProjectGuid>{8787A3B7-8A19-4586-8DCF-6F5914FD48D5}</ProjectGuid>
+ <ProjectGuid>{767CAD15-F8B5-4EAC-8B3D-4EF75F768015}</ProjectGuid>
<OutputType>Library</OutputType>
<NoWarn>1699</NoWarn>
<LangVersion>latest</LangVersion>
@@ -62,6 +62,7 @@
<Compile Include="Mono.Debugger.Soft\BreakpointEvent.cs" />
<Compile Include="Mono.Debugger.Soft\BreakpointEventRequest.cs" />
<Compile Include="Mono.Debugger.Soft\Connection.cs" />
+ <Compile Include="Mono.Debugger.Soft\CrashEvent.cs" />
<Compile Include="Mono.Debugger.Soft\CustomAttributeDataMirror.cs" />
<Compile Include="Mono.Debugger.Soft\CustomAttributeNamedArgumentMirror.cs" />
<Compile Include="Mono.Debugger.Soft\CustomAttributeTypedArgumentMirror.cs" />
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources
index 3ea9e744843..65ebbf5e7c0 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources
@@ -74,4 +74,5 @@ Mono.Debugger.Soft/ITargetProcess.cs
Mono.Debugger.Soft/AbsentInformationException.cs
Mono.Debugger.Soft/UserBreakEvent.cs
Mono.Debugger.Soft/UserLogEvent.cs
+Mono.Debugger.Soft/CrashEvent.cs
Mono.Debugger.Soft/ILInterpreter.cs
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 99db87ed34d..1553096b5f8 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
@@ -367,6 +367,14 @@ namespace Mono.Debugger.Soft
get; set;
}
+ public string Dump {
+ get; set;
+ }
+
+ public ulong Hash {
+ get; set;
+ }
+
public EventInfo (EventType type, int req_id) {
EventType = type;
ReqId = req_id;
@@ -420,7 +428,7 @@ namespace Mono.Debugger.Soft
* with newer runtimes, and vice versa.
*/
internal const int MAJOR_VERSION = 2;
- internal const int MINOR_VERSION = 48;
+ internal const int MINOR_VERSION = 49;
enum WPSuspendPolicy {
NONE = 0,
@@ -463,7 +471,8 @@ namespace Mono.Debugger.Soft
EXCEPTION = 13,
KEEPALIVE = 14,
USER_BREAK = 15,
- USER_LOG = 16
+ USER_LOG = 16,
+ CRASH = 17
}
enum ModifierKind {
@@ -1272,6 +1281,7 @@ namespace Mono.Debugger.Soft
}
bool disconnected;
+ VMCrashException crashed;
internal ManualResetEvent DisconnectedEvent = new ManualResetEvent (false);
@@ -1279,10 +1289,14 @@ namespace Mono.Debugger.Soft
while (!closed) {
try {
bool res = ReceivePacket ();
- if (!res)
+ if (!res) {
break;
+ }
} catch (ThreadAbortException) {
break;
+ } catch (VMCrashException ex) {
+ crashed = ex;
+ break;
} catch (Exception ex) {
if (!closed) {
Console.WriteLine (ex);
@@ -1300,6 +1314,15 @@ namespace Mono.Debugger.Soft
EventHandler.VMDisconnect (0, 0, null);
}
+ void disconnected_check () {
+ if (!disconnected)
+ return;
+ else if (crashed != null)
+ throw crashed;
+ else
+ throw new VMDisconnectedException ();
+ }
+
bool ReceivePacket () {
byte[] packet = ReadPacket ();
@@ -1354,6 +1377,11 @@ namespace Mono.Debugger.Soft
exit_code = r.ReadInt ();
//EventHandler.VMDeath (req_id, 0, null);
events [i] = new EventInfo (etype, req_id) { ExitCode = exit_code };
+ } else if (kind == EventKind.CRASH) {
+ ulong hash = (ulong) r.ReadLong ();
+ string dump = r.ReadString ();
+
+ events [i] = new EventInfo (etype, req_id) { Dump = dump, Hash = hash};
} else if (kind == EventKind.THREAD_START) {
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
//EventHandler.ThreadStart (req_id, thread_id, thread_id);
@@ -1571,8 +1599,7 @@ namespace Mono.Debugger.Soft
int id = IdGenerator;
Stopwatch watch = null;
- if (disconnected)
- throw new VMDisconnectedException ();
+ disconnected_check ();
if (EnableConnectionLogging)
watch = Stopwatch.StartNew ();
@@ -1606,8 +1633,7 @@ namespace Mono.Debugger.Soft
return r;
}
} else {
- if (disconnected)
- throw new VMDisconnectedException ();
+ disconnected_check ();
Monitor.Wait (reply_packets_monitor);
}
}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/CrashEvent.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/CrashEvent.cs
new file mode 100644
index 00000000000..35daf5d396c
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/CrashEvent.cs
@@ -0,0 +1,25 @@
+namespace Mono.Debugger.Soft
+{
+ public class CrashEvent : Event {
+
+ ulong hash;
+ string dump;
+
+ internal CrashEvent (VirtualMachine vm, int req_id, long thread_id, string dump, ulong hash) : base (EventType.Crash, vm, req_id, thread_id) {
+ this.dump = dump;
+ this.hash = hash;
+ }
+
+ public ulong Hash {
+ get {
+ return hash;
+ }
+ }
+
+ public string Dump {
+ get {
+ return dump;
+ }
+ }
+ }
+}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs
index 802a4ad7d0e..9fd82bd1aac 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs
@@ -26,6 +26,8 @@ namespace Mono.Debugger.Soft
// System.Diagnostics.Debugger.Log ()
//
UserLog = 16,
+ // Fatal error handling
+ Crash = 17,
// Not part of the wire protocol
VMDisconnect = 99
}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDisconnectedException.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDisconnectedException.cs
index d26b1be202f..6c3425e4fa5 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDisconnectedException.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDisconnectedException.cs
@@ -7,4 +7,14 @@ namespace Mono.Debugger.Soft
public VMDisconnectedException () : base () {
}
}
+
+ public class VMCrashException : VMDisconnectedException {
+ public readonly string Dump;
+ public readonly ulong Hash;
+
+ public VMCrashException (string dump, ulong hash) : base () {
+ this.Dump = dump;
+ this.Hash = hash;
+ }
+ }
}
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 c72c17a443c..aff5d94d9a1 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
@@ -808,6 +808,9 @@ namespace Mono.Debugger.Soft
case EventType.UserLog:
l.Add (new UserLogEvent (vm, req_id, thread_id, ei.Level, ei.Category, ei.Message));
break;
+ case EventType.Crash:
+ l.Add (new CrashEvent (vm, req_id, thread_id, ei.Dump, ei.Hash));
+ break;
}
}
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
index 98cf550d047..c617107cafe 100644
--- a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
+++ b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
@@ -319,6 +319,10 @@ public class Tests : TestsBase, ITest2
unhandled_exception_endinvoke ();
return 0;
}
+ if (args.Length >0 && args [0] == "crash-vm") {
+ crash ();
+ return 0;
+ }
if (args.Length >0 && args [0] == "unhandled-exception-user") {
unhandled_exception_user ();
return 0;
@@ -1331,6 +1335,11 @@ public class Tests : TestsBase, ITest2
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void crash () {
+ unsafe { Console.WriteLine("{0}", *(int*) -1); }
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
public static void unhandled_exception_user () {
System.Threading.Tasks.Task.Factory.StartNew (() => {
Throw ();
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
index b5a544a6f7e..d6c76b435e9 100644
--- a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
+++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
@@ -2455,6 +2455,39 @@ public class DebuggerTests
}
[Test]
+ [Category("NotOnWindows")]
+ public void Crash () {
+ bool success = false;
+
+ try {
+ vm.Detach ();
+ Start (new string [] { dtest_app_path, "crash-vm" });
+ Event e = run_until ("crash");
+ while (!success) {
+ vm.Resume ();
+ e = GetNextEvent ();
+ var crash = e as CrashEvent;
+ if (crash == null)
+ continue;
+
+ success = true;
+ Assert.AreNotEqual (0, crash.Dump.Length);
+
+ break;
+ }
+ } finally {
+ try {
+ vm.Detach ();
+ } finally {
+ vm = null;
+ }
+ }
+
+ if (!success)
+ Assert.Fail ("Didn't get crash event");
+ }
+
+ [Test]
public void Dispose () {
run_until ("Main");