From: Jb Evain Date: Fri, 4 May 2012 07:07:48 +0000 (+0200) Subject: Add exception handlers to MethodBodyMirror X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=583cab9f803a354965c5203aa663b264d56f1668;p=mono.git Add exception handlers to MethodBodyMirror --- 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 803efd849ba..db2a4d73bce 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources @@ -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 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 1c9e4f58bbb..6d6ad987e0e 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs @@ -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 index 00000000000..927949d0711 --- /dev/null +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILExceptionHandler.cs @@ -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; + } + } +} diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodBodyMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodBodyMirror.cs index c03f4cdb476..c383005a0d4 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodBodyMirror.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodBodyMirror.cs @@ -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 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 Instructions { get { - return ReadCilBody (new BinaryReader (new MemoryStream (il)), il.Length); + return ReadCilBody (new BinaryReader (new MemoryStream (info.il)), info.il.Length); } } diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs index 3034a01d335..7f315fd05d2 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs @@ -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; } diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index 5a6439fc1f6..27e19774f08 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -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: {