[mono/mono] c3b5906e: [sdb] Add an ExitCode property to VMDeathEvent. Fixes #16113.

"Zoltan Varga ([email protected])" <[email protected]> Fri, 15 Nov 2013 00:00:27 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <00000142590f0a53-7bf918b7-7a26-4f02-89f2-4efbcbd3a896-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/75d1cf2f193e...c3b5906efd1d

   Commit: c3b5906efd1d2d44cc7b556d8f4f7f6ee39a8ded
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-14 23:59:16 GMT
      URL: https://github.com/mono/mono/commit/c3b5906efd1d2d44cc7b556d8f4f7f6ee39a8ded

[sdb] Add an ExitCode property to VMDeathEvent. Fixes #16113.

Changed paths:
  M mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
  M mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDeathEvent.cs
  M mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
  M mcs/class/Mono.Debugger.Soft/Test/dtest.cs
  M mono/metadata/icall.c
  M mono/mini/debugger-agent.c

Modified: mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
===================================================================
@@ -348,6 +348,10 @@ class EventInfo {
 			get; set;
 		}
 
+		public int ExitCode {
+			get; set;
+		}
+
 		public EventInfo (EventType type, int req_id) {
 			EventType = type;
 			ReqId = req_id;
@@ -401,7 +405,7 @@ public abstract class Connection
 		 * with newer runtimes, and vice versa.
 		 */
 		internal const int MAJOR_VERSION = 2;
-		internal const int MINOR_VERSION = 26;
+		internal const int MINOR_VERSION = 27;
 
 		enum WPSuspendPolicy {
 			NONE = 0,
@@ -1225,82 +1229,71 @@ class PacketWriter {
 
 							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 ();

Modified: 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;
+			}
 		}
     }
 }

Modified: mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
===================================================================
@@ -137,7 +137,7 @@ public class VirtualMachine : Mirror
 		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")]
@@ -315,7 +315,7 @@ public void SetSocketTimeouts (int send_timeout, int receive_timeout, int keepal
 			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 +327,7 @@ public void SetSocketTimeouts (int send_timeout, int receive_timeout, int keepal
 				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 +620,10 @@ class EventHandler : MarshalByRefObject, IEventHandler
 
 				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 +677,7 @@ class EventHandler : MarshalByRefObject, IEventHandler
 		}
 
 		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);
         }
     }
 

Modified: mcs/class/Mono.Debugger.Soft/Test/dtest.cs
===================================================================
@@ -1689,6 +1689,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) {

Modified: mono/metadata/icall.c
===================================================================
@@ -6500,6 +6500,8 @@ enum {
 {
 	MONO_ARCH_SAVE_REGS;
 
+	mono_environment_exitcode_set (result);
+
 /* FIXME: There are some cleanup hangs that should be worked out, but
  * if the program is going to exit, everything will be cleaned up when
  * NaCl exits anyway.

Modified: mono/mini/debugger-agent.c
===================================================================
@@ -69,6 +69,7 @@ int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
 #include <mono/metadata/mono-debug-debugger.h>
 #include <mono/metadata/debug-mono-symfile.h>
 #include <mono/metadata/gc-internal.h>
+#include <mono/metadata/environment.h>
 #include <mono/metadata/threads-types.h>
 #include <mono/metadata/socket-io.h>
 #include <mono/metadata/assembly.h>
@@ -283,7 +284,7 @@ struct _InvokeData
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 26
+#define MINOR_VERSION 27
 
 typedef enum {
 	CMD_SET_VM = 1,
@@ -3641,6 +3642,8 @@ static void CALLBACK notify_thread_apc (ULONG_PTR param)
 			buffer_add_domainid (&buf, mono_get_root_domain ());
 			break;
 		case EVENT_KIND_VM_DEATH:
+			if (CHECK_PROTOCOL_VERSION (2, 27))
+				buffer_add_int (&buf, mono_environment_exitcode_get ());
 			break;
 		case EVENT_KIND_EXCEPTION: {
 			EventInfo *ei = arg;
@@ -6678,6 +6681,8 @@ static void CALLBACK notify_thread_apc (ULONG_PTR param)
 			if (!mono_runtime_try_shutdown ())
 				break;
 
+			mono_environment_exitcode_set (exit_code);
+
 			/* Suspend all managed threads since the runtime is going away */
 			DEBUG(1, fprintf (log_file, "Suspending all threads...\n"));
 			mono_thread_suspend_all_other_threads ();


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches