rb-trace 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.org>
2
+ All rights reserved.
3
+ *
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions
6
+ are met:
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ *
13
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
14
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
17
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
+ SUCH DAMAGE.
data/NEWS ADDED
@@ -0,0 +1,2 @@
1
+ September 12 2010 (0.2)
2
+ First release on gemcutter
data/Rakefile ADDED
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env rake
2
+ # -*- Ruby -*-
3
+ require 'rubygems'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/testtask'
6
+
7
+ SO_NAME = 'trace.so'
8
+
9
+ PACKAGE_VERSION = open('ext/trace.c') do |f|
10
+ f.grep(/^#define TRACE_VERSION/).first[/"(.+)"/,1]
11
+ end
12
+
13
+ EXT_FILES = FileList[%w(ext/*.c ext/*.h)]
14
+ LIB_FILES = FileList['lib/*.rb']
15
+ TEST_FILES = FileList['test/**/*.rb']
16
+ COMMON_FILES = FileList[%w(Rakefile NEWS LICENSE)]
17
+ ALL_FILES = COMMON_FILES + TEST_FILES + EXT_FILES + LIB_FILES
18
+
19
+ desc "Create a GNU-style ChangeLog via git2cl"
20
+ task :ChangeLog do
21
+ system("git log --pretty --numstat --summary | git2cl > ChangeLog")
22
+ end
23
+
24
+ desc 'Test units - the smaller tests'
25
+ task :'test:unit' => [:ext] do |t|
26
+ Rake::TestTask.new(:'test:unit') do |t|
27
+ t.test_files = FileList['test/unit/**/*.rb']
28
+ # t.pattern = 'test/**/*test-*.rb' # instead of above
29
+ t.verbose = true
30
+ end
31
+ end
32
+
33
+ desc "Create the core ruby-debug shared library extension"
34
+ task :ext do
35
+ Dir.chdir('ext') do
36
+ system("#{Gem.ruby} extconf.rb && make")
37
+ end
38
+ end
39
+
40
+ desc 'Remove built files'
41
+ task :clean do
42
+ cd 'ext' do
43
+ if File.exist?('Makefile')
44
+ sh 'make clean'
45
+ rm 'Makefile'
46
+ end
47
+ derived_files = Dir.glob('.o') + Dir.glob('*.so')
48
+ rm derived_files unless derived_files.empty?
49
+ end
50
+ end
51
+
52
+ desc 'Test everything - unit tests for now.'
53
+ task :test do
54
+ exceptions = ['test:unit'].collect do |task|
55
+ begin
56
+ Rake::Task[task].invoke
57
+ nil
58
+ rescue => e
59
+ e
60
+ end
61
+ end.compact
62
+ end
63
+
64
+ desc "Test everything - same as test."
65
+ task :check => :test
66
+ task :default => [:test]
67
+
68
+ # Base GEM Specification
69
+ spec = Gem::Specification.new do |spec|
70
+ spec.name = "rb-trace"
71
+
72
+ spec.homepage = "http://github.com/rocky/rb-trace/tree/master"
73
+ spec.summary = "Trace hook extensions"
74
+ spec.description = <<-EOF
75
+
76
+ rb-trace adds a trace_hook object, translates hooks bitmasks to sets
77
+ and vice versa, and extends set_trace_func to ignore frames or
78
+ functions.
79
+ EOF
80
+
81
+ spec.version = PACKAGE_VERSION
82
+ spec.extensions = ['ext/extconf.rb']
83
+
84
+ spec.author = "R. Bernstein"
85
+ spec.email = "rockyb@rubyforge.org"
86
+ spec.platform = Gem::Platform::RUBY
87
+ spec.files = ALL_FILES.to_a
88
+ spec.add_dependency('rb-threadframe', '>= 0.32')
89
+
90
+ spec.required_ruby_version = '>= 1.9.2'
91
+ spec.date = Time.now
92
+ # spec.rubyforge_project = 'rocky-hacks'
93
+
94
+ # rdoc
95
+ spec.has_rdoc = true
96
+ # spec.extra_rdoc_files = ['README', 'threadframe.rd']
97
+ end
98
+
99
+ # Rake task to build the default package
100
+ Rake::GemPackageTask.new(spec) do |pkg|
101
+ pkg.need_tar = true
102
+ end
103
+
104
+ def install(spec, *opts)
105
+ args = ['gem', 'install', "pkg/#{spec.name}-#{spec.version}.gem"] + opts
106
+ system(*args)
107
+ end
108
+
109
+ desc 'Install locally'
110
+ task :install => :package do
111
+ Dir.chdir(File::dirname(__FILE__)) do
112
+ # ri and rdoc take lots of time
113
+ install(spec, '--no-ri', '--no-rdoc')
114
+ end
115
+ end
116
+
117
+ task :install_full => :package do
118
+ Dir.chdir(File::dirname(__FILE__)) do
119
+ install(spec)
120
+ end
121
+ end
data/ext/extconf.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "mkmf"
2
+
3
+ config_file = File.join(File.dirname(__FILE__), 'config_options')
4
+ load config_file if File.exist?(config_file)
5
+
6
+ # Temporary: to turn off optimization
7
+ # $CFLAGS='-fno-strict-aliasing -g -fPIC'
8
+ create_makefile("trace")
@@ -0,0 +1,24 @@
1
+ /**********************************************************************
2
+
3
+ thread_pthread.h -
4
+
5
+ $Author$
6
+
7
+ Copyright (C) 2004-2007 Koichi Sasada
8
+
9
+ **********************************************************************/
10
+
11
+ #ifndef RUBY_THREAD_PTHREAD_H
12
+ #define RUBY_THREAD_PTHREAD_H
13
+
14
+ #include <pthread.h>
15
+ typedef pthread_t rb_thread_id_t;
16
+ typedef pthread_mutex_t rb_thread_lock_t;
17
+ typedef pthread_cond_t rb_thread_cond_t;
18
+
19
+ typedef struct native_thread_data_struct {
20
+ void *signal_thread_list;
21
+ pthread_cond_t sleep_cond;
22
+ } native_thread_data_t;
23
+
24
+ #endif /* RUBY_THREAD_PTHREAD_H */
data/ext/trace.c ADDED
@@ -0,0 +1,160 @@
1
+ #include "vm_core_mini.h" /* Pulls in ruby.h */
2
+
3
+ /* What release we got? */
4
+ #define TRACE_VERSION "0.2"
5
+
6
+ extern VALUE rb_cRubyVM; /* RubyVM class */
7
+ extern rb_vm_t *ruby_current_vm;
8
+ extern VALUE rb_obj_is_proc(VALUE proc);
9
+
10
+ VALUE rb_cTraceHook; /* TraceHook class */
11
+ VALUE rb_eTraceHookError; /* Exception raised by TraceHook class */
12
+
13
+ /* Extra information we need to save about a hook.
14
+ FIXME: For now we will work only with vm hooks. When this
15
+ extends to thread hooks, we will need to use this.
16
+ */
17
+ typedef struct
18
+ {
19
+ rb_thread_t *th; /* If NULL, hook is in vm. Otherwise, this
20
+ is the thread the hook belongs to. */
21
+ rb_event_hook_t *hook;
22
+ } hook_info_t;
23
+
24
+ static int is_hook_member(rb_event_hook_t *check_hook, rb_event_hook_t *hook);
25
+
26
+ static void
27
+ check_hook_valid(rb_event_hook_t *check_hook)
28
+ {
29
+ /* FIXME: in the future use check_hook to find the hook head. */
30
+ rb_event_hook_t *hook_head = GET_VM()->event_hooks;
31
+
32
+ if (!is_hook_member(check_hook, hook_head))
33
+ rb_raise(rb_eTraceHookError, "hook not found");
34
+ }
35
+
36
+ /* Return an Array of vm event hooks found from hook. */
37
+ VALUE
38
+ get_trace_hooks(rb_event_hook_t *hook)
39
+ {
40
+ VALUE ary;
41
+ for (ary = rb_ary_new(); hook; hook = hook->next)
42
+ rb_ary_push(ary, Data_Wrap_Struct(rb_cTraceHook, NULL, NULL, hook));
43
+ return ary;
44
+ }
45
+
46
+ /* Return 1 if check_hook is found in the list of hooks pointed to by
47
+ 'hook', or 0 if not found. */
48
+ static int
49
+ is_hook_member(rb_event_hook_t *check_hook, rb_event_hook_t *hook)
50
+ {
51
+ for (; hook; hook = hook->next) if (check_hook == hook) return 1;
52
+ return 0; /* Not found */
53
+ }
54
+
55
+ /* Return an Array of VM event hooks objects. */
56
+ VALUE
57
+ trace_hook_s_trace_hooks()
58
+ {
59
+ return get_trace_hooks(GET_VM()->event_hooks);
60
+ }
61
+
62
+ /*
63
+ Return the event mask value for a given hook. If no hook, then return nil.
64
+ */
65
+ static VALUE
66
+ trace_hook_event_mask(VALUE klass)
67
+ {
68
+ rb_event_hook_t *hook;
69
+ Data_Get_Struct(klass, rb_event_hook_t, hook);
70
+ if (!hook) return Qnil;
71
+ check_hook_valid(hook);
72
+ return INT2FIX(hook->flag);
73
+ }
74
+
75
+ /* Set a new mask value for given hook and return the old mask
76
+ value. Can raise an error if there is no hook installed. */
77
+ static VALUE
78
+ trace_hook_event_mask_set(VALUE klass, VALUE maskval)
79
+ {
80
+ rb_event_hook_t *hook;
81
+ rb_event_flag_t flag;
82
+ Data_Get_Struct(klass, rb_event_hook_t, hook);
83
+ if (!hook)
84
+ rb_raise(rb_eTraceHookError, "No hook installed");
85
+ if (!FIXNUM_P(maskval)) {
86
+ rb_raise(rb_eTypeError, "integer argument expected");
87
+ }
88
+ check_hook_valid(hook);
89
+ flag = hook->flag;
90
+ hook->flag = FIX2INT(maskval);
91
+ return INT2FIX(flag);
92
+ }
93
+
94
+ /*
95
+ Return the event mask value for a given hook. If no hook, then return nil.
96
+ */
97
+ static VALUE
98
+ trace_hook_proc(VALUE klass)
99
+ {
100
+ rb_event_hook_t *hook;
101
+ Data_Get_Struct(klass, rb_event_hook_t, hook);
102
+ if (!hook) return Qnil;
103
+ check_hook_valid(hook);
104
+ return hook->data;
105
+ }
106
+
107
+ /*
108
+ Return the event mask value for a given hook. If no hook, then return nil.
109
+ */
110
+ static VALUE
111
+ trace_hook_proc_set(VALUE klass, VALUE trace_proc)
112
+ {
113
+ rb_event_hook_t *hook;
114
+ if (!rb_obj_is_proc(trace_proc)) {
115
+ rb_raise(rb_eTypeError, "trace_func needs to be Proc");
116
+ }
117
+
118
+ Data_Get_Struct(klass, rb_event_hook_t, hook);
119
+ if (!hook) return Qnil;
120
+ check_hook_valid(hook);
121
+ hook->data = trace_proc;
122
+ return trace_proc;
123
+ }
124
+
125
+ /*
126
+ Return true if hook is still valid or is nil), false otherwise.
127
+ */
128
+ static VALUE
129
+ trace_hook_valid(VALUE klass)
130
+ {
131
+ rb_event_hook_t *hook;
132
+ Data_Get_Struct(klass, rb_event_hook_t, hook);
133
+ /* FIXME in the future we will need to extract whether this hook is
134
+ part of a thread or from the vm.
135
+ */
136
+ return is_hook_member(hook, GET_VM()->event_hooks) ? Qtrue : Qfalse;
137
+ }
138
+
139
+ void
140
+ Init_trace(void)
141
+ {
142
+ rb_eTraceHookError = rb_define_class_under(rb_cRubyVM, "TraceHookError",
143
+ rb_eStandardError);
144
+ rb_cTraceHook = rb_define_class_under(rb_cRubyVM, "TraceHook",
145
+ rb_cObject);
146
+
147
+ rb_define_singleton_method(rb_cTraceHook, "trace_hooks",
148
+ trace_hook_s_trace_hooks, 0);
149
+
150
+ rb_define_method(rb_cTraceHook, "event_mask",
151
+ trace_hook_event_mask, 0);
152
+ rb_define_method(rb_cTraceHook, "event_mask=",
153
+ trace_hook_event_mask_set, 1);
154
+ rb_define_method(rb_cTraceHook, "proc",
155
+ trace_hook_proc, 0);
156
+ rb_define_method(rb_cTraceHook, "proc=",
157
+ trace_hook_proc_set, 1);
158
+ rb_define_method(rb_cTraceHook, "valid?",
159
+ trace_hook_valid, 0);
160
+ }
@@ -0,0 +1,133 @@
1
+ /* Headers Exposing a little more of the 1.9 runtime and some
2
+ method prototypes for extensions to the Thread class.
3
+ */
4
+ #include <ruby.h>
5
+ #include <signal.h>
6
+ #include "thread_pthread.h"
7
+
8
+ /* From vm_core.h: */
9
+
10
+ #define GET_VM() ruby_current_vm
11
+ #define GET_THREAD() ruby_current_thread
12
+
13
+ #if 1
14
+ #define GetCoreDataFromValue(obj, type, ptr) do { \
15
+ ptr = (type*)DATA_PTR(obj); \
16
+ } while (0)
17
+ #else
18
+ #define GetCoreDataFromValue(obj, type, ptr) Data_Get_Struct(obj, type, ptr)
19
+ #endif
20
+ #if 1
21
+ #define GetCoreDataFromValue(obj, type, ptr) do { \
22
+ ptr = (type*)DATA_PTR(obj); \
23
+ } while (0)
24
+ #else
25
+ #define GetCoreDataFromValue(obj, type, ptr) Data_Get_Struct(obj, type, ptr)
26
+ #endif
27
+
28
+ /* Opaque types (for now at least) */
29
+ typedef struct rb_iseq_struct rb_iseq_t;
30
+ typedef struct rb_method_entry_struct rb_method_entry_t;
31
+ typedef struct rb_proc_struct rb_proc_t;
32
+
33
+ typedef struct {
34
+ VALUE *pc; /* cfp[0] */
35
+ VALUE *sp; /* cfp[1] */
36
+ VALUE *bp; /* cfp[2] */
37
+ rb_iseq_t *iseq; /* cfp[3] */
38
+ VALUE flag; /* cfp[4] */
39
+ VALUE self; /* cfp[5] / block[0] */
40
+ VALUE *lfp; /* cfp[6] / block[1] */
41
+ VALUE *dfp; /* cfp[7] / block[2] */
42
+ rb_iseq_t *block_iseq; /* cfp[8] / block[3] */
43
+ VALUE proc; /* cfp[9] / block[4] */
44
+ const rb_method_entry_t *me;/* cfp[10] */
45
+ } rb_control_frame_t;
46
+
47
+ enum ruby_special_exceptions {
48
+ ruby_error_reenter,
49
+ ruby_error_nomemory,
50
+ ruby_error_sysstack,
51
+ ruby_special_error_count
52
+ };
53
+
54
+ #define GetThreadPtr(obj, ptr) \
55
+ GetCoreDataFromValue(obj, rb_thread_t, ptr)
56
+
57
+ #define GetProcPtr(obj, ptr) \
58
+ GetCoreDataFromValue(obj, rb_proc_t, ptr)
59
+
60
+ #ifndef NSIG
61
+ # define NSIG (_SIGMAX + 1) /* For QNX */
62
+ #endif
63
+
64
+ #define RUBY_NSIG NSIG
65
+ typedef struct rb_vm_struct {
66
+ VALUE self;
67
+
68
+ rb_thread_lock_t global_vm_lock;
69
+
70
+ struct rb_thread_struct *main_thread;
71
+ struct rb_thread_struct *running_thread;
72
+
73
+ st_table *living_threads;
74
+ VALUE thgroup_default;
75
+
76
+ int running;
77
+ int thread_abort_on_exception;
78
+ unsigned long trace_flag;
79
+ volatile int sleeper;
80
+
81
+ /* object management */
82
+ VALUE mark_object_ary;
83
+
84
+ VALUE special_exceptions[ruby_special_error_count];
85
+
86
+ /* load */
87
+ VALUE top_self;
88
+ VALUE load_path;
89
+ VALUE loaded_features;
90
+ struct st_table *loading_table;
91
+
92
+ /* signal */
93
+ struct {
94
+ VALUE cmd;
95
+ int safe;
96
+ } trap_list[RUBY_NSIG];
97
+
98
+ /* hook */
99
+ rb_event_hook_t *event_hooks;
100
+
101
+ int src_encoding_index;
102
+
103
+ VALUE verbose, debug, progname;
104
+ VALUE coverages;
105
+
106
+ #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
107
+ struct rb_objspace *objspace;
108
+ #endif
109
+ } rb_vm_t;
110
+
111
+ typedef struct rb_thread_struct
112
+ {
113
+ VALUE self;
114
+ rb_vm_t *vm;
115
+
116
+ /* execution information */
117
+ VALUE *stack; /* must free, must mark. rb: seems to be nil. */
118
+ unsigned long stack_size; /* Number of stack (or rb_control_frame_t) entries */
119
+ rb_control_frame_t *cfp;
120
+
121
+ int safe_level;
122
+ int raised_flag;
123
+ VALUE last_status; /* $? */
124
+
125
+ /* passing state */
126
+ int state;
127
+
128
+ /* Lot's of other stuff ... */
129
+ } rb_thread_t;
130
+
131
+ extern rb_thread_t *ruby_current_thread;
132
+
133
+
@@ -0,0 +1,172 @@
1
+ module Trace
2
+
3
+ class EventBuffer
4
+ EventStruct = Struct.new(:event, :arg, :type, :thread, :method,
5
+ :source_container, :source_location,
6
+ :iseq, :pc_offset) unless defined?(EventStruct)
7
+ attr_reader :buf
8
+ attr_accessor :marks # User position mark into buffer. If buffer is limited,
9
+ attr_reader :maxsize # Maximum size of buffer or nil if unlimited.
10
+ attr_reader :size # size of buffer
11
+ # then marks will drop out as they disappear from the buffer
12
+ def initialize(maxsize=nil)
13
+ @maxsize = maxsize
14
+ reset
15
+ end
16
+
17
+ def reset
18
+ @buf = []
19
+ @marks = []
20
+ @pos = -1
21
+ @size = 0
22
+ end
23
+
24
+ # Add a new event dropping off old events if that was declared
25
+ # marks are also dropped if buffer has a limit.
26
+ def append(event, frame, arg)
27
+ if 'c-return' == event
28
+ arg = frame.sp(2)
29
+ elsif 'return' == event
30
+ arg = frame.sp(1)
31
+ end
32
+
33
+ iseq = frame.iseq
34
+ item = EventStruct.new(event, arg, frame.type, frame.thread, frame.method,
35
+ frame.source_container, frame.source_location,
36
+ iseq, iseq ? frame.pc_offset : nil)
37
+ @pos = self.succ_pos
38
+ @marks.shift if @marks[0] == @pos
39
+ @buf[@pos] = item
40
+ @size += 1 unless @maxsize && @size == @maxsize
41
+ end
42
+
43
+ # Add mark for the current event buffer position.
44
+ def add_mark
45
+ @marks << @pos
46
+ end
47
+
48
+ # Like add mark, but do only if the last marked position has
49
+ # changed
50
+ def add_mark_nodup
51
+ @marks << @pos unless @marks[-1] == @pos
52
+ end
53
+
54
+ def each(from=nil, to=nil)
55
+ from = self.succ_pos unless from
56
+ to = @pos unless to
57
+ if from <= to
58
+ from.upto(to).each do |pos|
59
+ yield @buf[pos]
60
+ end
61
+ else
62
+ from.upto(@size-1).each do |pos|
63
+ yield @buf[pos]
64
+ end
65
+ 0.upto(@pos).each do |pos|
66
+ yield @buf[pos]
67
+ end
68
+ end
69
+ end
70
+
71
+ def each_with_index(from=nil, to=nil)
72
+ from = succ_pos unless from
73
+ to = @pos unless to
74
+ if from <= to
75
+ from.upto(to).each do |pos|
76
+ yield [@buf[pos], pos]
77
+ end
78
+ else
79
+ from.upto(@size-1).each do |pos|
80
+ yield [@buf[pos], pos]
81
+ end
82
+ 0.upto(@pos).each do |pos|
83
+ yield [@buf[pos], pos]
84
+ end
85
+ end
86
+ end
87
+
88
+ def format_entry(item, long_format=true)
89
+ # require 'rbdbgr'; Debugger.debug
90
+ container =
91
+ if item.source_container[0] == 'file'
92
+ item.source_container[1].inspect
93
+ else
94
+ item.source_container.inspect
95
+ end
96
+
97
+ location =
98
+ if 1 == item.source_location.size
99
+ item.source_location[0].inspect
100
+ else
101
+ item.source_location.inspect
102
+ end
103
+
104
+ mess = "#{item.event} #{item.type} #{item.method} " +
105
+ "#{container} #{location}"
106
+ if long_format && item.iseq
107
+ mess += "\n\t" + "VM offset #{item.pc_offset} of #{item.iseq.name}"
108
+ end
109
+ mess
110
+ end
111
+
112
+ # Return the next event buffer position taking into account
113
+ # that we may have a fixed-sized buffer ring.
114
+ def succ_pos(inc=1)
115
+ pos = @pos + inc
116
+ @maxsize ? pos % @maxsize : pos
117
+ end
118
+
119
+ # Return the next event buffer position taking into account
120
+ # that we may have a fixed-sized buffer ring.
121
+ def pred_pos(dec=1)
122
+ pos = @pos - dec
123
+ @maxsize ? pos % @maxsize : pos
124
+ end
125
+
126
+ # Return the adjusted zeroth position in @buf.
127
+ def zero_pos
128
+ if !@maxsize || @buf.size < @maxsize
129
+ 0
130
+ else
131
+ self.succ_pos
132
+ end
133
+ end
134
+
135
+ end # EventBuffer
136
+ end # Trace
137
+
138
+ if __FILE__ == $0
139
+ def event_processor(event, frame, arg=nil)
140
+ begin
141
+ @eventbuf.append(event, frame, arg)
142
+ rescue
143
+ p $!
144
+ end
145
+ end
146
+ def dump_all
147
+ puts '-' * 40
148
+ @eventbuf.each do |e|
149
+ puts @eventbuf.format_entry(e) if e
150
+ end
151
+ end
152
+
153
+ require_relative 'trace'
154
+ @eventbuf = Trace::EventBuffer.new(5)
155
+ p @eventbuf.zero_pos
156
+ dump_all
157
+
158
+ trace_filter = Trace::Filter.new
159
+ trace_func = method(:event_processor).to_proc
160
+ trace_filter << trace_func
161
+ trace_filter.set_trace_func(trace_func)
162
+ z=5
163
+ z.times do |i|
164
+ x = i
165
+ y = x+2
166
+ end
167
+ trace_filter.set_trace_func(nil)
168
+ p @eventbuf.buf[@eventbuf.zero_pos]
169
+ dump_all
170
+ @eventbuf.reset
171
+ dump_all
172
+ end
data/lib/trace.rb ADDED
@@ -0,0 +1,3 @@
1
+ require_relative 'trace_mod'
2
+ require_relative 'tracefilter'
3
+ require_relative 'eventbuffer'