ruby-debug-base19 0.11.19 → 0.11.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/ruby_debug/ruby_debug.c +62 -7
- data/ext/ruby_debug/ruby_debug.h +7 -0
- metadata +1 -1
data/ext/ruby_debug/ruby_debug.c
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#include <vm_core.h>
|
5
5
|
#include <iseq.h>
|
6
6
|
#include <version.h>
|
7
|
+
#include <eval_intern.h>
|
7
8
|
#include <insns.inc>
|
8
9
|
#include <insns_info.inc>
|
9
10
|
#include "ruby_debug.h"
|
@@ -386,6 +387,7 @@ debug_context_create(VALUE thread)
|
|
386
387
|
debug_context->breakpoint = Qnil;
|
387
388
|
debug_context->jump_pc = NULL;
|
388
389
|
debug_context->jump_cfp = NULL;
|
390
|
+
debug_context->old_iseq_catch = NULL;
|
389
391
|
if(rb_obj_class(thread) == cDebugThread)
|
390
392
|
CTX_FL_SET(debug_context, CTX_FL_IGNORE);
|
391
393
|
return Data_Wrap_Struct(cContext, debug_context_mark, debug_context_free, debug_context);
|
@@ -684,7 +686,7 @@ create_catch_table(debug_context_t *debug_context, unsigned long cont)
|
|
684
686
|
catch_table->type = CATCH_TYPE_RESCUE;
|
685
687
|
catch_table->start = 0;
|
686
688
|
catch_table->end = ULONG_MAX;
|
687
|
-
catch_table->cont = cont
|
689
|
+
catch_table->cont = cont;
|
688
690
|
catch_table->sp = 0;
|
689
691
|
|
690
692
|
return(catch_table);
|
@@ -769,6 +771,20 @@ debug_event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE kl
|
|
769
771
|
/* only the current thread can proceed */
|
770
772
|
locker = thread->self;
|
771
773
|
|
774
|
+
/* restore catch tables removed for jump */
|
775
|
+
if (debug_context->old_iseq_catch != NULL)
|
776
|
+
{
|
777
|
+
int i = 0;
|
778
|
+
while (debug_context->old_iseq_catch[i].iseq != NULL)
|
779
|
+
{
|
780
|
+
debug_context->old_iseq_catch[i].iseq->catch_table = debug_context->old_iseq_catch[i].catch_table;
|
781
|
+
debug_context->old_iseq_catch[i].iseq->catch_table_size = debug_context->old_iseq_catch[i].catch_table_size;
|
782
|
+
i++;
|
783
|
+
}
|
784
|
+
free(debug_context->old_iseq_catch);
|
785
|
+
debug_context->old_iseq_catch = NULL;
|
786
|
+
}
|
787
|
+
|
772
788
|
/* make sure all threads have event flag set so we'll get its events */
|
773
789
|
st_foreach(thread->vm->living_threads, set_thread_event_flag_i, 0);
|
774
790
|
|
@@ -1024,7 +1040,7 @@ debug_event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE kl
|
|
1024
1040
|
/* create a new catch table to catch this exception, and put it in the current iseq */
|
1025
1041
|
cfp->iseq->catch_table_size = 1;
|
1026
1042
|
cfp->iseq->catch_table =
|
1027
|
-
create_catch_table(debug_context, top_frame->info.runtime.last_pc - cfp->iseq->iseq_encoded);
|
1043
|
+
create_catch_table(debug_context, top_frame->info.runtime.last_pc - cfp->iseq->iseq_encoded - insn_len(BIN(trace)));
|
1028
1044
|
break;
|
1029
1045
|
}
|
1030
1046
|
}
|
@@ -2276,6 +2292,8 @@ FUNC_FASTCALL(do_jump)(rb_thread_t *th, rb_control_frame_t *cfp)
|
|
2276
2292
|
{
|
2277
2293
|
VALUE context;
|
2278
2294
|
debug_context_t *debug_context;
|
2295
|
+
rb_control_frame_t *jump_cfp;
|
2296
|
+
VALUE *jump_pc;
|
2279
2297
|
|
2280
2298
|
thread_context_lookup(th->self, &context, &debug_context, 0);
|
2281
2299
|
if (debug_context == NULL)
|
@@ -2283,17 +2301,54 @@ FUNC_FASTCALL(do_jump)(rb_thread_t *th, rb_control_frame_t *cfp)
|
|
2283
2301
|
cfp->pc[-2] = debug_context->saved_jump_ins[0];
|
2284
2302
|
cfp->pc[-1] = debug_context->saved_jump_ins[1];
|
2285
2303
|
|
2286
|
-
|
2287
|
-
|
2304
|
+
if ((debug_context->jump_pc < debug_context->jump_cfp->iseq->iseq_encoded) ||
|
2305
|
+
(debug_context->jump_pc >= debug_context->jump_cfp->iseq->iseq_encoded + cfp->iseq->iseq_size))
|
2288
2306
|
rb_raise(rb_eRuntimeError, "Invalid jump PC target");
|
2289
|
-
cfp->pc = debug_context->jump_pc;
|
2290
2307
|
|
2308
|
+
jump_cfp = debug_context->jump_cfp;
|
2309
|
+
jump_pc = debug_context->jump_pc;
|
2291
2310
|
debug_context->jump_pc = NULL;
|
2292
2311
|
debug_context->jump_cfp = NULL;
|
2293
2312
|
debug_context->last_line = 0;
|
2294
2313
|
debug_context->last_file = NULL;
|
2295
2314
|
debug_context->stop_next = 1;
|
2296
|
-
|
2315
|
+
|
2316
|
+
if (cfp < jump_cfp)
|
2317
|
+
{
|
2318
|
+
/* save all intermediate-frame catch tables
|
2319
|
+
+1 for target frame
|
2320
|
+
+1 for array terminator
|
2321
|
+
*/
|
2322
|
+
int frames = jump_cfp - cfp + 2;
|
2323
|
+
debug_context->old_iseq_catch = (iseq_catch_t*)malloc(frames * sizeof(iseq_catch_t));
|
2324
|
+
MEMZERO(debug_context->old_iseq_catch, iseq_catch_t, frames);
|
2325
|
+
frames = 0;
|
2326
|
+
do
|
2327
|
+
{
|
2328
|
+
if (cfp->iseq != NULL)
|
2329
|
+
{
|
2330
|
+
debug_context->old_iseq_catch[frames].iseq = cfp->iseq;
|
2331
|
+
debug_context->old_iseq_catch[frames].catch_table = cfp->iseq->catch_table;
|
2332
|
+
debug_context->old_iseq_catch[frames].catch_table_size = cfp->iseq->catch_table_size;
|
2333
|
+
cfp->iseq->catch_table = NULL;
|
2334
|
+
cfp->iseq->catch_table_size = 0;
|
2335
|
+
|
2336
|
+
frames++;
|
2337
|
+
}
|
2338
|
+
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
2339
|
+
} while (cfp <= jump_cfp);
|
2340
|
+
|
2341
|
+
jump_cfp->iseq->catch_table_size = 1;
|
2342
|
+
jump_cfp->iseq->catch_table =
|
2343
|
+
create_catch_table(debug_context, jump_pc - jump_cfp->iseq->iseq_encoded);
|
2344
|
+
jump_cfp->iseq->catch_table->sp = -1;
|
2345
|
+
|
2346
|
+
JUMP_TAG(TAG_RAISE);
|
2347
|
+
}
|
2348
|
+
else if (cfp > jump_cfp)
|
2349
|
+
rb_raise(rb_eRuntimeError, "Invalid jump frame target");
|
2350
|
+
|
2351
|
+
cfp->pc = jump_pc;
|
2297
2352
|
return(cfp);
|
2298
2353
|
}
|
2299
2354
|
|
@@ -2356,7 +2411,7 @@ context_jump(int argc, VALUE *argv, VALUE self)
|
|
2356
2411
|
if (cfp->iseq->insn_info_table[i].line_no != line)
|
2357
2412
|
continue;
|
2358
2413
|
|
2359
|
-
/* hijack the currently running code so that we can change the frame PC
|
2414
|
+
/* hijack the currently running code so that we can change the frame PC */
|
2360
2415
|
debug_context->saved_jump_ins[0] = cfp_start->pc[0];
|
2361
2416
|
debug_context->saved_jump_ins[1] = cfp_start->pc[1];
|
2362
2417
|
cfp_start->pc[0] = opt_call_c_function;
|
data/ext/ruby_debug/ruby_debug.h
CHANGED
@@ -26,6 +26,12 @@ typedef struct {
|
|
26
26
|
VALUE errinfo;
|
27
27
|
} debug_catch_t;
|
28
28
|
|
29
|
+
typedef struct {
|
30
|
+
struct rb_iseq_struct *iseq;
|
31
|
+
struct iseq_catch_table_entry *catch_table;
|
32
|
+
int catch_table_size;
|
33
|
+
} iseq_catch_t;
|
34
|
+
|
29
35
|
typedef struct {
|
30
36
|
int argc; /* Number of arguments a frame should have. */
|
31
37
|
VALUE binding;
|
@@ -71,6 +77,7 @@ typedef struct {
|
|
71
77
|
VALUE saved_jump_ins[2];
|
72
78
|
rb_control_frame_t *jump_cfp;
|
73
79
|
VALUE *jump_pc;
|
80
|
+
iseq_catch_t *old_iseq_catch;
|
74
81
|
} debug_context_t;
|
75
82
|
|
76
83
|
/* variables in ruby_debug.c */
|