rb-threadframe 0.37 → 0.38
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +5 -0
- data/Rakefile +3 -3
- data/ext/proc_extra.c +80 -2
- data/ext/thread_frame.c +83 -30
- data/ext/thread_frame.h +4 -0
- data/test/unit/test-argc.rb +1 -1
- data/test/unit/test-prev.rb +16 -5
- data/test/unit/test-proc.rb +4 -0
- data/test/unit/test-settracefunc.rb +107 -55
- data/test/unit/test-thread-trace-masks.rb +8 -6
- metadata +23 -27
- data/test/ruby/test_brkpt.rb +0 -60
- data/test/ruby/test_disasm.rb +0 -17
- data/test/ruby/test_iseq.rb +0 -50
- data/test/ruby/test_tracefunc_adds.rb +0 -145
- data/test/ruby/test_tracefunc_raise.rb +0 -26
data/NEWS
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
March 15, 2011 (0.38) Ron Frankel Release
|
2
|
+
- Add RubyVM::ThreadFrame.prev (same as RubyVM::ThreadFrame.current.prev)
|
3
|
+
- Allow access to a C method type
|
4
|
+
- Method extensions now included on UnboundMethods as well
|
5
|
+
|
1
6
|
Feb 1, 2011 (0.37)
|
2
7
|
- 1.9.2 patches:
|
3
8
|
* Mark VM Instruction sequences for no garbage collection if they are
|
data/Rakefile
CHANGED
@@ -20,14 +20,14 @@ task :gem=>:gemspec do
|
|
20
20
|
Dir.chdir(ROOT_DIR) do
|
21
21
|
sh "gem build .gemspec"
|
22
22
|
FileUtils.mkdir_p 'pkg'
|
23
|
-
FileUtils.mv
|
23
|
+
FileUtils.mv("#{gemspec.file_name}", "pkg/")
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
desc "Install the gem locally"
|
28
28
|
task :install => :gem do
|
29
29
|
Dir.chdir(ROOT_DIR) do
|
30
|
-
sh %{gem install --local pkg/#{gemspec.
|
30
|
+
sh %{gem install --local pkg/#{gemspec.file_name}}
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -73,7 +73,7 @@ Rake::TestTask.new(:'test:unit') do |t|
|
|
73
73
|
t.libs << './ext'
|
74
74
|
t.test_files = FileList['test/unit/**/*.rb']
|
75
75
|
# t.pattern = 'test/**/*test-*.rb' # instead of above
|
76
|
-
t.
|
76
|
+
t.options = '--verbose' if $VERBOSE
|
77
77
|
end
|
78
78
|
task :'test:unit' => [:ext]
|
79
79
|
|
data/ext/proc_extra.c
CHANGED
@@ -49,9 +49,10 @@ extern rb_iseq_t *rb_method_get_iseq(VALUE method);
|
|
49
49
|
|
50
50
|
#if 0 /* The following is to fake out rdoc, until I find a better fix. */
|
51
51
|
/*
|
52
|
-
* Additions to the RubyVM::Method class
|
52
|
+
* Additions to the RubyVM::Method and RubyVM::UnboundMethod class
|
53
53
|
*/
|
54
54
|
VALUE rb_cIseq = rb_define_class("Method", ...)
|
55
|
+
VALUE rb_cIseq = rb_define_class("UnboundMethod", ...)
|
55
56
|
#endif
|
56
57
|
/*
|
57
58
|
* call-seq:
|
@@ -70,6 +71,78 @@ method_iseq(VALUE self)
|
|
70
71
|
return rb_iseq;
|
71
72
|
}
|
72
73
|
|
74
|
+
static void null_gc_proc(void *ptr) { }
|
75
|
+
|
76
|
+
static size_t null_gc_memsize(const void *ptr) { }
|
77
|
+
|
78
|
+
|
79
|
+
static const rb_data_type_t method_data_type = {
|
80
|
+
"method",
|
81
|
+
null_gc_proc,
|
82
|
+
null_gc_proc,
|
83
|
+
null_gc_memsize,
|
84
|
+
};
|
85
|
+
|
86
|
+
static inline rb_method_definition_t *
|
87
|
+
method_get_def(VALUE method)
|
88
|
+
{
|
89
|
+
/* FIXME: use
|
90
|
+
struct METHOD *data;
|
91
|
+
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
|
92
|
+
*/
|
93
|
+
struct METHOD *data = (struct METHOD *)DATA_PTR(method);
|
94
|
+
return data->me.def;
|
95
|
+
}
|
96
|
+
|
97
|
+
/*
|
98
|
+
* call-seq:
|
99
|
+
* Method#type -> String
|
100
|
+
*
|
101
|
+
* Returns the Method object.
|
102
|
+
*/
|
103
|
+
VALUE
|
104
|
+
method_type(VALUE self)
|
105
|
+
{
|
106
|
+
rb_method_definition_t *def = method_get_def(self);
|
107
|
+
const char *type_str;
|
108
|
+
switch (def->type) {
|
109
|
+
case VM_METHOD_TYPE_ISEQ:
|
110
|
+
type_str = "instruction sequence";
|
111
|
+
break;
|
112
|
+
case VM_METHOD_TYPE_CFUNC:
|
113
|
+
type_str = "C function";
|
114
|
+
break;
|
115
|
+
case VM_METHOD_TYPE_ATTRSET:
|
116
|
+
type_str = "attrset";
|
117
|
+
break;
|
118
|
+
case VM_METHOD_TYPE_IVAR:
|
119
|
+
type_str = "ivar";
|
120
|
+
break;
|
121
|
+
case VM_METHOD_TYPE_BMETHOD:
|
122
|
+
type_str = "bmethod";
|
123
|
+
break;
|
124
|
+
case VM_METHOD_TYPE_ZSUPER:
|
125
|
+
type_str = "zsuper";
|
126
|
+
break;
|
127
|
+
case VM_METHOD_TYPE_UNDEF:
|
128
|
+
type_str = "undefined";
|
129
|
+
break;
|
130
|
+
case VM_METHOD_TYPE_NOTIMPLEMENTED:
|
131
|
+
type_str = "not implemented";
|
132
|
+
break;
|
133
|
+
case VM_METHOD_TYPE_OPTIMIZED: /* Kernel#send, Proc#call, etc */
|
134
|
+
type_str = "optimized";
|
135
|
+
break;
|
136
|
+
case VM_METHOD_TYPE_MISSING: /* wrapper for method_missing(id) */
|
137
|
+
type_str = "type missing";
|
138
|
+
break;
|
139
|
+
default:
|
140
|
+
type_str = "unknown";
|
141
|
+
break;
|
142
|
+
}
|
143
|
+
return rb_str_new2(type_str);
|
144
|
+
}
|
145
|
+
|
73
146
|
/*
|
74
147
|
* call-seq:
|
75
148
|
* Method#alias_count -> Fixnum
|
@@ -102,7 +175,12 @@ Init_proc_extra(void)
|
|
102
175
|
rb_define_method(rb_cProc, "iseq", proc_iseq, 0);
|
103
176
|
|
104
177
|
/* Additions to Method */
|
105
|
-
rb_define_method(rb_cMethod, "iseq", method_iseq, 0);
|
106
178
|
rb_define_method(rb_cMethod, "alias_count", method_alias_count, 0);
|
179
|
+
rb_define_method(rb_cMethod, "iseq", method_iseq, 0);
|
107
180
|
rb_define_method(rb_cMethod, "original_id", method_original_id, 0);
|
181
|
+
rb_define_method(rb_cMethod, "type", method_type, 0);
|
182
|
+
|
183
|
+
rb_define_method(rb_cUnboundMethod, "alias_count", method_alias_count, 0);
|
184
|
+
rb_define_method(rb_cUnboundMethod, "original_id", method_original_id, 0);
|
185
|
+
rb_define_method(rb_cUnboundMethod, "type", method_type, 0);
|
108
186
|
}
|
data/ext/thread_frame.c
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
*/
|
7
7
|
|
8
8
|
/* What release we got? */
|
9
|
-
#define THREADFRAME_VERSION "0.
|
9
|
+
#define THREADFRAME_VERSION "0.38"
|
10
10
|
|
11
11
|
#include <string.h>
|
12
12
|
#include "../include/vm_core_mini.h" /* Pulls in ruby.h and node.h */
|
@@ -114,7 +114,11 @@ tf_free(void *ptr)
|
|
114
114
|
thread_frame_t *tf;
|
115
115
|
if (ptr) {
|
116
116
|
tf = ptr;
|
117
|
-
|
117
|
+
/* All valid frame types have 0x1 set so we will use this.
|
118
|
+
Warning: this is an undocumented assumption which may someday
|
119
|
+
be wrong. */
|
120
|
+
if (tf->cfp && ((tf->cfp->flag & 0x1) == 0) &&
|
121
|
+
RUBY_VM_NORMAL_ISEQ_P(tf->cfp->iseq))
|
118
122
|
tf->cfp->iseq->in_use--;
|
119
123
|
xfree(ptr);
|
120
124
|
}
|
@@ -812,44 +816,93 @@ thread_frame_s_current(VALUE klass)
|
|
812
816
|
/*
|
813
817
|
* call-seq:
|
814
818
|
* RubyVM::ThreadFrame::prev(thread) -> threadframe_object
|
815
|
-
* RubyVM::ThreadFrame::prev(thread, n)
|
819
|
+
* RubyVM::ThreadFrame::prev(thread, n) -> threadframe_object
|
820
|
+
* RubyVM::ThreadFrame::prev -> threadframe_object
|
821
|
+
* RubyVM::ThreadFrame::prev(n) -> threadframe_object
|
822
|
+
*
|
823
|
+
* In the first form, we return a RubyVM::ThreadFrame prior to the
|
824
|
+
* Thread object passed. That is we go back one frame from the
|
825
|
+
* current frfame.
|
826
|
+
*
|
827
|
+
* In the second form we try to go back that many thread frames.
|
828
|
+
*
|
829
|
+
* In the the third form, the current thread is assumed, and like the
|
830
|
+
* first form we go back one frame.
|
831
|
+
*
|
832
|
+
* The fourth form, like the third form, we assume the current
|
833
|
+
* thread. And like the first form we go back we try to back a
|
834
|
+
* FixNum number of entries.
|
835
|
+
*
|
836
|
+
* When count +n+ is given 1 is synonymous with the previous frame
|
837
|
+
* and 0 is invalid. If the +n+ is negative, we count from the bottom
|
838
|
+
* of the frame stack.
|
839
|
+
*
|
840
|
+
* In all cases we return a RubyVM::ThreadFrame or nil if we can't
|
841
|
+
* go back (or forward for a negative +n+) that many frames.
|
816
842
|
*
|
817
|
-
* Returns a RubyVM::ThreadFrame for the frame prior to the
|
818
|
-
* Thread object passed or nil if there is none. The default value for n
|
819
|
-
* is 1. 0 just returns the object passed.
|
820
|
-
* Negative counts or counts exceeding the stack will return nil.
|
821
843
|
*/
|
822
844
|
static VALUE
|
823
845
|
thread_frame_s_prev(int argc, VALUE *argv, VALUE klass)
|
824
846
|
{
|
825
|
-
VALUE
|
826
|
-
VALUE
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
847
|
+
VALUE first_val;
|
848
|
+
VALUE second_val;
|
849
|
+
VALUE thval = Qnil;
|
850
|
+
int prev_count = 0;
|
851
|
+
rb_thread_t *th = NULL;
|
852
|
+
|
853
|
+
/* Such complicated options processing. But we do want this
|
854
|
+
routine to be convenient. */
|
855
|
+
rb_scan_args(argc, argv, "02", &first_val, &second_val);
|
856
|
+
switch (argc) {
|
857
|
+
case 0:
|
858
|
+
th = ruby_current_thread;
|
859
|
+
/* Do'nt count the RubyVM::ThreadFrame.prev call */
|
860
|
+
prev_count = 2;
|
861
|
+
break;
|
862
|
+
case 1:
|
863
|
+
if (FIXNUM_P(first_val)) {
|
864
|
+
prev_count = FIX2INT(first_val);
|
865
|
+
if (prev_count > 0) prev_count++ ;
|
866
|
+
th = ruby_current_thread;
|
867
|
+
} else
|
868
|
+
if (Qtrue == rb_obj_is_kind_of(first_val, rb_cThread)) {
|
869
|
+
GetThreadPtr(first_val, th);
|
870
|
+
/* Don't count the RubyVM::ThreadFrame.prev call */
|
871
|
+
prev_count = 1;
|
872
|
+
} else {
|
873
|
+
rb_raise(rb_eTypeError,
|
874
|
+
"FixNum or ThreadFrame object expected for first argument");
|
875
|
+
}
|
876
|
+
break;
|
877
|
+
case 2:
|
878
|
+
if (Qtrue == rb_obj_is_kind_of(first_val, rb_cThread)) {
|
879
|
+
GetThreadPtr(first_val, th);
|
880
|
+
} else {
|
881
|
+
rb_raise(rb_eTypeError,
|
882
|
+
"ThreadFrame object expected for first argument");
|
883
|
+
}
|
884
|
+
if (FIXNUM_P(second_val)) {
|
885
|
+
prev_count = FIX2INT(second_val);
|
886
|
+
} else
|
887
|
+
rb_raise(rb_eTypeError,
|
888
|
+
"FixNum previous count expected for second argument");
|
889
|
+
break;
|
890
|
+
default:
|
891
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
|
892
|
+
}
|
836
893
|
|
837
|
-
if (
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
} else
|
842
|
-
n = FIX2INT(nv);
|
894
|
+
if (0 == prev_count) {
|
895
|
+
rb_raise(rb_eArgError,
|
896
|
+
"previous count can not be 0. Use current instead of prev");
|
897
|
+
}
|
843
898
|
|
844
|
-
if (
|
845
|
-
return thread_frame_s_current(klass);
|
846
|
-
} else if (n < 0) {
|
899
|
+
if (0 > prev_count) {
|
847
900
|
int stack_size = thread_frame_stack_size_internal(th->cfp, th);
|
848
|
-
if (-
|
849
|
-
|
901
|
+
if (-prev_count > stack_size) return Qnil;
|
902
|
+
prev_count = stack_size + prev_count;
|
850
903
|
}
|
851
904
|
|
852
|
-
return thread_frame_prev_internal(th->cfp, th,
|
905
|
+
return thread_frame_prev_internal(th->cfp, th, prev_count);
|
853
906
|
}
|
854
907
|
|
855
908
|
/*
|
data/ext/thread_frame.h
ADDED
data/test/unit/test-argc.rb
CHANGED
@@ -23,7 +23,7 @@ class TestARGC < Test::Unit::TestCase
|
|
23
23
|
all_events = []
|
24
24
|
eval <<-EOF.gsub(/^.*?: /, "")
|
25
25
|
1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
|
26
|
-
2: tf = RubyVM::ThreadFrame.
|
26
|
+
2: tf = RubyVM::ThreadFrame.prev
|
27
27
|
3: all_events << [tf.argc, tf.arity, tf.type, mid]
|
28
28
|
4: if :basename == mid
|
29
29
|
5: events << [tf.argc, tf.arity, tf.type, mid]
|
data/test/unit/test-prev.rb
CHANGED
@@ -21,18 +21,26 @@ class TestThread < Test::Unit::TestCase
|
|
21
21
|
|
22
22
|
def test_prev
|
23
23
|
|
24
|
-
assert RubyVM::ThreadFrame::prev(Thread::current,
|
25
|
-
|
26
|
-
|
24
|
+
assert RubyVM::ThreadFrame::prev(Thread::current, 1),
|
25
|
+
'should allow 2-arg prev'
|
26
|
+
assert RubyVM::ThreadFrame::prev(Thread::current),
|
27
|
+
'should allow 1-arg thread prev'
|
28
|
+
assert(RubyVM::ThreadFrame::prev(2),
|
29
|
+
'There should be at least two prior frames in single Fixnum prev')
|
27
30
|
|
28
31
|
top_frame = RubyVM::ThreadFrame::prev(Thread::current, -1)
|
29
|
-
assert(top_frame, 'Should give back the top frame')
|
32
|
+
assert(top_frame, 'Should give back the top frame for two arg and -1')
|
33
|
+
assert_equal('TOP', top_frame.type,
|
34
|
+
'The type of the top frame should be "TOP"')
|
35
|
+
|
36
|
+
top_frame = RubyVM::ThreadFrame::prev(-1)
|
37
|
+
assert(top_frame, 'Should give back the top frame for one arg and -1')
|
30
38
|
assert_equal('TOP', top_frame.type,
|
31
39
|
'The type of the top frame should be "TOP"')
|
32
40
|
|
33
41
|
assert_equal(nil, RubyVM::ThreadFrame::prev(Thread::current, 1000))
|
34
42
|
|
35
|
-
tf = RubyVM::ThreadFrame
|
43
|
+
tf = RubyVM::ThreadFrame.prev
|
36
44
|
|
37
45
|
assert tf.prev(2)
|
38
46
|
assert_equal(tf, tf.prev(0),
|
@@ -43,6 +51,9 @@ class TestThread < Test::Unit::TestCase
|
|
43
51
|
assert_raises TypeError do
|
44
52
|
tf.prev('a')
|
45
53
|
end
|
54
|
+
assert_raises ArgumentError do
|
55
|
+
tf.prev(RubyVM::ThreadFrame::current, 1, 'bad_arg')
|
56
|
+
end
|
46
57
|
assert_raises TypeError do
|
47
58
|
RubyVM::ThreadFrame::prev([1])
|
48
59
|
end
|
data/test/unit/test-proc.rb
CHANGED
@@ -19,5 +19,9 @@ class TestProcAndMethod < Test::Unit::TestCase
|
|
19
19
|
assert_equal(3, m.alias_count)
|
20
20
|
assert_equal(4, self.method(:two).alias_count)
|
21
21
|
assert_equal(:test_method_extra, self.method(:two).original_id)
|
22
|
+
assert_equal("instruction sequence", method(:test_method_extra).type)
|
23
|
+
assert_equal("C function", File.method(:basename).type)
|
24
|
+
# Array.map is an unbound method
|
25
|
+
assert_equal("C function", Array.instance_method(:map).type)
|
22
26
|
end
|
23
27
|
end
|
@@ -45,10 +45,13 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|
45
45
|
5: set_trace_func(nil)
|
46
46
|
EOF
|
47
47
|
|
48
|
-
expected = [
|
48
|
+
expected = [
|
49
|
+
[4, 'line', __method__, self.class],
|
50
|
+
[4, 'send', __method__, self.class],
|
49
51
|
[4, "c-call", :+, Fixnum],
|
50
52
|
[4, "c-return", :+, Fixnum],
|
51
53
|
[5, "line", __method__, self.class],
|
54
|
+
[5, "send", __method__, self.class],
|
52
55
|
[5, "c-call", :set_trace_func, Kernel]]
|
53
56
|
checkit(@events, expected)
|
54
57
|
end
|
@@ -65,17 +68,25 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|
65
68
|
8: set_trace_func(nil)
|
66
69
|
EOF
|
67
70
|
|
68
|
-
expected =
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
71
|
+
expected =
|
72
|
+
[
|
73
|
+
[4, 'line', __method__, self.class],
|
74
|
+
[4, 'send', __method__, self.class],
|
75
|
+
[4, 'c-call', :method_added, Module],
|
76
|
+
[4, 'c-return', :method_added, Module],
|
77
|
+
[7, 'line', __method__, self.class],
|
78
|
+
[7, 'send', __method__, self.class],
|
79
|
+
[4, 'call', :add, self.class],
|
80
|
+
[5, 'line', :add, self.class],
|
81
|
+
[5, 'send', :add, self.class],
|
82
|
+
[5, 'c-call', :+, Fixnum],
|
83
|
+
[5, 'c-return', :+, Fixnum],
|
84
|
+
[6, 'return', :add, self.class],
|
85
|
+
[6, 'leave', :add, self.class],
|
86
|
+
[8, 'line', __method__, self.class],
|
87
|
+
[8, 'send', __method__, self.class],
|
88
|
+
[8, 'c-call', :set_trace_func, Kernel]
|
89
|
+
]
|
79
90
|
checkit(@events, expected)
|
80
91
|
end
|
81
92
|
|
@@ -96,17 +107,23 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|
96
107
|
[4, 'c-return', :inherited, Class],
|
97
108
|
[4, 'class', nil, nil],
|
98
109
|
[5, 'line', nil, nil],
|
110
|
+
[5, 'send', nil, nil],
|
99
111
|
[5, 'c-call', :method_added, Module],
|
100
112
|
[5, 'c-return', :method_added, Module],
|
101
113
|
[7, 'end', nil, nil],
|
114
|
+
[7, 'leave', nil, nil],
|
102
115
|
[8, 'line', __method__, self.class],
|
116
|
+
[8, 'send', __method__, self.class],
|
103
117
|
[8, 'c-call', :new, Class],
|
104
118
|
[8, 'c-call', :initialize, BasicObject],
|
105
119
|
[8, 'c-return', :initialize, BasicObject],
|
106
120
|
[8, 'c-return', :new, Class],
|
121
|
+
[8, 'send', __method__, Class],
|
107
122
|
[5, 'call', :bar, Foo],
|
108
123
|
[6, 'return', :bar, Foo],
|
124
|
+
[6, 'leave', :bar, Foo],
|
109
125
|
[9, 'line', __method__, self.class],
|
126
|
+
[9, 'send', __method__, self.class],
|
110
127
|
[9, 'c-call', :clear_trace_func, Kernel]]
|
111
128
|
checkit(@events, expected)
|
112
129
|
end
|
@@ -124,19 +141,27 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|
124
141
|
9: foo(false)
|
125
142
|
10: set_trace_func(nil)
|
126
143
|
EOF
|
127
|
-
expected =
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
144
|
+
expected =
|
145
|
+
[
|
146
|
+
[ 4, 'line', __method__, self.class],
|
147
|
+
[ 4, 'send', __method__, self.class],
|
148
|
+
[ 4, 'c-call', :method_added, Module],
|
149
|
+
[ 4, 'c-return', :method_added, Module],
|
150
|
+
[ 8, 'line', __method__, self.class],
|
151
|
+
[ 8, 'send', __method__, self.class],
|
152
|
+
[ 4, 'call', :foo, self.class],
|
153
|
+
[ 5, 'line', :foo, self.class],
|
154
|
+
[ 5, 'return', :foo, self.class],
|
155
|
+
[ 5, 'leave', :foo, self.class],
|
156
|
+
[ 9, 'line', :test_return, self.class],
|
157
|
+
[ 9, 'send', :test_return, self.class],
|
158
|
+
[ 4, 'call', :foo, self.class],
|
159
|
+
[ 5, 'line', :foo, self.class],
|
160
|
+
[ 7, 'return', :foo, self.class],
|
161
|
+
[10, 'line', :test_return, self.class],
|
162
|
+
[10, 'leave', :test_return, self.class],
|
163
|
+
[10, 'send', :test_return, self.class],
|
164
|
+
[10, 'c-call', :set_trace_func, Kernel]]
|
140
165
|
checkit(@events, expected)
|
141
166
|
end
|
142
167
|
|
@@ -153,16 +178,22 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|
153
178
|
9: set_trace_func(nil)
|
154
179
|
EOF
|
155
180
|
|
156
|
-
expected =
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
181
|
+
expected =
|
182
|
+
[
|
183
|
+
[4, 'line', __method__, self.class],
|
184
|
+
[4, 'send', __method__, self.class],
|
185
|
+
[4, 'c-call', :method_added, Module],
|
186
|
+
[4, 'c-return', :method_added, Module],
|
187
|
+
[8, 'line', __method__, self.class],
|
188
|
+
[8, 'send', __method__, self.class],
|
189
|
+
[4, 'call', :foo, self.class],
|
190
|
+
[5, 'line', :foo, self.class],
|
191
|
+
[6, 'line', :foo, self.class],
|
192
|
+
[7, 'return', :foo, self.class],
|
193
|
+
[7, 'leave', :foo, self.class],
|
194
|
+
[9, 'line', :test_return2, self.class],
|
195
|
+
[9, 'send', :test_return2, self.class],
|
196
|
+
[9, 'c-call', :set_trace_func, Kernel]]
|
166
197
|
@events.each_with_index{|e, i|
|
167
198
|
assert_equal(e, @events[i], showit(@events, expected))}
|
168
199
|
assert_equal(expected.size, @events.size, showit(@events, expected))
|
@@ -181,23 +212,30 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|
181
212
|
8: set_trace_func(nil)
|
182
213
|
EOF
|
183
214
|
|
184
|
-
expected =
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
215
|
+
expected =
|
216
|
+
[
|
217
|
+
[4, 'line', __method__, self.class],
|
218
|
+
[5, 'line', __method__, self.class],
|
219
|
+
[5, 'send', __method__, Kernel],
|
220
|
+
[5, 'c-call', :raise, Kernel],
|
221
|
+
[5, 'c-call', :exception, Exception],
|
222
|
+
[5, 'c-call', :initialize, Exception],
|
223
|
+
[5, 'c-return', :initialize, Exception],
|
224
|
+
[5, 'c-return', :exception, Exception],
|
225
|
+
[5, 'c-call', :backtrace, Exception],
|
226
|
+
[5, 'c-return', :backtrace, Exception],
|
227
|
+
[5, 'c-call', :set_backtrace, Exception],
|
228
|
+
[5, 'c-return', :set_backtrace, Exception],
|
229
|
+
[5, 'raise', :test_raise, $e],
|
230
|
+
[5, 'c-return', :raise, Kernel],
|
231
|
+
[5, 'send', __method__, Kernel],
|
232
|
+
[6, 'c-call', :===, Module],
|
233
|
+
[6, 'c-return', :===, Module],
|
234
|
+
[7, 'leave', __method__, Module],
|
235
|
+
[8, 'line', __method__, self.class],
|
236
|
+
[8, 'send', __method__, self.class],
|
237
|
+
[8, 'c-call', :set_trace_func, Kernel]
|
238
|
+
]
|
201
239
|
checkit(events, expected)
|
202
240
|
end
|
203
241
|
|
@@ -211,13 +249,17 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|
211
249
|
8: set_trace_func(nil)
|
212
250
|
EOF
|
213
251
|
|
214
|
-
expected = [
|
252
|
+
expected = [
|
253
|
+
[4, 'line', __method__, self.class],
|
254
|
+
[4, 'send', __method__, self.class],
|
215
255
|
[4, 'c-call', :any?, Enumerable],
|
216
256
|
[4, 'c-call', :each, Array],
|
217
257
|
[4, 'line', __method__, self.class],
|
258
|
+
[4, 'leave', __method__, self.class],
|
218
259
|
[4, 'c-return', :each, Array],
|
219
260
|
[4, 'c-return', :any?, Enumerable],
|
220
261
|
[5, 'line', __method__, self.class],
|
262
|
+
[5, 'send', __method__, self.class],
|
221
263
|
[5, 'c-call', :set_trace_func, Kernel]]
|
222
264
|
checkit(events, expected)
|
223
265
|
end
|
@@ -258,7 +300,9 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|
258
300
|
|
259
301
|
expected = [[1, 'c-return', :set_trace_func, Thread, :set],
|
260
302
|
[2, 'line', __method__, self.class, :set],
|
261
|
-
[2, '
|
303
|
+
[2, 'send', :test_thread_trace, TestSetTraceFunc, :set],
|
304
|
+
[2, 'c-call', :add_trace_func, Thread, :set],
|
305
|
+
]
|
262
306
|
expected.each do |e|
|
263
307
|
assert_equal(e, events[:set].shift, showit(events, expected))
|
264
308
|
end
|
@@ -269,21 +313,29 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|
269
313
|
[3, 'c-return', :inherited, Class],
|
270
314
|
[3, 'class', nil, nil],
|
271
315
|
[4, 'line', nil, nil],
|
316
|
+
[4, 'send', nil, nil],
|
272
317
|
[4, 'c-call', :method_added, Module],
|
273
318
|
[4, 'c-return', :method_added, Module],
|
274
319
|
[7, 'end', nil, nil],
|
320
|
+
[7, 'leave', nil, nil],
|
275
321
|
[8, 'line', __method__, self.class],
|
322
|
+
[8, 'send', __method__, self.class],
|
276
323
|
[8, 'c-call', :new, Class],
|
277
324
|
[8, 'c-call', :initialize, BasicObject],
|
278
325
|
[8, 'c-return', :initialize, BasicObject],
|
279
326
|
[8, 'c-return', :new, Class],
|
327
|
+
[8, 'send', :test_thread_trace, TestSetTraceFunc],
|
280
328
|
[4, 'call', :foo, ThreadTraceInnerClass],
|
281
329
|
[5, 'line', :foo, ThreadTraceInnerClass],
|
330
|
+
[5, 'send', :foo, ThreadTraceInnerClass],
|
282
331
|
[5, 'c-call', :+, Fixnum],
|
283
332
|
[5, 'c-return', :+, Fixnum],
|
284
333
|
[6, 'return', :foo, ThreadTraceInnerClass],
|
334
|
+
[6, 'leave', :foo, ThreadTraceInnerClass],
|
285
335
|
[9, 'line', __method__, self.class],
|
286
|
-
[9, '
|
336
|
+
[9, 'send', __method__, self.class],
|
337
|
+
[9, 'c-call', :set_trace_func, Thread]
|
338
|
+
].each do |e|
|
287
339
|
[:set, :add].each do |type|
|
288
340
|
assert_equal(e + [type], events[type].shift)
|
289
341
|
end
|
@@ -4,12 +4,14 @@ require_relative '../../ext/thread_frame'
|
|
4
4
|
|
5
5
|
class TestTracingMasks < Test::Unit::TestCase
|
6
6
|
@@EVENT2MASK = {
|
7
|
-
'line' =>
|
8
|
-
'call' =>
|
9
|
-
'return' =>
|
10
|
-
'c-call' =>
|
11
|
-
'c-return' =>
|
12
|
-
'raise' =>
|
7
|
+
'line' => 0x0001,
|
8
|
+
'call' => 0x0008,
|
9
|
+
'return' => 0x0010,
|
10
|
+
'c-call' => 0x0020,
|
11
|
+
'c-return' => 0x0040,
|
12
|
+
'raise' => 0x0080,
|
13
|
+
'send' => 0x0400,
|
14
|
+
'leave' => 0x0800,
|
13
15
|
}
|
14
16
|
|
15
17
|
def something_to_test(n)
|
metadata
CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
version: "0.
|
7
|
+
- 38
|
8
|
+
version: "0.38"
|
9
9
|
platform: ruby
|
10
10
|
authors:
|
11
11
|
- R. Bernstein
|
@@ -13,7 +13,7 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date: 2011-
|
16
|
+
date: 2011-03-15 00:00:00 -04:00
|
17
17
|
default_executable:
|
18
18
|
dependencies: []
|
19
19
|
|
@@ -33,46 +33,42 @@ files:
|
|
33
33
|
- Makefile
|
34
34
|
- LICENSE
|
35
35
|
- NEWS
|
36
|
+
- include/thread_pthread.h
|
36
37
|
- include/node.h
|
37
|
-
- include/ruby19_externs.h
|
38
38
|
- include/method_mini.h
|
39
|
-
- include/
|
39
|
+
- include/ruby19_externs.h
|
40
40
|
- include/vm_core_mini.h
|
41
|
-
- lib/thread_frame.rb
|
42
41
|
- lib/iseq_extra.rb
|
42
|
+
- lib/thread_frame.rb
|
43
43
|
- ext/iseq_extra.c
|
44
44
|
- ext/thread_frame.c
|
45
|
-
- ext/thread_extra.c
|
46
45
|
- ext/proc_extra.c
|
46
|
+
- ext/thread_extra.c
|
47
|
+
- ext/thread_frame.h
|
48
|
+
- ext/proc_extra.h
|
49
|
+
- ext/thread_pthread.h
|
50
|
+
- ext/node.h
|
47
51
|
- ext/thread_extra.h
|
48
|
-
- ext/iseq_mini.h
|
49
52
|
- ext/iseq_extra.h
|
50
|
-
- ext/
|
51
|
-
-
|
52
|
-
- ext/proc_extra.h
|
53
|
-
- test/ruby/test_tracefunc_adds.rb
|
54
|
-
- test/ruby/test_brkpt.rb
|
55
|
-
- test/ruby/test_disasm.rb
|
56
|
-
- test/ruby/test_iseq.rb
|
57
|
-
- test/ruby/test_tracefunc_raise.rb
|
58
|
-
- test/unit/test-sp-size.rb
|
59
|
-
- test/unit/test-iseq-brkpt.rb
|
53
|
+
- ext/iseq_mini.h
|
54
|
+
- test/unit/test-trace.rb
|
60
55
|
- test/unit/test-iseq-save.rb
|
61
|
-
- test/unit/test-binding.rb
|
62
56
|
- test/unit/test-prev.rb
|
57
|
+
- test/unit/test-source.rb
|
63
58
|
- test/unit/test-lib-iseq.rb
|
64
59
|
- test/unit/test-return-stop.rb
|
65
|
-
- test/unit/test-
|
66
|
-
- test/unit/cfunc-use.rb
|
67
|
-
- test/unit/test-argc.rb
|
60
|
+
- test/unit/test-proc.rb
|
68
61
|
- test/unit/test-invalid.rb
|
62
|
+
- test/unit/test-argc.rb
|
63
|
+
- test/unit/cfunc-use.rb
|
64
|
+
- test/unit/test-binding.rb
|
69
65
|
- test/unit/test-lib-iseq-extra.rb
|
70
|
-
- test/unit/test-thread-trace-masks.rb
|
71
|
-
- test/unit/test-proc.rb
|
72
66
|
- test/unit/test-thread.rb
|
67
|
+
- test/unit/test-iseq-brkpt.rb
|
68
|
+
- test/unit/test-iseq.rb
|
69
|
+
- test/unit/test-thread-trace-masks.rb
|
73
70
|
- test/unit/test-settracefunc.rb
|
74
|
-
- test/unit/test-
|
75
|
-
- test/unit/test-source.rb
|
71
|
+
- test/unit/test-sp-size.rb
|
76
72
|
- threadframe.rd
|
77
73
|
- ext/extconf.rb
|
78
74
|
has_rdoc: true
|
@@ -84,7 +80,7 @@ rdoc_options:
|
|
84
80
|
- --main
|
85
81
|
- README.md
|
86
82
|
- --title
|
87
|
-
- ThreadFrame 0.
|
83
|
+
- ThreadFrame 0.38 Documentation
|
88
84
|
require_paths:
|
89
85
|
- lib
|
90
86
|
required_ruby_version: !ruby/object:Gem::Requirement
|
data/test/ruby/test_brkpt.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
class TestISeqBrkpt < Test::Unit::TestCase
|
4
|
-
|
5
|
-
def setup
|
6
|
-
@original_compile_option = RubyVM::InstructionSequence.compile_option
|
7
|
-
RubyVM::InstructionSequence.compile_option = {
|
8
|
-
:trace_instruction => false,
|
9
|
-
:specialized_instruction => false
|
10
|
-
}
|
11
|
-
end
|
12
|
-
|
13
|
-
def teardown
|
14
|
-
set_trace_func(nil)
|
15
|
-
RubyVM::InstructionSequence.compile_option = @original_compile_option
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_iseq_brkpt
|
19
|
-
iseq = RubyVM::InstructionSequence.compile('x=1; y=2')
|
20
|
-
assert iseq
|
21
|
-
assert_equal(nil, iseq.brkpts)
|
22
|
-
assert_equal(true, iseq.brkpt_alloc)
|
23
|
-
assert_equal([], iseq.brkpts)
|
24
|
-
assert_equal(false, iseq.brkpt_alloc)
|
25
|
-
|
26
|
-
assert_equal(true, iseq.brkpt_set(0))
|
27
|
-
assert_equal(1, iseq.brkpts.size)
|
28
|
-
assert_equal(true, iseq.brkpt_get(0), 'Offset 0 should be set')
|
29
|
-
assert_equal(true, iseq.brkpt_unset(0),'Offset 0 should be unset')
|
30
|
-
assert_equal(false, iseq.brkpt_get(0), 'Offset 0 should be unset now')
|
31
|
-
assert_equal(true, iseq.brkpt_unset(0),
|
32
|
-
'Offset 0 should be unset again')
|
33
|
-
assert_raises TypeError do iseq.brkpt_get(100) end
|
34
|
-
assert_equal(true, iseq.brkpt_dealloc)
|
35
|
-
assert_equal(false, iseq.brkpt_dealloc)
|
36
|
-
assert_equal(true, iseq.brkpt_unset(0),
|
37
|
-
'Offset 0 should be unset even when deallocated')
|
38
|
-
|
39
|
-
assert_raises TypeError do iseq.brkpt_set('a') end
|
40
|
-
|
41
|
-
iseq.brkpt_set(2)
|
42
|
-
iseq.brkpt_set(4)
|
43
|
-
events = []
|
44
|
-
eval <<-EOF.gsub(/^.*?: /, "")
|
45
|
-
1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
|
46
|
-
2: events << [event, lineno, mid, klass]
|
47
|
-
3: })
|
48
|
-
4: iseq.eval
|
49
|
-
5: set_trace_func(nil)
|
50
|
-
EOF
|
51
|
-
# puts iseq.disassemble
|
52
|
-
brkpt_events = events.select{|item| item[0] == 'brkpt'}
|
53
|
-
assert_equal(2, brkpt_events.size,
|
54
|
-
"Expecting to see 2 brkpts in #{events}.inspect")
|
55
|
-
assert_equal(true, iseq.brkpt_dealloc)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# We want to double-check we didn't mess up any pointers somewhere.
|
60
|
-
at_exit { GC.start }
|
data/test/ruby/test_disasm.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# Some simple tests of RubyVM::InstructionSequence#disasm, and
|
2
|
-
# #disasm_nochildren
|
3
|
-
require 'test/unit'
|
4
|
-
|
5
|
-
class TestDisasmClass < Test::Unit::TestCase
|
6
|
-
|
7
|
-
def test_basic
|
8
|
-
assert_equal(RubyVM::InstructionSequence.compile('1+2').disassemble,
|
9
|
-
RubyVM::InstructionSequence.compile('1+2').disasm)
|
10
|
-
|
11
|
-
p='def five; 5 end; five'
|
12
|
-
s1=RubyVM::InstructionSequence.compile(p).disasm
|
13
|
-
assert_equal String, s1.class, 'disasm output should be a string'
|
14
|
-
s2=RubyVM::InstructionSequence.compile(p).disasm_nochildren
|
15
|
-
assert_equal true, s1.size > s2.size
|
16
|
-
end
|
17
|
-
end
|
data/test/ruby/test_iseq.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
# See that setting ISEQS__ and SCRIPT_ISEQS__ saves
|
2
|
-
# RubyVM::Instruction_sequenses
|
3
|
-
require 'test/unit'
|
4
|
-
|
5
|
-
class TestIseqAccess < Test::Unit::TestCase
|
6
|
-
def setup
|
7
|
-
old_verbosity = $VERBOSE
|
8
|
-
$VERBOSE = nil
|
9
|
-
Kernel.const_set(:ISEQS__, {})
|
10
|
-
Kernel.const_set(:SCRIPT_ISEQS__, {})
|
11
|
-
$VERBOSE = old_verbosity
|
12
|
-
end
|
13
|
-
|
14
|
-
def teardown
|
15
|
-
old_verbosity = $VERBOSE
|
16
|
-
$VERBOSE = nil
|
17
|
-
Kernel.const_set(:ISEQS__, nil)
|
18
|
-
Kernel.const_set(:SCRIPT_ISEQS__, nil)
|
19
|
-
$VERBOSE = old_verbosity
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_basic
|
23
|
-
sizes=[]
|
24
|
-
[ISEQS__, SCRIPT_ISEQS__].each do |iseq_hash|
|
25
|
-
sizes << iseq_hash.size
|
26
|
-
end
|
27
|
-
# defining five should trigger five instruction sequence additions
|
28
|
-
# to ISEQS__ and SCRIPT_ISEQS__
|
29
|
-
#
|
30
|
-
eval 'def five; 5 end'
|
31
|
-
assert_equal sizes[0], sizes[1]
|
32
|
-
[SCRIPT_ISEQS__, ISEQS__].each do |iseq_hash|
|
33
|
-
assert_equal true, iseq_hash.size > sizes.pop
|
34
|
-
assert_equal Hash, iseq_hash.class
|
35
|
-
a = iseq_hash.first
|
36
|
-
assert_equal Array, a.class
|
37
|
-
assert_equal RubyVM::InstructionSequence, iseq_hash.values[0][0].class
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Check RubyVM::InstructionSequence#arity
|
42
|
-
def test_arity
|
43
|
-
eval 'def five; 5 end'
|
44
|
-
eval 'def add(a,b); a+b end'
|
45
|
-
eval 'def splat(*a); 5 end'
|
46
|
-
[['five', 0,], ['add', 2], ['splat', -1]].each do |meth, expect|
|
47
|
-
assert_equal(expect, ISEQS__[meth][0].arity)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,145 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
# tests set_trace_func with event bitmasks, clear_trace_func,
|
4
|
-
# Newer changes
|
5
|
-
class TestSetTraceFuncAdds < Test::Unit::TestCase
|
6
|
-
|
7
|
-
# Some of the below setup is similar to what is in lib/trace_mod.rb of
|
8
|
-
# rb-trace
|
9
|
-
@@NO_EVENT_MASK = 0x0000
|
10
|
-
@@LINE_EVENT_MASK = 0x0001
|
11
|
-
@@CLASS_EVENT_MASK = 0x0002
|
12
|
-
@@END_EVENT_MASK = 0x0004
|
13
|
-
@@CALL_EVENT_MASK = 0x0008
|
14
|
-
@@RETURN_EVENT_MASK = 0x0010
|
15
|
-
@@C_CALL_EVENT_MASK = 0x0020
|
16
|
-
@@C_RETURN_EVENT_MASK = 0x0040
|
17
|
-
@@RAISE_EVENT_MASK = 0x0080
|
18
|
-
@@INSN_EVENT_MASK = 0x0100
|
19
|
-
@@ALL_EVENTS_MASK = (0xffff & ~@@INSN_EVENT_MASK)
|
20
|
-
|
21
|
-
@@EVENT2MASK = {
|
22
|
-
'line' => @@LINE_EVENT_MASK,
|
23
|
-
'call' => @@CALL_EVENT_MASK,
|
24
|
-
'return' => @@RETURN_EVENT_MASK,
|
25
|
-
'c-call' => @@C_CALL_EVENT_MASK,
|
26
|
-
'c-return' => @@C_RETURN_EVENT_MASK,
|
27
|
-
'c-raise' => @@RAISE_EVENT_MASK
|
28
|
-
}
|
29
|
-
|
30
|
-
# Convert +events+ into a Fixnum bitmask used internally by Ruby.
|
31
|
-
# Parameter +events+ should be Enumerable and each element should
|
32
|
-
# either be a Fixnum mask value or something that can be converted
|
33
|
-
# to a symbol. If the latter, the case is not important as we'll
|
34
|
-
# downcase the string representation.
|
35
|
-
def events2bitmask(event_list)
|
36
|
-
bitmask = @@NO_EVENT_MASK
|
37
|
-
event_list.each do |event|
|
38
|
-
bitmask |= @@EVENT2MASK[event]
|
39
|
-
end
|
40
|
-
return bitmask
|
41
|
-
end
|
42
|
-
|
43
|
-
def setup
|
44
|
-
@original_compile_option = RubyVM::InstructionSequence.compile_option
|
45
|
-
RubyVM::InstructionSequence.compile_option = {
|
46
|
-
:trace_instruction => true,
|
47
|
-
:specialized_instruction => false
|
48
|
-
}
|
49
|
-
@proc_template = 'Proc.new { |event, file, lineno, mid, binding, klass|
|
50
|
-
%s << [event, lineno, mid, klass]}'
|
51
|
-
end
|
52
|
-
|
53
|
-
def teardown
|
54
|
-
clear_trace_func
|
55
|
-
RubyVM::InstructionSequence.compile_option = @original_compile_option
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_eventmask
|
59
|
-
returned_tuples =
|
60
|
-
[['line', 5, :test_eventmask, self.class],
|
61
|
-
['class', 5, nil, nil],
|
62
|
-
['end', 5, nil, nil],
|
63
|
-
['line', 6, :test_eventmask, self.class],
|
64
|
-
['call', 1, :five, self.class],
|
65
|
-
['line', 1, :five, self.class],
|
66
|
-
['return', 1, :five, self.class],
|
67
|
-
['c-call', 6, :any?, Enumerable],
|
68
|
-
['c-call', 6, :each, Array],
|
69
|
-
['line', 6, :test_eventmask, self.class],
|
70
|
-
['c-return', 6, :each, Array],
|
71
|
-
['c-return', 6, :any?, Enumerable],
|
72
|
-
['line', 7, :test_eventmask, self.class],
|
73
|
-
['c-call', 7, :clear_trace_func, Kernel]]
|
74
|
-
|
75
|
-
[[], nil,
|
76
|
-
%w(line),
|
77
|
-
%w(call line),
|
78
|
-
%w(c-call c-return line),
|
79
|
-
].each do |event_list|
|
80
|
-
tuples = []
|
81
|
-
event_mask = if event_list
|
82
|
-
events2bitmask(event_list)
|
83
|
-
else
|
84
|
-
@@ALL_EVENTS_MASK
|
85
|
-
end
|
86
|
-
cmd = <<-EOF.gsub(/^.*?: /, '')
|
87
|
-
1: def five; 5 end
|
88
|
-
2: p1 = #{@proc_template}
|
89
|
-
3: set_trace_func(p1, #{event_mask})
|
90
|
-
4: class Foo; end
|
91
|
-
5: [1,2,five].any? {|n| n}
|
92
|
-
6: clear_trace_func
|
93
|
-
EOF
|
94
|
-
eval(cmd % 'tuples')
|
95
|
-
expected = if event_list
|
96
|
-
returned_tuples.select{|x| !([x[0]] & event_list).empty?}
|
97
|
-
else
|
98
|
-
returned_tuples
|
99
|
-
end
|
100
|
-
assert_equal(expected, tuples,
|
101
|
-
"Error filtering #{event_list}")
|
102
|
-
# p tuples
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_chained_hook
|
107
|
-
tuples1 = []
|
108
|
-
tuples2 = []
|
109
|
-
cmd = <<-EOF.gsub(/^.*?: /, '')
|
110
|
-
1: def five; 5 end
|
111
|
-
2: p1 = #{@proc_template}
|
112
|
-
3: p2 = #{@proc_template}
|
113
|
-
4: add_trace_func(p1, @@LINE_EVENT_MASK)
|
114
|
-
5: add_trace_func(p2, @@CALL_EVENT_MASK)
|
115
|
-
6: class Foo; end
|
116
|
-
7: [1,2,five].any? {|n| n}
|
117
|
-
EOF
|
118
|
-
eval(cmd % %w(tuples1 tuples2))
|
119
|
-
clear_trace_func
|
120
|
-
assert_equal([
|
121
|
-
["line", 7, :test_chained_hook, self.class],
|
122
|
-
["line", 8, :test_chained_hook, self.class],
|
123
|
-
["line", 9, :test_chained_hook, self.class],
|
124
|
-
["line", 1, :five, self.class],
|
125
|
-
["line", 9, :test_chained_hook, self.class],
|
126
|
-
], tuples1[0..-2],
|
127
|
-
'line filtering')
|
128
|
-
assert_equal([["call", 1, :five, self.class]], tuples2,
|
129
|
-
'call filtering')
|
130
|
-
end
|
131
|
-
|
132
|
-
def test_trace_insn
|
133
|
-
tuples = []
|
134
|
-
cmd = <<-EOF.gsub(/^.*?: /, '')
|
135
|
-
1: p = #{@proc_template}
|
136
|
-
2: add_trace_func(p, @@INSN_EVENT_MASK)
|
137
|
-
4: x = 1
|
138
|
-
3: y = 2
|
139
|
-
EOF
|
140
|
-
eval cmd % 'tuples'
|
141
|
-
clear_trace_func
|
142
|
-
assert_equal true, !tuples.empty?, 'triggered instruction events'
|
143
|
-
assert_equal true, tuples.all?{|t| 'vm-insn' == t[0]}, 'instruction events'
|
144
|
-
end
|
145
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
# tests that we a trace hook has access to the runtime exception Object
|
4
|
-
# when it is called through a raise event
|
5
|
-
|
6
|
-
class TestTracefuncRaise < Test::Unit::TestCase
|
7
|
-
|
8
|
-
def test_basic
|
9
|
-
tuples = []
|
10
|
-
p = Proc.new {
|
11
|
-
|event, file, lineno, mid, binding, klass|
|
12
|
-
tuples << klass
|
13
|
-
}
|
14
|
-
msg = 'this is a message'
|
15
|
-
set_trace_func(p, 0x0080)
|
16
|
-
begin ; x = 1/0; rescue; end
|
17
|
-
begin ; raise RuntimeError, msg; rescue; end
|
18
|
-
clear_trace_func
|
19
|
-
assert_equal(2, tuples.size,
|
20
|
-
"Wrong number of tuples captured #{tuples.inspect}")
|
21
|
-
assert_equal msg, tuples[1].message
|
22
|
-
assert_equal([ZeroDivisionError, RuntimeError], tuples.map{|t| t.class},
|
23
|
-
"Mismatched tuples classes in #{tuples.inspect}")
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|