rb-threadframe 0.37 → 0.38
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/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
|