ruby-debug 0.7.2-mswin32 → 0.7.3-mswin32
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/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
|