ruby-debug 0.7.1-mswin32 → 0.7.2-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 +8 -0
- data/ext/ruby_debug.c +69 -12
- data/lib/ruby-debug.rb +2 -0
- data/lib/ruby-debug/processor.rb +17 -1
- data/lib/ruby_debug.so +0 -0
- metadata +2 -2
data/CHANGES
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
0.7.2
|
2
|
+
- Fixed a case when a frame is not popped up properly (ruby's bug!).
|
3
|
+
- Fixed Context#resume (a thread should be waked up only when it was running when it wsa suspened).
|
4
|
+
- When handling post-mortem exception, all threads must be suspended.
|
5
|
+
|
6
|
+
0.7.1
|
7
|
+
- Fixed 'delete' command
|
8
|
+
|
1
9
|
0.7
|
2
10
|
- Eliminated explicit Frame object. Use Context.frame_[binding,file,line] instead.
|
3
11
|
- Fixed help command.
|
data/ext/ruby_debug.c
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
#include <rubysig.h>
|
5
5
|
#include <st.h>
|
6
6
|
|
7
|
-
#define DEBUG_VERSION "0.7.
|
7
|
+
#define DEBUG_VERSION "0.7.2"
|
8
8
|
|
9
9
|
#ifdef _WIN32
|
10
10
|
struct FRAME {
|
@@ -48,6 +48,7 @@ RUBY_EXTERN struct RVarmap *ruby_dyna_vars;
|
|
48
48
|
#define CTX_FL_SKIPPED (1<<4)
|
49
49
|
#define CTX_FL_IGNORE (1<<5)
|
50
50
|
#define CTX_FL_DEAD (1<<6)
|
51
|
+
#define CTX_FL_WAS_RUNNING (1<<7)
|
51
52
|
|
52
53
|
#define CTX_FL_TEST(c,f) ((c)->flags & (f))
|
53
54
|
#define CTX_FL_SET(c,f) do { (c)->flags |= (f); } while (0)
|
@@ -156,6 +157,8 @@ static VALUE create_binding(VALUE);
|
|
156
157
|
static VALUE debug_stop(VALUE);
|
157
158
|
static void save_current_position(debug_context_t *);
|
158
159
|
static VALUE context_copy_locals(debug_frame_t *);
|
160
|
+
static void context_suspend_0(debug_context_t *);
|
161
|
+
static void context_resume_0(debug_context_t *);
|
159
162
|
|
160
163
|
typedef struct locked_thread_t {
|
161
164
|
VALUE thread_id;
|
@@ -521,6 +524,7 @@ save_call_frame(VALUE self, char *file, int line, ID mid, debug_context_t *debug
|
|
521
524
|
debug_frame->self = self;
|
522
525
|
debug_frame->info.runtime.frame = ruby_frame;
|
523
526
|
debug_frame->info.runtime.scope = ruby_scope;
|
527
|
+
|
524
528
|
debug_frame->info.runtime.dyna_vars = ruby_dyna_vars;
|
525
529
|
}
|
526
530
|
|
@@ -711,6 +715,32 @@ save_current_position(debug_context_t *debug_context)
|
|
711
715
|
CTX_FL_UNSET(debug_context, CTX_FL_MOVED);
|
712
716
|
}
|
713
717
|
|
718
|
+
static char *
|
719
|
+
get_event_name(rb_event_t event)
|
720
|
+
{
|
721
|
+
switch (event) {
|
722
|
+
case RUBY_EVENT_LINE:
|
723
|
+
return "line";
|
724
|
+
case RUBY_EVENT_CLASS:
|
725
|
+
return "class";
|
726
|
+
case RUBY_EVENT_END:
|
727
|
+
return "end";
|
728
|
+
case RUBY_EVENT_CALL:
|
729
|
+
return "call";
|
730
|
+
case RUBY_EVENT_RETURN:
|
731
|
+
return "return";
|
732
|
+
case RUBY_EVENT_C_CALL:
|
733
|
+
return "c-call";
|
734
|
+
case RUBY_EVENT_C_RETURN:
|
735
|
+
return "c-return";
|
736
|
+
case RUBY_EVENT_RAISE:
|
737
|
+
return "raise";
|
738
|
+
default:
|
739
|
+
return "unknown";
|
740
|
+
}
|
741
|
+
}
|
742
|
+
|
743
|
+
|
714
744
|
static void
|
715
745
|
debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
716
746
|
{
|
@@ -725,7 +755,7 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
725
755
|
|
726
756
|
if (mid == ID_ALLOCATOR) return;
|
727
757
|
if(!node) return;
|
728
|
-
|
758
|
+
|
729
759
|
thread = rb_thread_current();
|
730
760
|
thread_context_lookup(thread, &context, &debug_context);
|
731
761
|
|
@@ -853,8 +883,15 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
853
883
|
debug_context->stop_next = 1;
|
854
884
|
debug_context->stop_frame = 0;
|
855
885
|
}
|
856
|
-
|
886
|
+
// frame's method id must be checked to avoid a nasty Ruby's bug where
|
887
|
+
// [call] event is received without corresponding [return] event.
|
888
|
+
// For example, it happens when singleton methods are called.
|
889
|
+
while(debug_context->stack_size > 0)
|
890
|
+
{
|
857
891
|
debug_context->stack_size--;
|
892
|
+
if(debug_context->frames[debug_context->stack_size].id == mid)
|
893
|
+
break;
|
894
|
+
}
|
858
895
|
break;
|
859
896
|
}
|
860
897
|
case RUBY_EVENT_CLASS:
|
@@ -1266,7 +1303,7 @@ debug_suspend(VALUE self)
|
|
1266
1303
|
if(current == context)
|
1267
1304
|
continue;
|
1268
1305
|
Data_Get_Struct(context, debug_context_t, debug_context);
|
1269
|
-
|
1306
|
+
context_suspend_0(debug_context);
|
1270
1307
|
}
|
1271
1308
|
rb_thread_critical = saved_crit;
|
1272
1309
|
|
@@ -1304,11 +1341,7 @@ debug_resume(VALUE self)
|
|
1304
1341
|
if(current == context)
|
1305
1342
|
continue;
|
1306
1343
|
Data_Get_Struct(context, debug_context_t, debug_context);
|
1307
|
-
|
1308
|
-
{
|
1309
|
-
CTX_FL_UNSET(debug_context, CTX_FL_SUSPEND);
|
1310
|
-
rb_thread_run(context_thread_0(debug_context));
|
1311
|
-
}
|
1344
|
+
context_resume_0(debug_context);
|
1312
1345
|
}
|
1313
1346
|
rb_thread_critical = saved_crit;
|
1314
1347
|
|
@@ -1765,6 +1798,31 @@ context_thnum(VALUE self)
|
|
1765
1798
|
return INT2FIX(debug_context->thnum);
|
1766
1799
|
}
|
1767
1800
|
|
1801
|
+
static void
|
1802
|
+
context_suspend_0(debug_context_t *debug_context)
|
1803
|
+
{
|
1804
|
+
VALUE status;
|
1805
|
+
|
1806
|
+
status = rb_funcall(context_thread_0(debug_context), rb_intern("status"), 0);
|
1807
|
+
if(rb_str_cmp(status, rb_str_new2("run")) == 0)
|
1808
|
+
CTX_FL_SET(debug_context, CTX_FL_WAS_RUNNING);
|
1809
|
+
else if(rb_str_cmp(status, rb_str_new2("sleep")) == 0)
|
1810
|
+
CTX_FL_UNSET(debug_context, CTX_FL_WAS_RUNNING);
|
1811
|
+
else
|
1812
|
+
return;
|
1813
|
+
CTX_FL_SET(debug_context, CTX_FL_SUSPEND);
|
1814
|
+
}
|
1815
|
+
|
1816
|
+
static void
|
1817
|
+
context_resume_0(debug_context_t *debug_context)
|
1818
|
+
{
|
1819
|
+
if(!CTX_FL_TEST(debug_context, CTX_FL_SUSPEND))
|
1820
|
+
return;
|
1821
|
+
CTX_FL_UNSET(debug_context, CTX_FL_SUSPEND);
|
1822
|
+
if(CTX_FL_TEST(debug_context, CTX_FL_WAS_RUNNING))
|
1823
|
+
rb_thread_wakeup(context_thread_0(debug_context));
|
1824
|
+
}
|
1825
|
+
|
1768
1826
|
/*
|
1769
1827
|
* call-seq:
|
1770
1828
|
* context.suspend -> nil
|
@@ -1781,7 +1839,7 @@ context_suspend(VALUE self)
|
|
1781
1839
|
Data_Get_Struct(self, debug_context_t, debug_context);
|
1782
1840
|
if(CTX_FL_TEST(debug_context, CTX_FL_SUSPEND))
|
1783
1841
|
rb_raise(rb_eRuntimeError, "Already suspended.");
|
1784
|
-
|
1842
|
+
context_suspend_0(debug_context);
|
1785
1843
|
return Qnil;
|
1786
1844
|
}
|
1787
1845
|
|
@@ -1818,8 +1876,7 @@ context_resume(VALUE self)
|
|
1818
1876
|
Data_Get_Struct(self, debug_context_t, debug_context);
|
1819
1877
|
if(!CTX_FL_TEST(debug_context, CTX_FL_SUSPEND))
|
1820
1878
|
rb_raise(rb_eRuntimeError, "Thread is not suspended.");
|
1821
|
-
|
1822
|
-
rb_thread_run(context_thread_0(debug_context));
|
1879
|
+
context_resume_0(debug_context);
|
1823
1880
|
return Qnil;
|
1824
1881
|
}
|
1825
1882
|
|
data/lib/ruby-debug.rb
CHANGED
@@ -260,11 +260,13 @@ module Debugger
|
|
260
260
|
|
261
261
|
def handle_post_mortem(exp)
|
262
262
|
return if exp.__debug_context.stack_size == 0
|
263
|
+
Debugger.suspend
|
263
264
|
orig_tracing = Debugger.tracing, Debugger.current_context.tracing
|
264
265
|
Debugger.tracing = Debugger.current_context.tracing = false
|
265
266
|
processor.at_line(exp.__debug_context, exp.__debug_file, exp.__debug_line)
|
266
267
|
ensure
|
267
268
|
Debugger.tracing, Debugger.current_context.tracing = orig_tracing
|
269
|
+
Debugger.resume
|
268
270
|
end
|
269
271
|
private :handle_post_mortem
|
270
272
|
end
|
data/lib/ruby-debug/processor.rb
CHANGED
@@ -94,6 +94,22 @@ module Debugger
|
|
94
94
|
end
|
95
95
|
commands = event_cmds.map{|cmd| cmd.new(state) }
|
96
96
|
commands.select{|cmd| cmd.class.always_run }.each{|cmd| cmd.execute }
|
97
|
+
|
98
|
+
splitter = lambda do |str|
|
99
|
+
str.split(/;/).inject([]) do |m, v|
|
100
|
+
if m.empty?
|
101
|
+
m << v
|
102
|
+
else
|
103
|
+
if m.last[-1] == ?\\
|
104
|
+
m.last[-1,1] = ''
|
105
|
+
m.last << ';' << v
|
106
|
+
else
|
107
|
+
m << v
|
108
|
+
end
|
109
|
+
end
|
110
|
+
m
|
111
|
+
end
|
112
|
+
end
|
97
113
|
|
98
114
|
while !state.proceed? and input = @interface.read_command(prompt(context))
|
99
115
|
catch(:debug_error) do
|
@@ -105,7 +121,7 @@ module Debugger
|
|
105
121
|
@last_cmd = input
|
106
122
|
end
|
107
123
|
|
108
|
-
input.
|
124
|
+
splitter[input].each do |input|
|
109
125
|
if cmd = commands.find{ |c| c.match(input) }
|
110
126
|
if context.dead? && cmd.class.need_context
|
111
127
|
print "Command is unavailable\n"
|
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.2
|
7
|
+
date: 2007-02-03 15:35:35 -05:00
|
8
8
|
summary: Fast Ruby debugger
|
9
9
|
require_paths:
|
10
10
|
- lib
|