ruby-debug-base19 0.11.19 → 0.11.20
Sign up to get free protection for your applications and to get access to all the features.
- 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 */
|