ruby-debug 0.7.2-mswin32 → 0.7.3-mswin32
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +6 -1
- data/ext/ruby_debug.c +225 -239
- data/lib/ruby-debug/commands/settings.rb +2 -2
- data/lib/ruby-debug/interface.rb +2 -2
- data/lib/ruby-debug.rb +0 -7
- data/lib/ruby_debug.so +0 -0
- metadata +2 -2
data/CHANGES
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
0.7.3
|
2
|
+
- Fixed a case when a frame is not popped up properly.
|
3
|
+
- Removed Context.ignore= method, since it can result with the segmentation fault error.
|
4
|
+
- Fixed the case when Context#suspend may effect the state of the thread on Context#resume
|
5
|
+
- Fixed several cases of seg faults when accessing dyna_vars structure.
|
6
|
+
|
1
7
|
0.7.2
|
2
|
-
- Fixed a case when a frame is not popped up properly (ruby's bug!).
|
3
8
|
- Fixed Context#resume (a thread should be waked up only when it was running when it wsa suspened).
|
4
9
|
- When handling post-mortem exception, all threads must be suspended.
|
5
10
|
|
data/ext/ruby_debug.c
CHANGED
@@ -4,35 +4,35 @@
|
|
4
4
|
#include <rubysig.h>
|
5
5
|
#include <st.h>
|
6
6
|
|
7
|
-
#define DEBUG_VERSION "0.7.
|
7
|
+
#define DEBUG_VERSION "0.7.3"
|
8
8
|
|
9
9
|
#ifdef _WIN32
|
10
10
|
struct FRAME {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
11
|
+
VALUE self;
|
12
|
+
int argc;
|
13
|
+
ID last_func;
|
14
|
+
ID orig_func;
|
15
|
+
VALUE last_class;
|
16
|
+
struct FRAME *prev;
|
17
|
+
struct FRAME *tmp;
|
18
|
+
struct RNode *node;
|
19
|
+
int iter;
|
20
|
+
int flags;
|
21
|
+
unsigned long uniq;
|
22
22
|
};
|
23
23
|
|
24
24
|
struct SCOPE {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
struct RBasic super;
|
26
|
+
ID *local_tbl;
|
27
|
+
VALUE *local_vars;
|
28
|
+
int flags;
|
29
29
|
};
|
30
30
|
|
31
31
|
struct RVarmap {
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
struct RBasic super;
|
33
|
+
ID id;
|
34
|
+
VALUE val;
|
35
|
+
struct RVarmap *next;
|
36
36
|
};
|
37
37
|
|
38
38
|
RUBY_EXTERN struct SCOPE *ruby_scope;
|
@@ -67,7 +67,7 @@ RUBY_EXTERN struct RVarmap *ruby_dyna_vars;
|
|
67
67
|
#endif
|
68
68
|
|
69
69
|
#define STACK_SIZE_INCREMENT 128
|
70
|
-
|
70
|
+
|
71
71
|
typedef struct {
|
72
72
|
VALUE binding;
|
73
73
|
ID id;
|
@@ -76,14 +76,14 @@ typedef struct {
|
|
76
76
|
short dead;
|
77
77
|
VALUE self;
|
78
78
|
union {
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
79
|
+
struct {
|
80
|
+
struct FRAME *frame;
|
81
|
+
struct SCOPE *scope;
|
82
|
+
struct RVarmap *dyna_vars;
|
83
|
+
} runtime;
|
84
|
+
struct {
|
85
|
+
VALUE locals;
|
86
|
+
} copy;
|
87
87
|
} info;
|
88
88
|
} debug_frame_t;
|
89
89
|
|
@@ -136,6 +136,7 @@ static VALUE mDebugger;
|
|
136
136
|
static VALUE cThreadsTable;
|
137
137
|
static VALUE cContext;
|
138
138
|
static VALUE cBreakpoint;
|
139
|
+
static VALUE cDebugThread;
|
139
140
|
|
140
141
|
static VALUE rb_mObjectSpace;
|
141
142
|
|
@@ -160,7 +161,7 @@ static VALUE context_copy_locals(debug_frame_t *);
|
|
160
161
|
static void context_suspend_0(debug_context_t *);
|
161
162
|
static void context_resume_0(debug_context_t *);
|
162
163
|
|
163
|
-
typedef struct locked_thread_t {
|
164
|
+
typedef struct locked_thread_t {
|
164
165
|
VALUE thread_id;
|
165
166
|
struct locked_thread_t *next;
|
166
167
|
} locked_thread_t;
|
@@ -218,10 +219,10 @@ static int
|
|
218
219
|
is_in_locked(VALUE thread_id)
|
219
220
|
{
|
220
221
|
locked_thread_t *node;
|
221
|
-
|
222
|
+
|
222
223
|
if(!locked_head)
|
223
224
|
return 0;
|
224
|
-
|
225
|
+
|
225
226
|
for(node = locked_head; node != locked_tail; node = node->next)
|
226
227
|
{
|
227
228
|
if(node->thread_id == thread_id) return 1;
|
@@ -234,7 +235,7 @@ add_to_locked(VALUE thread)
|
|
234
235
|
{
|
235
236
|
locked_thread_t *node;
|
236
237
|
VALUE thread_id = ref2id(thread);
|
237
|
-
|
238
|
+
|
238
239
|
if(is_in_locked(thread_id))
|
239
240
|
return;
|
240
241
|
|
@@ -253,7 +254,7 @@ remove_from_locked()
|
|
253
254
|
{
|
254
255
|
VALUE thread;
|
255
256
|
locked_thread_t *node;
|
256
|
-
|
257
|
+
|
257
258
|
if(locked_head == NULL)
|
258
259
|
return Qnil;
|
259
260
|
node = locked_head;
|
@@ -291,7 +292,7 @@ static VALUE
|
|
291
292
|
threads_table_create()
|
292
293
|
{
|
293
294
|
threads_table_t *threads_table;
|
294
|
-
|
295
|
+
|
295
296
|
threads_table = ALLOC(threads_table_t);
|
296
297
|
threads_table->tbl = st_init_numtable();
|
297
298
|
return Data_Wrap_Struct(cThreadsTable, threads_table_mark, threads_table_free, threads_table);
|
@@ -307,7 +308,7 @@ static void
|
|
307
308
|
threads_table_clear(VALUE table)
|
308
309
|
{
|
309
310
|
threads_table_t *threads_table;
|
310
|
-
|
311
|
+
|
311
312
|
Data_Get_Struct(table, threads_table_t, threads_table);
|
312
313
|
st_foreach(threads_table->tbl, threads_table_clear_i, 0);
|
313
314
|
}
|
@@ -328,7 +329,7 @@ static int
|
|
328
329
|
threads_table_check_i(VALUE key, VALUE value, VALUE dummy)
|
329
330
|
{
|
330
331
|
VALUE thread;
|
331
|
-
|
332
|
+
|
332
333
|
thread = id2ref(key);
|
333
334
|
if(!rb_obj_is_kind_of(thread, rb_cThread))
|
334
335
|
{
|
@@ -353,7 +354,7 @@ check_thread_contexts()
|
|
353
354
|
/*
|
354
355
|
* call-seq:
|
355
356
|
* Debugger.started? -> bool
|
356
|
-
*
|
357
|
+
*
|
357
358
|
* Returns +true+ the debugger is started.
|
358
359
|
*/
|
359
360
|
static VALUE
|
@@ -376,17 +377,17 @@ debug_context_mark(void *data)
|
|
376
377
|
{
|
377
378
|
debug_frame_t *frame;
|
378
379
|
int i;
|
379
|
-
|
380
|
+
|
380
381
|
debug_context_t *debug_context = (debug_context_t *)data;
|
381
382
|
for(i = 0; i < debug_context->stack_size; i++)
|
382
383
|
{
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
384
|
+
frame = &(debug_context->frames[i]);
|
385
|
+
rb_gc_mark(frame->binding);
|
386
|
+
rb_gc_mark(frame->self);
|
387
|
+
if(frame->dead)
|
388
|
+
{
|
389
|
+
rb_gc_mark(frame->info.copy.locals);
|
390
|
+
}
|
390
391
|
}
|
391
392
|
}
|
392
393
|
|
@@ -401,10 +402,10 @@ static VALUE
|
|
401
402
|
debug_context_create(VALUE thread)
|
402
403
|
{
|
403
404
|
debug_context_t *debug_context;
|
404
|
-
|
405
|
+
|
405
406
|
debug_context = ALLOC(debug_context_t);
|
406
407
|
debug_context-> thnum = ++thnum_max;
|
407
|
-
|
408
|
+
|
408
409
|
debug_context->last_file = NULL;
|
409
410
|
debug_context->last_line = 0;
|
410
411
|
debug_context->flags = 0;
|
@@ -417,6 +418,8 @@ debug_context_create(VALUE thread)
|
|
417
418
|
debug_context->frames = ALLOC_N(debug_frame_t, STACK_SIZE_INCREMENT);
|
418
419
|
debug_context->stack_size = 0;
|
419
420
|
debug_context->thread_id = ref2id(thread);
|
421
|
+
if(rb_obj_class(thread) == cDebugThread)
|
422
|
+
CTX_FL_SET(debug_context, CTX_FL_IGNORE);
|
420
423
|
return Data_Wrap_Struct(cContext, debug_context_mark, debug_context_free, debug_context);
|
421
424
|
}
|
422
425
|
|
@@ -439,10 +442,10 @@ debug_context_dup(debug_context_t *debug_context)
|
|
439
442
|
memcpy(new_debug_context->frames, debug_context->frames, sizeof(debug_frame_t) * debug_context->stack_size);
|
440
443
|
for(i = 0; i < debug_context->stack_size; i++)
|
441
444
|
{
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
445
|
+
new_frame = &(new_debug_context->frames[i]);
|
446
|
+
old_frame = &(debug_context->frames[i]);
|
447
|
+
new_frame->dead = 1;
|
448
|
+
new_frame->info.copy.locals = context_copy_locals(old_frame);
|
446
449
|
}
|
447
450
|
return Data_Wrap_Struct(cContext, debug_context_mark, debug_context_free, new_debug_context);
|
448
451
|
}
|
@@ -470,7 +473,7 @@ thread_context_lookup(VALUE thread, VALUE *context, debug_context_t **debug_cont
|
|
470
473
|
*context = debug_context_create(thread);
|
471
474
|
st_insert(threads_table->tbl, thread_id, *context);
|
472
475
|
}
|
473
|
-
|
476
|
+
|
474
477
|
Data_Get_Struct(*context, debug_context_t, l_debug_context);
|
475
478
|
if(debug_context)
|
476
479
|
*debug_context = l_debug_context;
|
@@ -492,28 +495,28 @@ static VALUE
|
|
492
495
|
call_at_line(VALUE context, debug_context_t *debug_context, VALUE file, VALUE line)
|
493
496
|
{
|
494
497
|
VALUE args;
|
495
|
-
|
498
|
+
|
496
499
|
last_debugged_thnum = debug_context->thnum;
|
497
500
|
save_current_position(debug_context);
|
498
|
-
|
501
|
+
|
499
502
|
args = rb_ary_new3(3, context, file, line);
|
500
503
|
return rb_protect(call_at_line_unprotected, args, 0);
|
501
504
|
}
|
502
505
|
|
503
506
|
static void
|
504
|
-
save_call_frame(VALUE self, char *file, int line, ID mid, debug_context_t *debug_context)
|
507
|
+
save_call_frame(rb_event_t event, VALUE self, char *file, int line, ID mid, debug_context_t *debug_context)
|
505
508
|
{
|
506
509
|
VALUE binding;
|
507
510
|
debug_frame_t *debug_frame;
|
508
511
|
int frame_n;
|
509
|
-
|
512
|
+
|
510
513
|
binding = self && RTEST(keep_frame_binding)? create_binding(self) : Qnil;
|
511
|
-
|
514
|
+
|
512
515
|
frame_n = debug_context->stack_size++;
|
513
516
|
if(frame_n >= debug_context->stack_len)
|
514
517
|
{
|
515
|
-
|
516
|
-
|
518
|
+
debug_context->stack_len += STACK_SIZE_INCREMENT;
|
519
|
+
debug_context->frames = REALLOC_N(debug_context->frames, debug_frame_t, debug_context->stack_len);
|
517
520
|
}
|
518
521
|
debug_frame = &debug_context->frames[frame_n];
|
519
522
|
debug_frame->file = file;
|
@@ -524,8 +527,7 @@ save_call_frame(VALUE self, char *file, int line, ID mid, debug_context_t *debug
|
|
524
527
|
debug_frame->self = self;
|
525
528
|
debug_frame->info.runtime.frame = ruby_frame;
|
526
529
|
debug_frame->info.runtime.scope = ruby_scope;
|
527
|
-
|
528
|
-
debug_frame->info.runtime.dyna_vars = ruby_dyna_vars;
|
530
|
+
debug_frame->info.runtime.dyna_vars = event == RUBY_EVENT_LINE ? ruby_dyna_vars : NULL;
|
529
531
|
}
|
530
532
|
|
531
533
|
#if defined DOSISH
|
@@ -541,14 +543,14 @@ filename_cmp(VALUE source, char *file)
|
|
541
543
|
int s_len, f_len, min_len;
|
542
544
|
int s,f;
|
543
545
|
int dirsep_flag = 0;
|
544
|
-
|
546
|
+
|
545
547
|
s_len = RSTRING(source)->len;
|
546
548
|
f_len = strlen(file);
|
547
549
|
min_len = min(s_len, f_len);
|
548
|
-
|
550
|
+
|
549
551
|
source_ptr = RSTRING(source)->ptr;
|
550
552
|
file_ptr = file;
|
551
|
-
|
553
|
+
|
552
554
|
for( s = s_len - 1, f = f_len - 1; s >= s_len - min_len && f >= f_len - min_len; s--, f-- )
|
553
555
|
{
|
554
556
|
if((source_ptr[s] == '.' || file_ptr[f] == '.') && dirsep_flag)
|
@@ -564,7 +566,7 @@ filename_cmp(VALUE source, char *file)
|
|
564
566
|
static int
|
565
567
|
check_breakpoints_by_pos(debug_context_t *debug_context, char *file, int line)
|
566
568
|
{
|
567
|
-
VALUE breakpoint;
|
569
|
+
VALUE breakpoint;
|
568
570
|
debug_breakpoint_t *debug_breakpoint;
|
569
571
|
int i;
|
570
572
|
|
@@ -572,7 +574,7 @@ check_breakpoints_by_pos(debug_context_t *debug_context, char *file, int line)
|
|
572
574
|
return -1;
|
573
575
|
if(!CTX_FL_TEST(debug_context, CTX_FL_MOVED))
|
574
576
|
return -1;
|
575
|
-
|
577
|
+
|
576
578
|
for(i = 0; i < RARRAY(breakpoints)->len; i++)
|
577
579
|
{
|
578
580
|
breakpoint = rb_ary_entry(breakpoints, i);
|
@@ -596,10 +598,10 @@ classname_cmp(VALUE name, VALUE klass)
|
|
596
598
|
static int
|
597
599
|
check_breakpoints_by_method(debug_context_t *debug_context, VALUE klass, ID mid)
|
598
600
|
{
|
599
|
-
VALUE breakpoint;
|
601
|
+
VALUE breakpoint;
|
600
602
|
debug_breakpoint_t *debug_breakpoint;
|
601
603
|
int i;
|
602
|
-
|
604
|
+
|
603
605
|
if(RARRAY(breakpoints)->len == 0)
|
604
606
|
return -1;
|
605
607
|
if(!CTX_FL_TEST(debug_context, CTX_FL_MOVED))
|
@@ -619,7 +621,7 @@ check_breakpoints_by_method(debug_context_t *debug_context, VALUE klass, ID mid)
|
|
619
621
|
}
|
620
622
|
|
621
623
|
/*
|
622
|
-
* This is a NASTY HACK. For some reasons rb_f_binding is decalred
|
624
|
+
* This is a NASTY HACK. For some reasons rb_f_binding is decalred
|
623
625
|
* static in eval.c
|
624
626
|
*/
|
625
627
|
static VALUE
|
@@ -636,7 +638,7 @@ create_binding(VALUE self)
|
|
636
638
|
}
|
637
639
|
|
638
640
|
static VALUE
|
639
|
-
get_breakpoint_at(int index)
|
641
|
+
get_breakpoint_at(int index)
|
640
642
|
{
|
641
643
|
return rb_ary_entry(breakpoints, index);
|
642
644
|
}
|
@@ -652,11 +654,11 @@ check_breakpoint_expression(VALUE breakpoint, VALUE binding)
|
|
652
654
|
{
|
653
655
|
debug_breakpoint_t *debug_breakpoint;
|
654
656
|
VALUE args, expr_result;
|
655
|
-
|
657
|
+
|
656
658
|
Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
|
657
659
|
if(NIL_P(debug_breakpoint->expr))
|
658
660
|
return 1;
|
659
|
-
|
661
|
+
|
660
662
|
args = rb_ary_new3(2, debug_breakpoint->expr, binding);
|
661
663
|
expr_result = rb_protect(eval_expression, args, 0);
|
662
664
|
return RTEST(expr_result);
|
@@ -667,8 +669,8 @@ get_top_frame(debug_context_t *debug_context)
|
|
667
669
|
{
|
668
670
|
if(debug_context->stack_size == 0)
|
669
671
|
return NULL;
|
670
|
-
else
|
671
|
-
|
672
|
+
else
|
673
|
+
return &(debug_context->frames[debug_context->stack_size-1]);
|
672
674
|
}
|
673
675
|
|
674
676
|
inline static void
|
@@ -681,25 +683,16 @@ save_top_binding(debug_context_t *debug_context, VALUE binding)
|
|
681
683
|
}
|
682
684
|
|
683
685
|
inline static void
|
684
|
-
set_frame_source(debug_context_t *debug_context, char *file, int line)
|
686
|
+
set_frame_source(rb_event_t event, debug_context_t *debug_context, VALUE self, char *file, int line)
|
685
687
|
{
|
686
688
|
debug_frame_t *top_frame;
|
687
689
|
top_frame = get_top_frame(debug_context);
|
688
690
|
if(top_frame)
|
689
691
|
{
|
692
|
+
top_frame->self = self;
|
690
693
|
top_frame->file = file;
|
691
694
|
top_frame->line = line;
|
692
|
-
|
693
|
-
}
|
694
|
-
|
695
|
-
inline static void
|
696
|
-
set_dyna_vars(debug_context_t *debug_context)
|
697
|
-
{
|
698
|
-
debug_frame_t *top_frame;
|
699
|
-
top_frame = get_top_frame(debug_context);
|
700
|
-
if(top_frame)
|
701
|
-
{
|
702
|
-
top_frame->info.runtime.dyna_vars = ruby_dyna_vars;
|
695
|
+
top_frame->info.runtime.dyna_vars = event == RUBY_EVENT_C_CALL ? NULL : ruby_dyna_vars;
|
703
696
|
}
|
704
697
|
}
|
705
698
|
|
@@ -707,7 +700,7 @@ static void
|
|
707
700
|
save_current_position(debug_context_t *debug_context)
|
708
701
|
{
|
709
702
|
debug_frame_t *debug_frame;
|
710
|
-
|
703
|
+
|
711
704
|
debug_frame = get_top_frame(debug_context);
|
712
705
|
if(!debug_frame) return;
|
713
706
|
debug_context->last_file = debug_frame->file;
|
@@ -750,20 +743,19 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
750
743
|
char *file;
|
751
744
|
int line;
|
752
745
|
int breakpoint_index = -1;
|
753
|
-
|
746
|
+
|
754
747
|
hook_count++;
|
755
|
-
|
748
|
+
|
756
749
|
if (mid == ID_ALLOCATOR) return;
|
757
|
-
if(!node) return;
|
758
750
|
|
759
751
|
thread = rb_thread_current();
|
760
752
|
thread_context_lookup(thread, &context, &debug_context);
|
761
|
-
|
753
|
+
|
762
754
|
/* return if thread is marked as 'ignored'.
|
763
755
|
debugger's threads are marked this way
|
764
756
|
*/
|
765
757
|
if(CTX_FL_TEST(debug_context, CTX_FL_IGNORE)) return;
|
766
|
-
|
758
|
+
|
767
759
|
while(1)
|
768
760
|
{
|
769
761
|
/* halt execution of the current thread if the debugger
|
@@ -777,21 +769,30 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
777
769
|
|
778
770
|
/* stop the current thread if it's marked as suspended */
|
779
771
|
if(CTX_FL_TEST(debug_context, CTX_FL_SUSPEND))
|
772
|
+
{
|
773
|
+
CTX_FL_SET(debug_context, CTX_FL_WAS_RUNNING);
|
780
774
|
rb_thread_stop();
|
775
|
+
}
|
781
776
|
else break;
|
782
777
|
}
|
783
|
-
|
778
|
+
|
784
779
|
/* return if the current thread is the locker */
|
785
780
|
if(locker != Qnil) return;
|
786
|
-
|
781
|
+
|
787
782
|
/* only the current thread can proceed */
|
788
783
|
locker = thread;
|
789
784
|
|
790
785
|
/* ignore a skipped section of code */
|
791
786
|
if(CTX_FL_TEST(debug_context, CTX_FL_SKIPPED)) goto cleanup;
|
792
787
|
|
793
|
-
|
794
|
-
|
788
|
+
if(!node && !(event == RUBY_EVENT_RETURN || event == RUBY_EVENT_C_RETURN))
|
789
|
+
goto cleanup;
|
790
|
+
|
791
|
+
if(node)
|
792
|
+
{
|
793
|
+
file = node->nd_file;
|
794
|
+
line = nd_line(node);
|
795
|
+
}
|
795
796
|
|
796
797
|
if(DID_MOVED)
|
797
798
|
CTX_FL_SET(debug_context, CTX_FL_MOVED);
|
@@ -800,13 +801,12 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
800
801
|
{
|
801
802
|
case RUBY_EVENT_LINE:
|
802
803
|
{
|
803
|
-
set_frame_source(debug_context, file, line);
|
804
|
-
set_dyna_vars(debug_context);
|
804
|
+
set_frame_source(event, debug_context, self, file, line);
|
805
805
|
|
806
806
|
if(RTEST(tracing) || CTX_FL_TEST(debug_context, CTX_FL_TRACING))
|
807
807
|
rb_funcall(context, idAtTracing, 2, rb_str_new2(file), INT2FIX(line));
|
808
|
-
|
809
|
-
if(debug_context->dest_frame == -1 ||
|
808
|
+
|
809
|
+
if(debug_context->dest_frame == -1 ||
|
810
810
|
debug_context->stack_size == debug_context->dest_frame)
|
811
811
|
{
|
812
812
|
debug_context->stop_next--;
|
@@ -822,7 +822,7 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
822
822
|
}
|
823
823
|
|
824
824
|
if(debug_context->stack_size == 0)
|
825
|
-
save_call_frame(self, file, line, mid, debug_context);
|
825
|
+
save_call_frame(event, self, file, line, mid, debug_context);
|
826
826
|
|
827
827
|
if(debug_context->stop_next == 0 || debug_context->stop_line == 0 ||
|
828
828
|
(breakpoint_index = check_breakpoints_by_pos(debug_context, file, line)) != -1)
|
@@ -850,12 +850,12 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
850
850
|
}
|
851
851
|
case RUBY_EVENT_C_CALL:
|
852
852
|
{
|
853
|
-
set_frame_source(debug_context, file, line);
|
853
|
+
set_frame_source(event, debug_context, self, file, line);
|
854
854
|
break;
|
855
855
|
}
|
856
856
|
case RUBY_EVENT_CALL:
|
857
857
|
{
|
858
|
-
save_call_frame(self, file, line, mid, debug_context);
|
858
|
+
save_call_frame(event, self, file, line, mid, debug_context);
|
859
859
|
breakpoint_index = check_breakpoints_by_method(debug_context, klass, mid);
|
860
860
|
if(breakpoint_index != -1)
|
861
861
|
{
|
@@ -883,20 +883,13 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
883
883
|
debug_context->stop_next = 1;
|
884
884
|
debug_context->stop_frame = 0;
|
885
885
|
}
|
886
|
-
|
887
|
-
|
888
|
-
// For example, it happens when singleton methods are called.
|
889
|
-
while(debug_context->stack_size > 0)
|
890
|
-
{
|
891
|
-
debug_context->stack_size--;
|
892
|
-
if(debug_context->frames[debug_context->stack_size].id == mid)
|
893
|
-
break;
|
894
|
-
}
|
886
|
+
if(debug_context->stack_size > 0)
|
887
|
+
debug_context->stack_size--;
|
895
888
|
break;
|
896
889
|
}
|
897
890
|
case RUBY_EVENT_CLASS:
|
898
891
|
{
|
899
|
-
save_call_frame(self, file, line, mid, debug_context);
|
892
|
+
save_call_frame(event, self, file, line, mid, debug_context);
|
900
893
|
break;
|
901
894
|
}
|
902
895
|
case RUBY_EVENT_RAISE:
|
@@ -904,7 +897,9 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
904
897
|
VALUE ancestors;
|
905
898
|
VALUE expn_class, aclass;
|
906
899
|
int i;
|
907
|
-
|
900
|
+
|
901
|
+
set_frame_source(event, debug_context, self, file, line);
|
902
|
+
|
908
903
|
if(post_mortem == Qtrue && self)
|
909
904
|
{
|
910
905
|
binding = create_binding(self);
|
@@ -948,14 +943,14 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
948
943
|
}
|
949
944
|
|
950
945
|
cleanup:
|
951
|
-
|
946
|
+
|
952
947
|
/* check that all contexts point to alive threads */
|
953
948
|
if(hook_count - last_check > 3000)
|
954
949
|
{
|
955
950
|
check_thread_contexts();
|
956
951
|
last_check = hook_count;
|
957
952
|
}
|
958
|
-
|
953
|
+
|
959
954
|
/* release a lock */
|
960
955
|
locker = Qnil;
|
961
956
|
/* let the next thread to run */
|
@@ -976,13 +971,13 @@ debug_stop_i(VALUE self)
|
|
976
971
|
* call-seq:
|
977
972
|
* Debugger.start -> bool
|
978
973
|
* Debugger.start { ... } -> obj
|
979
|
-
*
|
980
|
-
* This method activates the debugger.
|
974
|
+
*
|
975
|
+
* This method activates the debugger.
|
981
976
|
* If it's called without a block it returns +true+, unless debugger was already started.
|
982
977
|
* If a block is given, it starts debugger and yields to block. When the block is finished
|
983
978
|
* executing it stops the debugger with Debugger.stop method.
|
984
979
|
*
|
985
|
-
* <i>Note that if you want to stop debugger, you must call Debugger.stop as many time as you
|
980
|
+
* <i>Note that if you want to stop debugger, you must call Debugger.stop as many time as you
|
986
981
|
* called Debugger.start method.</i>
|
987
982
|
*/
|
988
983
|
static VALUE
|
@@ -990,7 +985,7 @@ debug_start(VALUE self)
|
|
990
985
|
{
|
991
986
|
VALUE result;
|
992
987
|
start_count++;
|
993
|
-
|
988
|
+
|
994
989
|
if(IS_STARTED)
|
995
990
|
result = Qfalse;
|
996
991
|
else
|
@@ -1002,7 +997,7 @@ debug_start(VALUE self)
|
|
1002
997
|
rb_add_event_hook(debug_event_hook, RUBY_EVENT_ALL);
|
1003
998
|
result = Qtrue;
|
1004
999
|
}
|
1005
|
-
|
1000
|
+
|
1006
1001
|
if(rb_block_given_p())
|
1007
1002
|
return rb_ensure(rb_yield, self, debug_stop_i, self);
|
1008
1003
|
return result;
|
@@ -1011,22 +1006,22 @@ debug_start(VALUE self)
|
|
1011
1006
|
/*
|
1012
1007
|
* call-seq:
|
1013
1008
|
* Debugger.stop -> bool
|
1014
|
-
*
|
1015
|
-
* This method disacivates the debugger. It returns +true+ if the debugger is disacivated,
|
1009
|
+
*
|
1010
|
+
* This method disacivates the debugger. It returns +true+ if the debugger is disacivated,
|
1016
1011
|
* otherwise it returns +false+.
|
1017
1012
|
*
|
1018
|
-
* <i>Note that if you want to stop debugger, you must call Debugger.stop as many time as you
|
1013
|
+
* <i>Note that if you want to stop debugger, you must call Debugger.stop as many time as you
|
1019
1014
|
* called Debugger.start method.</i>
|
1020
1015
|
*/
|
1021
1016
|
static VALUE
|
1022
1017
|
debug_stop(VALUE self)
|
1023
1018
|
{
|
1024
1019
|
debug_check_started();
|
1025
|
-
|
1020
|
+
|
1026
1021
|
start_count--;
|
1027
1022
|
if(start_count)
|
1028
1023
|
return Qfalse;
|
1029
|
-
|
1024
|
+
|
1030
1025
|
rb_remove_event_hook(debug_event_hook);
|
1031
1026
|
|
1032
1027
|
locker = Qnil;
|
@@ -1048,7 +1043,7 @@ breakpoint_mark(void *data)
|
|
1048
1043
|
/*
|
1049
1044
|
* call-seq:
|
1050
1045
|
* Debugger.add_breakpoint(source, pos, condition = nil) -> breakpoint
|
1051
|
-
*
|
1046
|
+
*
|
1052
1047
|
* Adds a new breakpoint.
|
1053
1048
|
* <i>source</i> is a name of a file or a class.
|
1054
1049
|
* <i>pos</i> is a line number or a method name if <i>source</i> is a class name.
|
@@ -1064,7 +1059,7 @@ debug_add_breakpoint(int argc, VALUE *argv, VALUE self)
|
|
1064
1059
|
int type;
|
1065
1060
|
|
1066
1061
|
debug_check_started();
|
1067
|
-
|
1062
|
+
|
1068
1063
|
if(rb_scan_args(argc, argv, "21", &source, &pos, &expr) == 2)
|
1069
1064
|
{
|
1070
1065
|
expr = Qnil;
|
@@ -1091,7 +1086,7 @@ debug_add_breakpoint(int argc, VALUE *argv, VALUE self)
|
|
1091
1086
|
/*
|
1092
1087
|
* call-seq:
|
1093
1088
|
* Debugger.remove_breakpoint(id) -> breakpoint
|
1094
|
-
*
|
1089
|
+
*
|
1095
1090
|
* Removes breakpoint by its id.
|
1096
1091
|
* <i>id</i> is an identificator of a breakpoint.
|
1097
1092
|
*/
|
@@ -1102,9 +1097,9 @@ debug_remove_breakpoint(VALUE self, VALUE id_value)
|
|
1102
1097
|
int id;
|
1103
1098
|
VALUE breakpoint;
|
1104
1099
|
debug_breakpoint_t *debug_breakpoint;
|
1105
|
-
|
1100
|
+
|
1106
1101
|
id = FIX2INT(id_value);
|
1107
|
-
|
1102
|
+
|
1108
1103
|
for( i = 0; i < RARRAY(breakpoints)->len; i += 1 )
|
1109
1104
|
{
|
1110
1105
|
breakpoint = rb_ary_entry(breakpoints, i);
|
@@ -1121,7 +1116,7 @@ debug_remove_breakpoint(VALUE self, VALUE id_value)
|
|
1121
1116
|
/*
|
1122
1117
|
* call-seq:
|
1123
1118
|
* Debugger.breakpoints -> array
|
1124
|
-
*
|
1119
|
+
*
|
1125
1120
|
* Returns an array of breakpoints.
|
1126
1121
|
*/
|
1127
1122
|
static VALUE
|
@@ -1135,8 +1130,8 @@ debug_breakpoints(VALUE self)
|
|
1135
1130
|
/*
|
1136
1131
|
* call-seq:
|
1137
1132
|
* Debugger.checkpoint -> string
|
1138
|
-
*
|
1139
|
-
* Returns a current checkpoint, which is a name of exception that will
|
1133
|
+
*
|
1134
|
+
* Returns a current checkpoint, which is a name of exception that will
|
1140
1135
|
* trigger a debugger when raised.
|
1141
1136
|
*/
|
1142
1137
|
static VALUE
|
@@ -1150,7 +1145,7 @@ debug_catchpoint(VALUE self)
|
|
1150
1145
|
/*
|
1151
1146
|
* call-seq:
|
1152
1147
|
* Debugger.checkpoint = string -> string
|
1153
|
-
*
|
1148
|
+
*
|
1154
1149
|
* Sets checkpoint.
|
1155
1150
|
*/
|
1156
1151
|
static VALUE
|
@@ -1184,7 +1179,7 @@ find_last_context_func(VALUE key, VALUE value, VALUE *result)
|
|
1184
1179
|
/*
|
1185
1180
|
* call-seq:
|
1186
1181
|
* Debugger.last_interrupted -> context
|
1187
|
-
*
|
1182
|
+
*
|
1188
1183
|
* Returns last debugged context.
|
1189
1184
|
*/
|
1190
1185
|
static VALUE
|
@@ -1196,7 +1191,7 @@ debug_last_interrupted(VALUE self)
|
|
1196
1191
|
debug_check_started();
|
1197
1192
|
|
1198
1193
|
Data_Get_Struct(threads_tbl, threads_table_t, threads_table);
|
1199
|
-
|
1194
|
+
|
1200
1195
|
st_foreach(threads_table->tbl, find_last_context_func, (st_data_t)&result);
|
1201
1196
|
return result;
|
1202
1197
|
}
|
@@ -1204,8 +1199,8 @@ debug_last_interrupted(VALUE self)
|
|
1204
1199
|
/*
|
1205
1200
|
* call-seq:
|
1206
1201
|
* Debugger.current_context -> context
|
1207
|
-
*
|
1208
|
-
* Returns current context.
|
1202
|
+
*
|
1203
|
+
* Returns current context.
|
1209
1204
|
* <i>Note:</i> Debugger.current_context.thread == Thread.current
|
1210
1205
|
*/
|
1211
1206
|
static VALUE
|
@@ -1224,14 +1219,14 @@ debug_current_context(VALUE self)
|
|
1224
1219
|
/*
|
1225
1220
|
* call-seq:
|
1226
1221
|
* Debugger.thread_context(thread) -> context
|
1227
|
-
*
|
1228
|
-
* Returns context of the thread passed as an argument.
|
1222
|
+
*
|
1223
|
+
* Returns context of the thread passed as an argument.
|
1229
1224
|
*/
|
1230
1225
|
static VALUE
|
1231
1226
|
debug_thread_context(VALUE self, VALUE thread)
|
1232
1227
|
{
|
1233
1228
|
VALUE context;
|
1234
|
-
|
1229
|
+
|
1235
1230
|
debug_check_started();
|
1236
1231
|
thread_context_lookup(thread, &context, NULL);
|
1237
1232
|
return context;
|
@@ -1240,7 +1235,7 @@ debug_thread_context(VALUE self, VALUE thread)
|
|
1240
1235
|
/*
|
1241
1236
|
* call-seq:
|
1242
1237
|
* Debugger.contexts -> array
|
1243
|
-
*
|
1238
|
+
*
|
1244
1239
|
* Returns an array of all contexts.
|
1245
1240
|
*/
|
1246
1241
|
static VALUE
|
@@ -1278,7 +1273,7 @@ debug_contexts(VALUE self)
|
|
1278
1273
|
/*
|
1279
1274
|
* call-seq:
|
1280
1275
|
* Debugger.suspend -> Debugger
|
1281
|
-
*
|
1276
|
+
*
|
1282
1277
|
* Suspends all contexts.
|
1283
1278
|
*/
|
1284
1279
|
static VALUE
|
@@ -1303,7 +1298,7 @@ debug_suspend(VALUE self)
|
|
1303
1298
|
if(current == context)
|
1304
1299
|
continue;
|
1305
1300
|
Data_Get_Struct(context, debug_context_t, debug_context);
|
1306
|
-
|
1301
|
+
context_suspend_0(debug_context);
|
1307
1302
|
}
|
1308
1303
|
rb_thread_critical = saved_crit;
|
1309
1304
|
|
@@ -1316,7 +1311,7 @@ debug_suspend(VALUE self)
|
|
1316
1311
|
/*
|
1317
1312
|
* call-seq:
|
1318
1313
|
* Debugger.resume -> Debugger
|
1319
|
-
*
|
1314
|
+
*
|
1320
1315
|
* Resumes all contexts.
|
1321
1316
|
*/
|
1322
1317
|
static VALUE
|
@@ -1341,7 +1336,7 @@ debug_resume(VALUE self)
|
|
1341
1336
|
if(current == context)
|
1342
1337
|
continue;
|
1343
1338
|
Data_Get_Struct(context, debug_context_t, debug_context);
|
1344
|
-
|
1339
|
+
context_resume_0(debug_context);
|
1345
1340
|
}
|
1346
1341
|
rb_thread_critical = saved_crit;
|
1347
1342
|
|
@@ -1353,7 +1348,7 @@ debug_resume(VALUE self)
|
|
1353
1348
|
/*
|
1354
1349
|
* call-seq:
|
1355
1350
|
* Debugger.tracing -> bool
|
1356
|
-
*
|
1351
|
+
*
|
1357
1352
|
* Returns +true+ if the global tracing is activated.
|
1358
1353
|
*/
|
1359
1354
|
static VALUE
|
@@ -1365,7 +1360,7 @@ debug_tracing(VALUE self)
|
|
1365
1360
|
/*
|
1366
1361
|
* call-seq:
|
1367
1362
|
* Debugger.tracing = bool
|
1368
|
-
*
|
1363
|
+
*
|
1369
1364
|
* Sets the global tracing flag.
|
1370
1365
|
*/
|
1371
1366
|
static VALUE
|
@@ -1378,7 +1373,7 @@ debug_set_tracing(VALUE self, VALUE value)
|
|
1378
1373
|
/*
|
1379
1374
|
* call-seq:
|
1380
1375
|
* Debugger.post_mortem? -> bool
|
1381
|
-
*
|
1376
|
+
*
|
1382
1377
|
* Returns +true+ if post-moterm debugging is enabled.
|
1383
1378
|
*/
|
1384
1379
|
static VALUE
|
@@ -1390,7 +1385,7 @@ debug_post_mortem(VALUE self)
|
|
1390
1385
|
/*
|
1391
1386
|
* call-seq:
|
1392
1387
|
* Debugger.post_mortem = bool
|
1393
|
-
*
|
1388
|
+
*
|
1394
1389
|
* Sets post-moterm flag.
|
1395
1390
|
* FOR INTERNAL USE ONLY.
|
1396
1391
|
*/
|
@@ -1406,7 +1401,7 @@ debug_set_post_mortem(VALUE self, VALUE value)
|
|
1406
1401
|
/*
|
1407
1402
|
* call-seq:
|
1408
1403
|
* Debugger.keep_frame_binding? -> bool
|
1409
|
-
*
|
1404
|
+
*
|
1410
1405
|
* Returns +true+ if the debugger will collect frame bindings.
|
1411
1406
|
*/
|
1412
1407
|
static VALUE
|
@@ -1418,7 +1413,7 @@ debug_keep_frame_binding(VALUE self)
|
|
1418
1413
|
/*
|
1419
1414
|
* call-seq:
|
1420
1415
|
* Debugger.keep_frame_binding = bool
|
1421
|
-
*
|
1416
|
+
*
|
1422
1417
|
* Setting to +true+ will make the debugger create frame bindings.
|
1423
1418
|
*/
|
1424
1419
|
static VALUE
|
@@ -1428,11 +1423,17 @@ debug_set_keep_frame_binding(VALUE self, VALUE value)
|
|
1428
1423
|
return value;
|
1429
1424
|
}
|
1430
1425
|
|
1426
|
+
static VALUE
|
1427
|
+
debug_thread_inherited(VALUE klass)
|
1428
|
+
{
|
1429
|
+
rb_raise(rb_eRuntimeError, "Can't inherite Debugger::DebugThread class");
|
1430
|
+
}
|
1431
|
+
|
1431
1432
|
/*
|
1432
1433
|
* call-seq:
|
1433
1434
|
* Debugger.debug_load(file) -> nil
|
1434
|
-
*
|
1435
|
-
* Same as Kernel#load but resets current context's frames.
|
1435
|
+
*
|
1436
|
+
* Same as Kernel#load but resets current context's frames.
|
1436
1437
|
* FOR INTERNAL USE ONLY. Use Debugger.post_mortem method instead.
|
1437
1438
|
*/
|
1438
1439
|
static VALUE
|
@@ -1440,14 +1441,14 @@ debug_debug_load(VALUE self, VALUE file)
|
|
1440
1441
|
{
|
1441
1442
|
VALUE context;
|
1442
1443
|
debug_context_t *debug_context;
|
1443
|
-
|
1444
|
+
|
1444
1445
|
debug_start(self);
|
1445
|
-
|
1446
|
+
|
1446
1447
|
context = debug_current_context(self);
|
1447
1448
|
Data_Get_Struct(context, debug_context_t, debug_context);
|
1448
1449
|
debug_context->stack_size = 0;
|
1449
1450
|
rb_load(file, 0);
|
1450
|
-
|
1451
|
+
|
1451
1452
|
debug_stop(self);
|
1452
1453
|
return Qnil;
|
1453
1454
|
}
|
@@ -1457,10 +1458,10 @@ set_current_skipped_status(VALUE status)
|
|
1457
1458
|
{
|
1458
1459
|
VALUE context;
|
1459
1460
|
debug_context_t *debug_context;
|
1460
|
-
|
1461
|
+
|
1461
1462
|
context = debug_current_context(Qnil);
|
1462
1463
|
Data_Get_Struct(context, debug_context_t, debug_context);
|
1463
|
-
if(status)
|
1464
|
+
if(status)
|
1464
1465
|
CTX_FL_SET(debug_context, CTX_FL_SKIPPED);
|
1465
1466
|
else
|
1466
1467
|
CTX_FL_UNSET(debug_context, CTX_FL_SKIPPED);
|
@@ -1470,7 +1471,7 @@ set_current_skipped_status(VALUE status)
|
|
1470
1471
|
/*
|
1471
1472
|
* call-seq:
|
1472
1473
|
* Debugger.skip { block } -> obj or nil
|
1473
|
-
*
|
1474
|
+
*
|
1474
1475
|
* The code inside of the block is escaped from the debugger.
|
1475
1476
|
*/
|
1476
1477
|
static VALUE
|
@@ -1508,7 +1509,7 @@ debug_at_exit_i(VALUE proc)
|
|
1508
1509
|
/*
|
1509
1510
|
* call-seq:
|
1510
1511
|
* Debugger.debug_at_exit { block } -> proc
|
1511
|
-
*
|
1512
|
+
*
|
1512
1513
|
* Register <tt>at_exit</tt> hook which is escaped from the debugger.
|
1513
1514
|
* FOR INTERNAL USE ONLY.
|
1514
1515
|
*/
|
@@ -1527,7 +1528,7 @@ debug_at_exit(VALUE self)
|
|
1527
1528
|
/*
|
1528
1529
|
* call-seq:
|
1529
1530
|
* context.stop_next = steps
|
1530
|
-
*
|
1531
|
+
*
|
1531
1532
|
* Stops the current context after a number +steps+ are made.
|
1532
1533
|
*/
|
1533
1534
|
static VALUE
|
@@ -1540,14 +1541,14 @@ context_stop_next(VALUE self, VALUE steps)
|
|
1540
1541
|
if(FIX2INT(steps) < 0)
|
1541
1542
|
rb_raise(rb_eRuntimeError, "Steps argument can't be negative.");
|
1542
1543
|
debug_context->stop_next = FIX2INT(steps);
|
1543
|
-
|
1544
|
+
|
1544
1545
|
return steps;
|
1545
1546
|
}
|
1546
1547
|
|
1547
1548
|
/*
|
1548
1549
|
* call-seq:
|
1549
1550
|
* context.step_over(steps)
|
1550
|
-
*
|
1551
|
+
*
|
1551
1552
|
* Steps over a +steps+ number of times.
|
1552
1553
|
*/
|
1553
1554
|
static VALUE
|
@@ -1580,7 +1581,7 @@ context_step_over(int argc, VALUE *argv, VALUE self)
|
|
1580
1581
|
/*
|
1581
1582
|
* call-seq:
|
1582
1583
|
* context.stop_frame(frame)
|
1583
|
-
*
|
1584
|
+
*
|
1584
1585
|
* Stops when a frame with number +frame+ is activated. Implements +up+ and +down+ commands.
|
1585
1586
|
*/
|
1586
1587
|
static VALUE
|
@@ -1604,15 +1605,15 @@ check_frame_number(debug_context_t *debug_context, VALUE frame)
|
|
1604
1605
|
|
1605
1606
|
frame_n = FIX2INT(frame);
|
1606
1607
|
if(frame_n < 0 || frame_n >= debug_context->stack_size)
|
1607
|
-
|
1608
|
-
|
1608
|
+
rb_raise(rb_eArgError, "Invalid frame number %d, stack (0...%d)",
|
1609
|
+
frame_n, debug_context->stack_size);
|
1609
1610
|
return frame_n;
|
1610
1611
|
}
|
1611
1612
|
|
1612
1613
|
/*
|
1613
1614
|
* call-seq:
|
1614
1615
|
* context.frame_binding(frame) -> binding
|
1615
|
-
*
|
1616
|
+
*
|
1616
1617
|
* Returns frame's binding.
|
1617
1618
|
*/
|
1618
1619
|
static VALUE
|
@@ -1628,7 +1629,7 @@ context_frame_binding(VALUE self, VALUE frame)
|
|
1628
1629
|
/*
|
1629
1630
|
* call-seq:
|
1630
1631
|
* context.frame_id(frame) -> sym
|
1631
|
-
*
|
1632
|
+
*
|
1632
1633
|
* Returns the sym of the called method.
|
1633
1634
|
*/
|
1634
1635
|
static VALUE
|
@@ -1648,7 +1649,7 @@ context_frame_id(VALUE self, VALUE frame)
|
|
1648
1649
|
/*
|
1649
1650
|
* call-seq:
|
1650
1651
|
* context.frame_line(frame) -> int
|
1651
|
-
*
|
1652
|
+
*
|
1652
1653
|
* Returns the line number in the file.
|
1653
1654
|
*/
|
1654
1655
|
static VALUE
|
@@ -1665,7 +1666,7 @@ context_frame_line(VALUE self, VALUE frame)
|
|
1665
1666
|
/*
|
1666
1667
|
* call-seq:
|
1667
1668
|
* context.frame_file(frame) -> string
|
1668
|
-
*
|
1669
|
+
*
|
1669
1670
|
* Returns the name of the file.
|
1670
1671
|
*/
|
1671
1672
|
static VALUE
|
@@ -1691,20 +1692,24 @@ context_copy_locals(debug_frame_t *debug_frame)
|
|
1691
1692
|
scope = debug_frame->info.runtime.scope;
|
1692
1693
|
tbl = scope->local_tbl;
|
1693
1694
|
|
1694
|
-
if (tbl && scope->local_vars)
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1695
|
+
if (tbl && scope->local_vars)
|
1696
|
+
{
|
1697
|
+
n = *tbl++;
|
1698
|
+
for (i=2; i<n; i++)
|
1699
|
+
{ /* skip first 2 ($_ and $~) */
|
1700
|
+
if (!rb_is_local_id(tbl[i])) continue; /* skip flip states */
|
1701
|
+
rb_hash_aset(hash, rb_str_new2(rb_id2name(tbl[i])), scope->local_vars[i]);
|
1702
|
+
}
|
1700
1703
|
}
|
1701
1704
|
|
1702
1705
|
vars = debug_frame->info.runtime.dyna_vars;
|
1703
|
-
while (vars)
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1706
|
+
while (vars)
|
1707
|
+
{
|
1708
|
+
if (vars->id && rb_is_local_id(vars->id))
|
1709
|
+
{ /* skip $_, $~ and flip states */
|
1710
|
+
rb_hash_aset(hash, rb_str_new2(rb_id2name(vars->id)), vars->val);
|
1711
|
+
}
|
1712
|
+
vars = vars->next;
|
1708
1713
|
}
|
1709
1714
|
return hash;
|
1710
1715
|
}
|
@@ -1712,7 +1717,7 @@ context_copy_locals(debug_frame_t *debug_frame)
|
|
1712
1717
|
/*
|
1713
1718
|
* call-seq:
|
1714
1719
|
* context.frame_locals(frame) -> hash
|
1715
|
-
*
|
1720
|
+
*
|
1716
1721
|
* Returns frame's local variables.
|
1717
1722
|
*/
|
1718
1723
|
static VALUE
|
@@ -1723,18 +1728,18 @@ context_frame_locals(VALUE self, VALUE frame)
|
|
1723
1728
|
|
1724
1729
|
debug_check_started();
|
1725
1730
|
Data_Get_Struct(self, debug_context_t, debug_context);
|
1726
|
-
|
1731
|
+
|
1727
1732
|
debug_frame = GET_FRAME;
|
1728
1733
|
if(debug_frame->dead)
|
1729
|
-
|
1734
|
+
return debug_frame->info.copy.locals;
|
1730
1735
|
else
|
1731
|
-
|
1736
|
+
return context_copy_locals(debug_frame);
|
1732
1737
|
}
|
1733
1738
|
|
1734
1739
|
/*
|
1735
1740
|
* call-seq:
|
1736
1741
|
* context.frame_self(frame) -> obj
|
1737
|
-
*
|
1742
|
+
*
|
1738
1743
|
* Returns self object of the frame.
|
1739
1744
|
*/
|
1740
1745
|
static VALUE
|
@@ -1753,7 +1758,7 @@ context_frame_self(VALUE self, VALUE frame)
|
|
1753
1758
|
/*
|
1754
1759
|
* call-seq:
|
1755
1760
|
* context.stack_size-> int
|
1756
|
-
*
|
1761
|
+
*
|
1757
1762
|
* Returns the size of the context stack.
|
1758
1763
|
*/
|
1759
1764
|
static VALUE
|
@@ -1770,7 +1775,7 @@ context_stack_size(VALUE self)
|
|
1770
1775
|
/*
|
1771
1776
|
* call-seq:
|
1772
1777
|
* context.thread -> trhread
|
1773
|
-
*
|
1778
|
+
*
|
1774
1779
|
* Returns a thread this context is associated with.
|
1775
1780
|
*/
|
1776
1781
|
static VALUE
|
@@ -1786,7 +1791,7 @@ context_thread(VALUE self)
|
|
1786
1791
|
/*
|
1787
1792
|
* call-seq:
|
1788
1793
|
* context.thnum -> int
|
1789
|
-
*
|
1794
|
+
*
|
1790
1795
|
* Returns the context's number.
|
1791
1796
|
*/
|
1792
1797
|
static VALUE
|
@@ -1798,7 +1803,7 @@ context_thnum(VALUE self)
|
|
1798
1803
|
return INT2FIX(debug_context->thnum);
|
1799
1804
|
}
|
1800
1805
|
|
1801
|
-
static void
|
1806
|
+
static void
|
1802
1807
|
context_suspend_0(debug_context_t *debug_context)
|
1803
1808
|
{
|
1804
1809
|
VALUE status;
|
@@ -1826,7 +1831,7 @@ context_resume_0(debug_context_t *debug_context)
|
|
1826
1831
|
/*
|
1827
1832
|
* call-seq:
|
1828
1833
|
* context.suspend -> nil
|
1829
|
-
*
|
1834
|
+
*
|
1830
1835
|
* Suspends the thread when it is running.
|
1831
1836
|
*/
|
1832
1837
|
static VALUE
|
@@ -1846,7 +1851,7 @@ context_suspend(VALUE self)
|
|
1846
1851
|
/*
|
1847
1852
|
* call-seq:
|
1848
1853
|
* context.suspended? -> bool
|
1849
|
-
*
|
1854
|
+
*
|
1850
1855
|
* Returns +true+ if the thread is suspended by debugger.
|
1851
1856
|
*/
|
1852
1857
|
static VALUE
|
@@ -1863,7 +1868,7 @@ context_is_suspended(VALUE self)
|
|
1863
1868
|
/*
|
1864
1869
|
* call-seq:
|
1865
1870
|
* context.resume -> nil
|
1866
|
-
*
|
1871
|
+
*
|
1867
1872
|
* Resumes the thread from the suspended mode.
|
1868
1873
|
*/
|
1869
1874
|
static VALUE
|
@@ -1883,7 +1888,7 @@ context_resume(VALUE self)
|
|
1883
1888
|
/*
|
1884
1889
|
* call-seq:
|
1885
1890
|
* context.tracing -> bool
|
1886
|
-
*
|
1891
|
+
*
|
1887
1892
|
* Returns the tracing flag for the current context.
|
1888
1893
|
*/
|
1889
1894
|
static VALUE
|
@@ -1900,7 +1905,7 @@ context_tracing(VALUE self)
|
|
1900
1905
|
/*
|
1901
1906
|
* call-seq:
|
1902
1907
|
* context.tracking = bool
|
1903
|
-
*
|
1908
|
+
*
|
1904
1909
|
* Controls the tracing for this context.
|
1905
1910
|
*/
|
1906
1911
|
static VALUE
|
@@ -1921,7 +1926,7 @@ context_set_tracing(VALUE self, VALUE value)
|
|
1921
1926
|
/*
|
1922
1927
|
* call-seq:
|
1923
1928
|
* context.ignore -> bool
|
1924
|
-
*
|
1929
|
+
*
|
1925
1930
|
* Returns the ignore flag for the current context.
|
1926
1931
|
*/
|
1927
1932
|
static VALUE
|
@@ -1935,31 +1940,10 @@ context_ignore(VALUE self)
|
|
1935
1940
|
return CTX_FL_TEST(debug_context, CTX_FL_IGNORE) ? Qtrue : Qfalse;
|
1936
1941
|
}
|
1937
1942
|
|
1938
|
-
/*
|
1939
|
-
* call-seq:
|
1940
|
-
* context.tracking = bool
|
1941
|
-
*
|
1942
|
-
* Controls the ignore flag for this context.
|
1943
|
-
*/
|
1944
|
-
static VALUE
|
1945
|
-
context_set_ignore(VALUE self, VALUE value)
|
1946
|
-
{
|
1947
|
-
debug_context_t *debug_context;
|
1948
|
-
|
1949
|
-
debug_check_started();
|
1950
|
-
|
1951
|
-
Data_Get_Struct(self, debug_context_t, debug_context);
|
1952
|
-
if(RTEST(value))
|
1953
|
-
CTX_FL_SET(debug_context, CTX_FL_IGNORE);
|
1954
|
-
else
|
1955
|
-
CTX_FL_UNSET(debug_context, CTX_FL_IGNORE);
|
1956
|
-
return value;
|
1957
|
-
}
|
1958
|
-
|
1959
1943
|
/*
|
1960
1944
|
* call-seq:
|
1961
1945
|
* context.dead? = bool
|
1962
|
-
*
|
1946
|
+
*
|
1963
1947
|
* Returns +true+ if context doesn't represent a live context and is created
|
1964
1948
|
* during post-mortem exception handling.
|
1965
1949
|
*/
|
@@ -1977,7 +1961,7 @@ context_dead(VALUE self)
|
|
1977
1961
|
/*
|
1978
1962
|
* call-seq:
|
1979
1963
|
* breakpoint.source -> string
|
1980
|
-
*
|
1964
|
+
*
|
1981
1965
|
* Returns a source of the breakpoint.
|
1982
1966
|
*/
|
1983
1967
|
static VALUE
|
@@ -1992,7 +1976,7 @@ breakpoint_source(VALUE self)
|
|
1992
1976
|
/*
|
1993
1977
|
* call-seq:
|
1994
1978
|
* breakpoint.pos -> string or int
|
1995
|
-
*
|
1979
|
+
*
|
1996
1980
|
* Returns a position of this breakpoint.
|
1997
1981
|
*/
|
1998
1982
|
static VALUE
|
@@ -2010,7 +1994,7 @@ breakpoint_pos(VALUE self)
|
|
2010
1994
|
/*
|
2011
1995
|
* call-seq:
|
2012
1996
|
* breakpoint.expr -> string
|
2013
|
-
*
|
1997
|
+
*
|
2014
1998
|
* Returns a codition expression when this breakpoint should be activated.
|
2015
1999
|
*/
|
2016
2000
|
static VALUE
|
@@ -2025,24 +2009,24 @@ breakpoint_expr(VALUE self)
|
|
2025
2009
|
/*
|
2026
2010
|
* call-seq:
|
2027
2011
|
* breakpoint.id -> int
|
2028
|
-
*
|
2012
|
+
*
|
2029
2013
|
* Returns id of the breakpoint.
|
2030
2014
|
*/
|
2031
2015
|
static VALUE
|
2032
2016
|
breakpoint_id(VALUE self)
|
2033
2017
|
{
|
2034
2018
|
debug_breakpoint_t *breakpoint;
|
2035
|
-
|
2019
|
+
|
2036
2020
|
Data_Get_Struct(self, debug_breakpoint_t, breakpoint);
|
2037
2021
|
return INT2FIX(breakpoint->id);
|
2038
2022
|
}
|
2039
2023
|
|
2040
2024
|
/*
|
2041
2025
|
* Document-class: Context
|
2042
|
-
*
|
2026
|
+
*
|
2043
2027
|
* == Summary
|
2044
|
-
*
|
2045
|
-
* Debugger keeps a single instance of this class for each Ruby thread.
|
2028
|
+
*
|
2029
|
+
* Debugger keeps a single instance of this class for each Ruby thread.
|
2046
2030
|
*/
|
2047
2031
|
static void
|
2048
2032
|
Init_context()
|
@@ -2059,7 +2043,6 @@ Init_context()
|
|
2059
2043
|
rb_define_method(cContext, "tracing", context_tracing, 0);
|
2060
2044
|
rb_define_method(cContext, "tracing=", context_set_tracing, 1);
|
2061
2045
|
rb_define_method(cContext, "ignore", context_ignore, 0);
|
2062
|
-
rb_define_method(cContext, "ignore=", context_set_ignore, 1);
|
2063
2046
|
rb_define_method(cContext, "frame_binding", context_frame_binding, 1);
|
2064
2047
|
rb_define_method(cContext, "frame_id", context_frame_id, 1);
|
2065
2048
|
rb_define_method(cContext, "frame_line", context_frame_line, 1);
|
@@ -2072,10 +2055,10 @@ Init_context()
|
|
2072
2055
|
|
2073
2056
|
/*
|
2074
2057
|
* Document-class: Breakpoint
|
2075
|
-
*
|
2058
|
+
*
|
2076
2059
|
* == Summary
|
2077
|
-
*
|
2078
|
-
* This class represents a breakpoint. It defines position of the breakpoint and
|
2060
|
+
*
|
2061
|
+
* This class represents a breakpoint. It defines position of the breakpoint and
|
2079
2062
|
* condition when this breakpoint should be triggered.
|
2080
2063
|
*/
|
2081
2064
|
static void
|
@@ -2091,14 +2074,14 @@ Init_breakpoint()
|
|
2091
2074
|
|
2092
2075
|
/*
|
2093
2076
|
* Document-class: Debugger
|
2094
|
-
*
|
2077
|
+
*
|
2095
2078
|
* == Summary
|
2096
|
-
*
|
2097
|
-
* This is a singleton class allows controlling the debugger. Use it to start/stop debugger,
|
2079
|
+
*
|
2080
|
+
* This is a singleton class allows controlling the debugger. Use it to start/stop debugger,
|
2098
2081
|
* set/remove breakpoints, etc.
|
2099
2082
|
*/
|
2100
2083
|
#if defined(_WIN32)
|
2101
|
-
__declspec(dllexport)
|
2084
|
+
__declspec(dllexport)
|
2102
2085
|
#endif
|
2103
2086
|
void
|
2104
2087
|
Init_ruby_debug()
|
@@ -2128,9 +2111,12 @@ Init_ruby_debug()
|
|
2128
2111
|
rb_define_module_function(mDebugger, "post_mortem=", debug_set_post_mortem, 1);
|
2129
2112
|
rb_define_module_function(mDebugger, "keep_frame_binding?", debug_keep_frame_binding, 0);
|
2130
2113
|
rb_define_module_function(mDebugger, "keep_frame_binding=", debug_set_keep_frame_binding, 1);
|
2131
|
-
|
2114
|
+
|
2132
2115
|
cThreadsTable = rb_define_class_under(mDebugger, "ThreadsTable", rb_cObject);
|
2133
|
-
|
2116
|
+
|
2117
|
+
cDebugThread = rb_define_class_under(mDebugger, "DebugThread", rb_cThread);
|
2118
|
+
rb_define_singleton_method(cDebugThread, "inherited", debug_thread_inherited, 1);
|
2119
|
+
|
2134
2120
|
Init_context();
|
2135
2121
|
Init_breakpoint();
|
2136
2122
|
|
@@ -16,7 +16,7 @@ module Debugger
|
|
16
16
|
print "Evaluation of unrecognized command is #{$1.nil? ? 'on' : 'off'}.\n"
|
17
17
|
when /^(no)?trace$/
|
18
18
|
@@display_stack_trace = $1.nil?
|
19
|
-
|
19
|
+
print "Display stack trace is #{$1.nil? ? 'on' : 'off'}.\n"
|
20
20
|
else
|
21
21
|
print "Unknown setting.\n"
|
22
22
|
end
|
@@ -34,7 +34,7 @@ module Debugger
|
|
34
34
|
autoeval - evaluate every unrecognized command
|
35
35
|
trace - display stack trace when 'eval' raises exception
|
36
36
|
To disable setting, use 'no' prefix, like 'noautolist'
|
37
|
-
|
37
|
+
}
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
data/lib/ruby-debug/interface.rb
CHANGED
@@ -34,7 +34,7 @@ module Debugger
|
|
34
34
|
Readline::HISTORY.to_a.last(500).each do |line|
|
35
35
|
file.puts line unless line.strip.empty?
|
36
36
|
end
|
37
|
-
|
37
|
+
end rescue nil
|
38
38
|
end
|
39
39
|
public :save_history
|
40
40
|
end
|
@@ -115,4 +115,4 @@ module Debugger
|
|
115
115
|
@file.close
|
116
116
|
end
|
117
117
|
end
|
118
|
-
end
|
118
|
+
end
|
data/lib/ruby-debug.rb
CHANGED
@@ -276,13 +276,6 @@ class Exception # :nodoc:
|
|
276
276
|
attr_reader :__debug_file, :__debug_line, :__debug_binding, :__debug_context
|
277
277
|
end
|
278
278
|
|
279
|
-
class DebugThread < Thread # :nodoc:
|
280
|
-
def initialize(*args, &b)
|
281
|
-
Debugger.thread_context(self).ignore = true
|
282
|
-
super
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
279
|
module Kernel
|
287
280
|
#
|
288
281
|
# Stops the current thread after a number of _steps_ made.
|
data/lib/ruby_debug.so
CHANGED
Binary file
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.1
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-debug
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.7.
|
7
|
-
date: 2007-02-
|
6
|
+
version: 0.7.3
|
7
|
+
date: 2007-02-04 20:33:00 -05:00
|
8
8
|
summary: Fast Ruby debugger
|
9
9
|
require_paths:
|
10
10
|
- lib
|