[io-layer] Extract socket (#4241)
[mono.git] / mono / mini / debugger-agent.c
index 9b188eeb2af50309ccf07f68ca823d03ce11ad38..ce2656126b6d1750e130ee034779a0be7664e87b 100644 (file)
 #include <mono/metadata/environment.h>
 #include <mono/metadata/threads-types.h>
 #include <mono/metadata/threadpool.h>
-#include <mono/metadata/socket-io.h>
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/runtime.h>
 #include <mono/metadata/verify-internals.h>
 #include <mono/metadata/reflection-internals.h>
+#include <mono/metadata/w32socket.h>
 #include <mono/utils/mono-coop-mutex.h>
 #include <mono/utils/mono-coop-semaphore.h>
 #include <mono/utils/mono-error-internals.h>
@@ -569,6 +569,8 @@ typedef struct {
        GSList *bps;
        /* The number of frames at the start of a step-over */
        int nframes;
+       /* If set, don't stop in methods that are not part of user assemblies */
+       MonoAssembly** user_assemblies;
 } SingleStepReq;
 
 /*
@@ -4910,6 +4912,22 @@ process_single_step_inner (DebuggerTlsData *tls, gboolean from_signal)
        if (method->klass == mono_defaults.string_class && (!strcmp (method->name, "memset") || strstr (method->name, "memcpy")))
                return;
 
+       /*
+        * This could be in ss_update method, but mono_find_next_seq_point_for_native_offset is pretty expensive method,
+        * hence we prefer this check here.
+        */
+       if (ss_req->user_assemblies) {
+               gboolean found = FALSE;
+               for (int k = 0; ss_req->user_assemblies[k]; k++)
+                       if (ss_req->user_assemblies[k] == method->klass->image->assembly) {
+                               found = TRUE;
+                               break;
+                       }
+               if (!found)
+                       return;
+       }
+
+
        /*
         * The ip points to the instruction causing the single step event, which is before
         * the offset recorded in the seq point map, so find the next seq point after ip.
@@ -5218,6 +5236,21 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI
                        nframes = tls->frame_count;
                }
 
+               /* Need to stop in catch clauses as well */
+               for (i = ss_req->depth == STEP_DEPTH_OUT ? 1 : 0; i < nframes; ++i) {
+                       StackFrame *frame = frames [i];
+
+                       if (frame->ji) {
+                               MonoJitInfo *jinfo = frame->ji;
+                               for (j = 0; j < jinfo->num_clauses; ++j) {
+                                       MonoJitExceptionInfo *ei = &jinfo->clauses [j];
+
+                                       if (mono_find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL, &local_sp))
+                                               ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, frame->method, local_sp.il_offset);
+                               }
+                       }
+               }
+
                /*
                 * Find the first sequence point in the current or in a previous frame which
                 * is not the last in its method.
@@ -5304,26 +5337,6 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI
                        ss_req->depth = STEP_DEPTH_INTO;
                }
 
-               if (ss_req->depth == STEP_DEPTH_OVER) {
-                       /* Need to stop in catch clauses as well */
-                       for (i = 0; i < nframes; ++i) {
-                               StackFrame *frame = frames [i];
-
-                               if (frame->ji) {
-                                       MonoJitInfo *jinfo = frame->ji;
-                                       for (j = 0; j < jinfo->num_clauses; ++j) {
-                                               MonoJitExceptionInfo *ei = &jinfo->clauses [j];
-
-                                               found_sp = mono_find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL, &local_sp);
-                                               sp = (found_sp)? &local_sp : NULL;
-
-                                               if (found_sp)
-                                                       ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, frame->method, sp->il_offset);
-                                       }
-                               }
-                       }
-               }
-
                if (ss_req->depth == STEP_DEPTH_INTO) {
                        /* Enable global stepping so we stop at method entry too */
                        enable_global = TRUE;
@@ -5392,6 +5405,13 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte
        ss_req->filter = filter;
        req->info = ss_req;
 
+       for (int i = 0; i < req->nmodifiers; i++) {
+               if (req->modifiers[i].kind == MOD_KIND_ASSEMBLY_ONLY) {
+                       ss_req->user_assemblies = req->modifiers[i].data.assemblies;
+                       break;
+               }
+       }
+
        mono_loader_lock ();
        tls = (DebuggerTlsData *)mono_g_hash_table_lookup (thread_to_tls, thread);
        mono_loader_unlock ();
@@ -6484,7 +6504,8 @@ clear_assembly_from_modifier (EventRequest *req, Modifier *m, MonoAssembly *asse
                }
 
                if (match_count) {
-                       newassemblies = g_new0 (MonoAssembly*, count - match_count);
+                       // +1 because we don't know length and we use last element to check for end
+                       newassemblies = g_new0 (MonoAssembly*, count - match_count + 1);
 
                        pos = 0;
                        for (i = 0; i < count; ++i)
@@ -7494,7 +7515,8 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                                int n = decode_int (p, &p, end);
                                int j;
 
-                               req->modifiers [i].data.assemblies = g_new0 (MonoAssembly*, n);
+                               // +1 because we don't know length and we use last element to check for end
+                               req->modifiers [i].data.assemblies = g_new0 (MonoAssembly*, n + 1);
                                for (j = 0; j < n; ++j) {
                                        req->modifiers [i].data.assemblies [j] = decode_assemblyid (p, &p, end, &domain, &err);
                                        if (err != ERR_NONE) {