Ignore requests to set breakpoints at il offsets belonging to dead code. Fixes #11880.
authorZoltan Varga <vargaz@gmail.com>
Sat, 27 Apr 2013 14:18:07 +0000 (16:18 +0200)
committerZoltan Varga <vargaz@gmail.com>
Sat, 27 Apr 2013 14:18:17 +0000 (16:18 +0200)
mono/mini/debugger-agent.c
mono/mini/debugger-agent.h
mono/mini/method-to-ir.c
mono/mini/mini.c

index 74e078c94de612bd3cf346f73eaa5d6400f3231d..1d74a7d9b01164aef249d73795c2dad668022eab 100644 (file)
@@ -4073,7 +4073,9 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo
        g_hash_table_insert (bp_locs, inst->ip, GINT_TO_POINTER (count + 1));
        mono_loader_unlock ();
 
-       if (count == 0) {
+       if (sp->native_offset == SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) {
+               DEBUG (1, fprintf (log_file, "[dbg] Attempting to insert seq point at dead IL offset %d, ignoring.\n", (int)bp->il_offset));
+       } else if (count == 0) {
 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
                mono_arch_set_breakpoint (ji, inst->ip);
 #else
@@ -4099,7 +4101,7 @@ remove_breakpoint (BreakpointInstance *inst)
 
        g_assert (count > 0);
 
-       if (count == 1) {
+       if (count == 1 && inst->native_offset != SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) {
                mono_arch_clear_breakpoint (ji, ip);
        }
 #else
index 7a7b9473a030166fbc2bfad1dfef82aded818b60..95b765069e70d6842fd9080516ab1a188ee9cf76 100644 (file)
@@ -7,6 +7,9 @@
 #define METHOD_ENTRY_IL_OFFSET -1
 #define METHOD_EXIT_IL_OFFSET 0xffffff
 
+/* Native offset used to mark seq points in dead code */
+#define SEQ_POINT_NATIVE_OFFSET_DEAD_CODE -1
+
 void
 mono_debugger_agent_parse_options (char *options) MONO_INTERNAL;
 
index 43129136143cb68da9b04f9b8f07231c4370ac50..17d4de9a7bd6234b2c01bc5df124ea8fcead5d90 100644 (file)
@@ -6182,6 +6182,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
        MonoInst *cached_tls_addr = NULL;
        MonoDebugMethodInfo *minfo;
        MonoBitSet *seq_point_locs = NULL;
+       MonoBitSet *seq_point_set_locs = NULL;
 
        disable_inline = is_jit_optimizer_disabled (method);
 
@@ -6242,6 +6243,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                        mono_debug_symfile_get_line_numbers_full (minfo, NULL, NULL, &n_il_offsets, &il_offsets, &line_numbers, NULL, NULL);
                        seq_point_locs = mono_bitset_mem_new (mono_mempool_alloc0 (cfg->mempool, mono_bitset_alloc_size (header->code_size, 0)), header->code_size, 0);
+                       seq_point_set_locs = mono_bitset_mem_new (mono_mempool_alloc0 (cfg->mempool, mono_bitset_alloc_size (header->code_size, 0)), header->code_size, 0);
                        sym_seq_points = TRUE;
                        for (i = 0; i < n_il_offsets; ++i) {
                                if (il_offsets [i] < header->code_size)
@@ -6721,6 +6723,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        //if (!(cfg->cbb->last_ins && cfg->cbb->last_ins->opcode == OP_SEQ_POINT)) {
                        NEW_SEQ_POINT (cfg, ins, ip - header->code, intr_loc);
                        MONO_ADD_INS (cfg->cbb, ins);
+
+                       if (sym_seq_points)
+                               mono_bitset_set_fast (seq_point_set_locs, ip - header->code);
                }
 
                bblock->real_offset = cfg->real_offset;
@@ -11449,6 +11454,21 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                MONO_ADD_INS (cfg->bb_exit, ins);
        }
 
+       /*
+        * Add seq points for IL offsets which have line number info, but wasn't generated a seq point during JITting because
+        * the code they refer to was dead (#11880).
+        */
+       if (sym_seq_points) {
+               for (i = 0; i < header->code_size; ++i) {
+                       if (mono_bitset_test_fast (seq_point_locs, i) && !mono_bitset_test_fast (seq_point_set_locs, i)) {
+                               MonoInst *ins;
+
+                               NEW_SEQ_POINT (cfg, ins, i, FALSE);
+                               mono_add_seq_point (cfg, NULL, ins, SEQ_POINT_NATIVE_OFFSET_DEAD_CODE);
+                       }
+               }
+       }
+
        cfg->ip = NULL;
 
        if (cfg->method == method) {
index 552d0827c8b9065b741e6bd5f9725592f8405dda..310deece77e2f243b44b7f8ba5edf7b37ab12b4e 100644 (file)
@@ -3414,8 +3414,10 @@ mono_add_seq_point (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int nat
 {
        ins->inst_offset = native_offset;
        g_ptr_array_add (cfg->seq_points, ins);
-       bb->seq_points = g_slist_prepend_mempool (cfg->mempool, bb->seq_points, ins);
-       bb->last_seq_point = ins;
+       if (bb) {
+               bb->seq_points = g_slist_prepend_mempool (cfg->mempool, bb->seq_points, ins);
+               bb->last_seq_point = ins;
+       }
 }
 
 void
@@ -3673,6 +3675,8 @@ mono_save_seq_point_info (MonoCompile *cfg)
                        if (ins->inst_imm == METHOD_ENTRY_IL_OFFSET || ins->inst_imm == METHOD_EXIT_IL_OFFSET)
                                /* Used to implement method entry/exit events */
                                continue;
+                       if (ins->inst_offset == SEQ_POINT_NATIVE_OFFSET_DEAD_CODE)
+                               continue;
 
                        if (last != NULL) {
                                /* Link with the previous seq point in the same bb */