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 e480555252ed..e7c43aca1a29 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs @@ -393,6 +393,9 @@ public class ErrorHandlerEventArgs : EventArgs { public ErrorCode ErrorCode { get; set; } + public string ErrorMessage { + get; set; + } } /* @@ -751,10 +754,12 @@ public PacketReader (Connection connection, byte[] packet) { // For reply packets offset = 0; - ReadInt (); // length + var len = ReadInt (); // length ReadInt (); // id ReadByte (); // flags ErrorCode = ReadShort (); + if (ErrorCode == (int)Mono.Debugger.Soft.ErrorCode.INVALID_ARGUMENT && len > offset) + ErrorMsg = ReadString (); } public CommandSet CommandSet { @@ -769,6 +774,10 @@ public int ErrorCode { get; set; } + public string ErrorMsg { + get; internal set; + } + public int Offset { get { return offset; @@ -1570,7 +1579,7 @@ PacketReader SendReceive (CommandSet command_set, int command, PacketWriter pack LogPacket (packetId, encoded_packet, reply, command_set, command, watch); if (r.ErrorCode != 0) { if (ErrorHandler != null) - ErrorHandler (this, new ErrorHandlerEventArgs () { ErrorCode = (ErrorCode)r.ErrorCode }); + ErrorHandler (this, new ErrorHandlerEventArgs () { ErrorCode = (ErrorCode)r.ErrorCode, ErrorMessage = r.ErrorMsg}); throw new NotImplementedException ("No error handler set."); } else { return r; 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 9d60855a31a7..1a3c0a77cbb7 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs @@ -347,7 +347,7 @@ internal void ErrorHandler (object sender, ErrorHandlerEventArgs args) { case ErrorCode.NO_SEQ_POINT_AT_IL_OFFSET: throw new ArgumentException ("Cannot set breakpoint on the specified IL offset."); default: - throw new CommandException (args.ErrorCode); + throw new CommandException (args.ErrorCode, args.ErrorMessage); } } @@ -792,13 +792,18 @@ public void VMDisconnect (int req_id, long thread_id, string vm_uri) { public class CommandException : Exception { - internal CommandException (ErrorCode error_code) : base ("Debuggee returned error code " + error_code + ".") { + internal CommandException (ErrorCode error_code, string error_message) : base ("Debuggee returned error code " + error_code + (error_message == null || error_message.Length == 0 ? "." : " - " + error_message + ".")) { ErrorCode = error_code; + ErrorMessage = error_message; } public ErrorCode ErrorCode { get; set; } + + public string ErrorMessage { + get; internal set; + } } public class VMNotSuspendedException : InvalidOperationException diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs index 341c247d342c..a90145526cdc 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs @@ -365,6 +365,9 @@ public static int Main (String[] args) { if (args.Length > 0 && args [0] == "invoke-abort") new Tests ().invoke_abort (); new Tests ().evaluate_method (); + + test_invalid_argument_assembly_get_type (); + return 3; } @@ -373,6 +376,10 @@ public static void local_reflect () { LocalReflectClass.RunMe (); } + public static void test_invalid_argument_assembly_get_type () { + + } + public static void breakpoints () { /* Call these early so it is JITted by the time a breakpoint is placed on it */ bp3 (); diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs index 0bb6328eccbc..e4d04451f458 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs @@ -4431,5 +4431,18 @@ public void InvokeRefReturnMethod () { AssertValue (1, mirror["i"]); AssertValue (2.0, mirror["d"]); } + + [Test] + public void InvalidArgumentAssemblyGetType () { + Event e = run_until ("test_invalid_argument_assembly_get_type"); + var assembly = entry_point.DeclaringType.Assembly; + try { + var type = assembly.GetType ("System.Collections.Generic.Dictionary.Main"); + } + catch (CommandException ex) { + Assert.AreEqual(ex.ErrorMessage, "Unexpected assembly-qualified type \"System.Collections.Generic.Dictionary.Main\" was provided"); + } + } + } // class DebuggerTests } // namespace diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index acc9ea9e91f6..9055c8f76b31 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -9183,6 +9183,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) ignore_case = decode_byte (p, &p, end); if (!mono_reflection_parse_type_checked (name, &info, &error)) { + buffer_add_string (buf, mono_error_get_message (&error)); mono_error_cleanup (&error); g_free (name); mono_reflection_free_type_info (&info); @@ -9700,6 +9701,8 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf) case CMD_ASSEMBLY_GET_TYPE: { MonoError error; char *s = decode_string (p, &p, end); + char* original_s = g_strdup_printf ("\"%s\"", s); + gboolean ignorecase = decode_byte (p, &p, end); MonoTypeNameParse info; MonoType *t; @@ -9714,20 +9717,33 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf) mono_error_cleanup (&error); t = NULL; } else { - if (info.assembly.name) - NOT_IMPLEMENTED; + if (info.assembly.name) { + mono_reflection_free_type_info (&info); + g_free (s); + mono_domain_set (d, TRUE); + char* error_msg = g_strdup_printf ("Unexpected assembly-qualified type %s was provided", original_s); + buffer_add_string (buf, error_msg); + g_free (error_msg); + g_free (original_s); + return ERR_INVALID_ARGUMENT; + } t = mono_reflection_get_type_checked (ass->image, ass->image, &info, ignorecase, &type_resolve, &error); if (!is_ok (&error)) { mono_error_cleanup (&error); /* FIXME don't swallow the error */ mono_reflection_free_type_info (&info); g_free (s); + mono_domain_set (d, TRUE); + char* error_msg = g_strdup_printf ("Invalid type name %s", original_s); + buffer_add_string (buf, error_msg); + g_free (error_msg); + g_free (original_s); return ERR_INVALID_ARGUMENT; } } buffer_add_typeid (buf, domain, t ? mono_class_from_mono_type (t) : NULL); mono_reflection_free_type_info (&info); g_free (s); - + g_free (original_s); mono_domain_set (d, TRUE); break; @@ -10693,6 +10709,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g header = mono_method_get_header_checked (method, &error); if (!header) { + buffer_add_string (buf, mono_error_get_message (&error)); mono_error_cleanup (&error); /* FIXME don't swallow the error */ return ERR_INVALID_ARGUMENT; } @@ -11580,7 +11597,7 @@ string_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (!mono_error_ok (&error)) { if (s) g_free (s); - + buffer_add_string (buf, mono_error_get_message (&error)); return ERR_INVALID_ARGUMENT; }