Add exception handlers to MethodBodyMirror
authorJb Evain <jbevain@gmail.com>
Fri, 4 May 2012 07:07:48 +0000 (09:07 +0200)
committerJb Evain <jbevain@gmail.com>
Fri, 4 May 2012 07:13:22 +0000 (09:13 +0200)
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILExceptionHandler.cs [new file with mode: 0644]
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodBodyMirror.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs
mono/mini/debugger-agent.c

index 803efd849ba58d335e5485a9e4d43b1fdfcf38f4..db2a4d73bcedf816a3ff6dd7e5702251106f800b 100644 (file)
@@ -12,6 +12,7 @@ Mono.Debugger.Soft/StackFrame.cs
 Mono.Debugger.Soft/CustomAttributeDataMirror.cs
 Mono.Debugger.Soft/ThreadStartEvent.cs
 Mono.Debugger.Soft/ILInstruction.cs
+Mono.Debugger.Soft/ILExceptionHandler.cs
 Mono.Debugger.Soft/InterfaceMappingMirror.cs
 Mono.Debugger.Soft/PrimitiveValue.cs
 Mono.Debugger.Soft/PointerValue.cs
index 1c9e4f58bbb90fbfd8df67b35bc1301b81778484..6d6ad987e0e645f8b3f40dd8e28ad4ee967b89ed 100644 (file)
@@ -79,6 +79,24 @@ namespace Mono.Debugger.Soft
 
        class MethodBodyInfo {
                public byte[] il;
+               public ExceptionClauseInfo[] clauses;
+       }
+
+       struct ExceptionClauseInfo {
+               public ExceptionClauseFlags flags;
+               public int try_offset;
+               public int try_length;
+               public int handler_offset;
+               public int handler_length;
+               public int filter_offset;
+               public long catch_type_id;
+       }
+
+       enum ExceptionClauseFlags {
+               None = 0x0,
+               Filter = 0x1,
+               Finally = 0x2,
+               Fault = 0x4,
        }
 
        struct ParamInfo {
@@ -376,7 +394,7 @@ namespace Mono.Debugger.Soft
                 * with newer runtimes, and vice versa.
                 */
                internal const int MAJOR_VERSION = 2;
-               internal const int MINOR_VERSION = 17;
+               internal const int MINOR_VERSION = 18;
 
                enum WPSuspendPolicy {
                        NONE = 0,
@@ -1757,6 +1775,28 @@ namespace Mono.Debugger.Soft
                        for (int i = 0; i < info.il.Length; ++i)
                                info.il [i] = (byte)res.ReadByte ();
 
+                       if (Version.AtLeast (2, 18)) {
+                               info.clauses = new ExceptionClauseInfo [res.ReadInt ()];
+
+                               for (int i = 0; i < info.clauses.Length; ++i) {
+                                       var clause = new ExceptionClauseInfo {
+                                               flags = (ExceptionClauseFlags) res.ReadInt (),
+                                               try_offset = res.ReadInt (),
+                                               try_length = res.ReadInt (),
+                                               handler_offset = res.ReadInt (),
+                                               handler_length = res.ReadInt (),
+                                       };
+
+                                       if (clause.flags == ExceptionClauseFlags.None)
+                                               clause.catch_type_id = res.ReadId ();
+                                       else if (clause.flags == ExceptionClauseFlags.Filter)
+                                               clause.filter_offset = res.ReadInt ();
+
+                                       info.clauses [i] = clause;
+                               }
+                       } else
+                               info.clauses = new ExceptionClauseInfo [0];
+
                        return info;
                }
 
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILExceptionHandler.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILExceptionHandler.cs
new file mode 100644 (file)
index 0000000..927949d
--- /dev/null
@@ -0,0 +1,33 @@
+using System;
+using System.IO;
+
+namespace Mono.Debugger.Soft
+{
+       public enum ILExceptionHandlerType
+       {
+               Catch = ExceptionClauseFlags.None,
+               Filter = ExceptionClauseFlags.Filter,
+               Finally = ExceptionClauseFlags.Finally,
+               Fault = ExceptionClauseFlags.Fault,
+       }
+
+       public class ILExceptionHandler
+       {
+               public int TryOffset { get; internal set; }
+               public int TryLength { get; internal set; }
+               public ILExceptionHandlerType HandlerType { get; internal set; }
+               public int HandlerOffset { get; internal set; }
+               public int HandlerLength { get; internal set;}
+               public int FilterOffset { get; internal set; }
+               public TypeMirror CatchType { get; internal set; }
+
+               internal ILExceptionHandler (int try_offset, int try_length, ILExceptionHandlerType handler_type, int handler_offset, int handler_length)
+               {
+                       TryOffset = try_offset;
+                       TryLength = try_length;
+                       HandlerType = handler_type;
+                       HandlerOffset = handler_offset;
+                       HandlerLength = handler_length;
+               }
+       }
+}
index c03f4cdb47625e076c12a4e5556013b26e35f6fd..c383005a0d41979d8d92977b7f96d93c4b7091f3 100644 (file)
@@ -4,6 +4,7 @@ using System.Text;
 using Mono.Cecil.Cil;
 using Mono.Cecil.Metadata;
 using System.IO;
+using System.Linq;
 using System.Reflection;
 
 namespace Mono.Debugger.Soft
@@ -11,11 +12,11 @@ namespace Mono.Debugger.Soft
        public class MethodBodyMirror : Mirror
        {
                MethodMirror method;
-               byte[] il;
+               MethodBodyInfo info;
 
-               internal MethodBodyMirror (VirtualMachine vm, MethodMirror method, byte[] il) : base (vm, 0) {
+               internal MethodBodyMirror (VirtualMachine vm, MethodMirror method, MethodBodyInfo info) : base (vm, 0) {
                        this.method = method;
-                       this.il = il;
+                       this.info = info;
                }
 
                public MethodMirror Method {
@@ -24,13 +25,29 @@ namespace Mono.Debugger.Soft
                        }
                }
 
+               public List<ILExceptionHandler> ExceptionHandlers {
+                       get {
+                               vm.CheckProtocolVersion (2, 18);
+                               return info.clauses.Select (c =>
+                               {
+                                       var handler = new ILExceptionHandler (c.try_offset, c.try_length, (ILExceptionHandlerType) c.flags, c.handler_offset, c.handler_length);
+                                       if (c.flags == ExceptionClauseFlags.None)
+                                               handler.CatchType = vm.GetType (c.catch_type_id);
+                                       else if (c.flags == ExceptionClauseFlags.Filter)
+                                               handler.FilterOffset = c.filter_offset;
+
+                                       return handler;
+                               }).ToList ();
+                       }
+               }
+
                public byte[] GetILAsByteArray () {
-                       return il;
+                       return info.il;
                }
 
                public List<ILInstruction> Instructions {
                        get {
-                               return ReadCilBody (new BinaryReader (new MemoryStream (il)), il.Length);
+                               return ReadCilBody (new BinaryReader (new MemoryStream (info.il)), info.il.Length);
                        }
                }
 
index 3034a01d33560703926814389da1c81cad98724e..7f315fd05d2b170101c870045d50da7824083533 100644 (file)
@@ -249,7 +249,7 @@ namespace Mono.Debugger.Soft
                        if (body == null) {
                                MethodBodyInfo info = vm.conn.Method_GetBody (id);
 
-                               body = new MethodBodyMirror (vm, this, info.il);
+                               body = new MethodBodyMirror (vm, this, info);
                        }
                        return body;
                }
index 5a6439fc1f6dd29bc48e0a47c708ba1ccc892b34..27e19774f08e5c3557c1fd2304f04da8863f5684 100644 (file)
@@ -275,7 +275,7 @@ typedef struct {
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 17
+#define MINOR_VERSION 18
 
 typedef enum {
        CMD_SET_VM = 1,
@@ -7709,12 +7709,34 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                header = mono_method_get_header (method);
                if (!header) {
                        buffer_add_int (buf, 0);
+
+                       if (CHECK_PROTOCOL_VERSION (2, 18))
+                               buffer_add_int (buf, 0);
                } else {
                        buffer_add_int (buf, header->code_size);
                        for (i = 0; i < header->code_size; ++i)
                                buffer_add_byte (buf, header->code [i]);
+
+                       if (CHECK_PROTOCOL_VERSION (2, 18)) {
+                               buffer_add_int (buf, header->num_clauses);
+                               for (i = 0; i < header->num_clauses; ++i) {
+                                       MonoExceptionClause *clause = &header->clauses [i];
+
+                                       buffer_add_int (buf, clause->flags);
+                                       buffer_add_int (buf, clause->try_offset);
+                                       buffer_add_int (buf, clause->try_len);
+                                       buffer_add_int (buf, clause->handler_offset);
+                                       buffer_add_int (buf, clause->handler_len);
+                                       if (clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
+                                               buffer_add_typeid (buf, domain, clause->data.catch_class);
+                                       else if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER)
+                                               buffer_add_int (buf, clause->data.filter_offset);
+                               }
+                       }
+
+                       mono_metadata_free_mh (header);
                }
-               mono_metadata_free_mh (header);
+
                break;
        }
        case CMD_METHOD_RESOLVE_TOKEN: {