Add filtering by type name to TypeLoad events
authorZoltan Varga <vargaz@gmail.com>
Tue, 25 Oct 2011 17:36:57 +0000 (19:36 +0200)
committerZoltan Varga <vargaz@gmail.com>
Tue, 25 Oct 2011 17:37:40 +0000 (19:37 +0200)
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeLoadEventRequest.cs
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mono/mini/debugger-agent.c

index 6e6726f15d54e8c6a3a1e135e7dd149517dd8ddc..c8b3132f1a03bd0d0a53c9b01a76889cf6b55d15 100644 (file)
@@ -257,6 +257,12 @@ namespace Mono.Debugger.Soft
                }
        }
 
+       class TypeNameModifier : Modifier {
+               public string[] TypeNames {
+                       get; set;
+               }
+       }
+
        class EventInfo {
                public EventType EventType {
                        get; set;
@@ -398,7 +404,8 @@ namespace Mono.Debugger.Soft
                        EXCEPTION_ONLY = 8,
                        STEP = 10,
                        ASSEMBLY_ONLY = 11,
-                       SOURCE_FILE_ONLY = 12
+                       SOURCE_FILE_ONLY = 12,
+                       TYPE_NAME_ONLY = 13
                }
 
                enum CmdVM {
@@ -1963,6 +1970,12 @@ namespace Mono.Debugger.Soft
                                                w.WriteInt (smod.SourceFiles.Length);
                                                foreach (var s in smod.SourceFiles)
                                                        w.WriteString (s);
+                                       } else if (mod is TypeNameModifier) {
+                                               w.WriteByte ((byte)ModifierKind.TYPE_NAME_ONLY);
+                                               var tmod = (mod as TypeNameModifier);
+                                               w.WriteInt (tmod.TypeNames.Length);
+                                               foreach (var s in tmod.TypeNames)
+                                                       w.WriteString (s);
                                        } else {
                                                throw new NotImplementedException ();
                                        }
index e2c905e44918c589e8ebc2bf06a15ec315212be5..130742b4c8ff46e71bd5809d85747eec42da3d1f 100644 (file)
@@ -6,6 +6,7 @@ namespace Mono.Debugger.Soft
 {
        public sealed class TypeLoadEventRequest : EventRequest {
                string[] sourceFiles;
+               string[] typeNames;
 
                internal TypeLoadEventRequest (VirtualMachine vm) : base (vm, EventType.TypeLoad) {
                }
@@ -20,10 +21,22 @@ namespace Mono.Debugger.Soft
                        }
                }
 
+               public string[] TypeNameFilter {
+                       get {
+                               return typeNames;
+                       }
+                       set {
+                               CheckDisabled ();
+                               typeNames = value;
+                       }
+               }
+
                public override void Enable () {
                        var mods = new List <Modifier> ();
                        if (SourceFileFilter != null && SourceFileFilter.Length != 0)
                                mods.Add (new SourceFileModifier () { SourceFiles = SourceFileFilter });
+                       if (TypeNameFilter != null && TypeNameFilter.Length != 0)
+                               mods.Add (new TypeNameModifier () { TypeNames = TypeNameFilter });
                        SendReq (mods);
                }
        }
index c635a4d7676000c16e9c3033d176fd0a8909f644..74df785454d944219f8f1040974103b32719b528 100644 (file)
@@ -925,12 +925,17 @@ public class Tests : TestsBase
                c1.ToString ();
                var c = new TypeLoadClass ();
                c.ToString ();
+               var c2 = new TypeLoadClass2 ();
+               c2.ToString ();
        }
 }
 
 class TypeLoadClass {
 }
 
+class TypeLoadClass2 {
+}
+
 public class CrossDomain : MarshalByRefObject
 {
        public void invoke () {
index 7595620f28b812ba142b02b02f623c882f8a17a6..133e58a33178820c6dade81c99dd3d8139d4b4dc 100644 (file)
@@ -2729,6 +2729,20 @@ public class DebuggerTests
                Assert.AreEqual ("TypeLoadClass", (e as TypeLoadEvent).Type.FullName);
        }
 
+       [Test]
+       public void TypeLoadTypeNameFilter () {
+               Event e = run_until ("type_load");
+
+               var req = vm.CreateTypeLoadRequest ();
+               req.TypeNameFilter = new string [] { "TypeLoadClass2" };
+               req.Enable ();
+
+               vm.Resume ();
+               e = GetNextEvent ();
+               Assert.IsTrue (e is TypeLoadEvent);
+               Assert.AreEqual ("TypeLoadClass2", (e as TypeLoadEvent).Type.FullName);
+       }
+
        [Test]
        public void GetTypesForSourceFile () {
                run_until ("user");
index 135ba52c9fbd39137a66e29011b07ba13e83ac0a..660bade58b0c5173e3efdb4734f21f333058f98c 100644 (file)
@@ -336,7 +336,8 @@ typedef enum {
        MOD_KIND_EXCEPTION_ONLY = 8,
        MOD_KIND_STEP = 10,
        MOD_KIND_ASSEMBLY_ONLY = 11,
-       MOD_KIND_SOURCE_FILE_ONLY = 12
+       MOD_KIND_SOURCE_FILE_ONLY = 12,
+       MOD_KIND_TYPE_NAME_ONLY = 13
 } ModifierKind;
 
 typedef enum {
@@ -496,6 +497,7 @@ typedef struct {
                MonoClass *exc_class; /* For kind == MONO_KIND_EXCEPTION_ONLY */
                MonoAssembly **assemblies; /* For kind == MONO_KIND_ASSEMBLY_ONLY */
                GHashTable *source_files; /* For kind == MONO_KIND_SOURCE_FILE_ONLY */
+               GHashTable *type_names; /* For kind == MONO_KIND_TYPE_NAME_ONLY */
        } data;
        gboolean caught, uncaught; /* For kind == MOD_KIND_EXCEPTION_ONLY */
 } Modifier;
@@ -3222,6 +3224,13 @@ create_event_list (EventKind event, GPtrArray *reqs, MonoJitInfo *ji, EventInfo
                                        }
                                        if (!found)
                                                filtered = TRUE;
+                               } else if (mod->kind == MOD_KIND_TYPE_NAME_ONLY && ei && ei->klass) {
+                                       char *s;
+
+                                       s = mono_type_full_name (&ei->klass->byval_arg);
+                                       if (!g_hash_table_lookup (mod->data.type_names, s))
+                                               filtered = TRUE;
+                                       g_free (s);
                                }
                        }
 
@@ -6373,6 +6382,18 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                                        if (s)
                                                g_hash_table_insert (modifier->data.source_files, s, s);
                                }
+                       } else if (mod == MOD_KIND_TYPE_NAME_ONLY) {
+                               int n = decode_int (p, &p, end);
+                               int j;
+
+                               modifier = &req->modifiers [i];
+                               modifier->data.type_names = g_hash_table_new (g_str_hash, g_str_equal);
+                               for (j = 0; j < n; ++j) {
+                                       char *s = decode_string (p, &p, end);
+
+                                       if (s)
+                                               g_hash_table_insert (modifier->data.type_names, s, s);
+                               }
                        } else {
                                g_free (req);
                                return ERR_NOT_IMPLEMENTED;