ruby-debug-base 0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (9) hide show
  1. data/AUTHORS +6 -0
  2. data/CHANGES +143 -0
  3. data/LICENSE +23 -0
  4. data/README +63 -0
  5. data/ext/extconf.rb +18 -0
  6. data/ext/ruby_debug.c +2175 -0
  7. data/ext/tags +118 -0
  8. data/lib/ruby-debug-base.rb +230 -0
  9. metadata +55 -0
@@ -0,0 +1,118 @@
1
+ CTX_FL_SET ruby_debug.c /^#define CTX_FL_SET(c,f) do { (c)->flags |= (f); } /
2
+ CTX_FL_TEST ruby_debug.c /^#define CTX_FL_TEST(c,f) ((c)->flags & (f))$/
3
+ CTX_FL_UNSET ruby_debug.c /^#define CTX_FL_UNSET(c,f) do { (c)->flags &= ~(f);/
4
+ FRAME ruby_debug.c /^struct FRAME {$/
5
+ FRAME_N ruby_debug.c /^#define FRAME_N(n) (&debug_context->frames[debug_/
6
+ Init_breakpoint ruby_debug.c /^Init_breakpoint()$/
7
+ Init_context ruby_debug.c /^Init_context()$/
8
+ Init_ruby_debug ruby_debug.c /^Init_ruby_debug()$/
9
+ RVarmap ruby_debug.c /^struct RVarmap {$/
10
+ SCOPE ruby_debug.c /^struct SCOPE {$/
11
+ VALUE ruby_debug.c /^ typedef VALUE (*id2ref_func_t)(VALUE, VALUE);$/
12
+ add_to_locked ruby_debug.c /^add_to_locked(VALUE thread)$/
13
+ bp_type ruby_debug.c /^enum bp_type {BP_POS_TYPE, BP_METHOD_TYPE};$/
14
+ breakpoint_expr ruby_debug.c /^breakpoint_expr(VALUE self)$/
15
+ breakpoint_id ruby_debug.c /^breakpoint_id(VALUE self)$/
16
+ breakpoint_mark ruby_debug.c /^breakpoint_mark(void *data)$/
17
+ breakpoint_pos ruby_debug.c /^breakpoint_pos(VALUE self)$/
18
+ breakpoint_source ruby_debug.c /^breakpoint_source(VALUE self)$/
19
+ call_at_line ruby_debug.c /^call_at_line(VALUE context, debug_context_t *debug/
20
+ call_at_line_unprotected ruby_debug.c /^call_at_line_unprotected(VALUE args)$/
21
+ check_breakpoint_expression ruby_debug.c /^check_breakpoint_expression(VALUE breakpoint, VALU/
22
+ check_breakpoints_by_method ruby_debug.c /^check_breakpoints_by_method(debug_context_t *debug/
23
+ check_breakpoints_by_pos ruby_debug.c /^check_breakpoints_by_pos(debug_context_t *debug_co/
24
+ check_frame_number ruby_debug.c /^check_frame_number(debug_context_t *debug_context,/
25
+ check_thread_contexts ruby_debug.c /^check_thread_contexts()$/
26
+ classname_cmp ruby_debug.c /^classname_cmp(VALUE name, VALUE klass)$/
27
+ context_copy_locals ruby_debug.c /^context_copy_locals(debug_frame_t *debug_frame)$/
28
+ context_dead ruby_debug.c /^context_dead(VALUE self)$/
29
+ context_frame_binding ruby_debug.c /^context_frame_binding(VALUE self, VALUE frame)$/
30
+ context_frame_file ruby_debug.c /^context_frame_file(VALUE self, VALUE frame)$/
31
+ context_frame_id ruby_debug.c /^context_frame_id(VALUE self, VALUE frame)$/
32
+ context_frame_line ruby_debug.c /^context_frame_line(VALUE self, VALUE frame)$/
33
+ context_frame_locals ruby_debug.c /^context_frame_locals(VALUE self, VALUE frame)$/
34
+ context_frame_self ruby_debug.c /^context_frame_self(VALUE self, VALUE frame)$/
35
+ context_ignore ruby_debug.c /^context_ignore(VALUE self)$/
36
+ context_is_suspended ruby_debug.c /^context_is_suspended(VALUE self)$/
37
+ context_resume ruby_debug.c /^context_resume(VALUE self)$/
38
+ context_resume_0 ruby_debug.c /^context_resume_0(debug_context_t *debug_context)$/
39
+ context_set_tracing ruby_debug.c /^context_set_tracing(VALUE self, VALUE value)$/
40
+ context_stack_size ruby_debug.c /^context_stack_size(VALUE self)$/
41
+ context_step_over ruby_debug.c /^context_step_over(int argc, VALUE *argv, VALUE sel/
42
+ context_stop_frame ruby_debug.c /^context_stop_frame(VALUE self, VALUE frame)$/
43
+ context_stop_next ruby_debug.c /^context_stop_next(VALUE self, VALUE steps)$/
44
+ context_suspend ruby_debug.c /^context_suspend(VALUE self)$/
45
+ context_suspend_0 ruby_debug.c /^context_suspend_0(debug_context_t *debug_context)$/
46
+ context_thnum ruby_debug.c /^context_thnum(VALUE self)$/
47
+ context_thread ruby_debug.c /^context_thread(VALUE self)$/
48
+ context_thread_0 ruby_debug.c /^context_thread_0(debug_context_t *debug_context)$/
49
+ context_tracing ruby_debug.c /^context_tracing(VALUE self)$/
50
+ create_binding ruby_debug.c /^create_binding(VALUE self)$/
51
+ debug_add_breakpoint ruby_debug.c /^debug_add_breakpoint(int argc, VALUE *argv, VALUE /
52
+ debug_at_exit ruby_debug.c /^debug_at_exit(VALUE self)$/
53
+ debug_at_exit_c ruby_debug.c /^debug_at_exit_c(VALUE proc)$/
54
+ debug_at_exit_i ruby_debug.c /^debug_at_exit_i(VALUE proc)$/
55
+ debug_breakpoint_t ruby_debug.c /^} debug_breakpoint_t;$/
56
+ debug_breakpoints ruby_debug.c /^debug_breakpoints(VALUE self)$/
57
+ debug_catchpoint ruby_debug.c /^debug_catchpoint(VALUE self)$/
58
+ debug_check_started ruby_debug.c /^debug_check_started()$/
59
+ debug_context_create ruby_debug.c /^debug_context_create(VALUE thread)$/
60
+ debug_context_dup ruby_debug.c /^debug_context_dup(debug_context_t *debug_context)$/
61
+ debug_context_free ruby_debug.c /^debug_context_free(void *data)$/
62
+ debug_context_mark ruby_debug.c /^debug_context_mark(void *data)$/
63
+ debug_context_t ruby_debug.c /^} debug_context_t;$/
64
+ debug_contexts ruby_debug.c /^debug_contexts(VALUE self)$/
65
+ debug_current_context ruby_debug.c /^debug_current_context(VALUE self)$/
66
+ debug_debug_load ruby_debug.c /^debug_debug_load(VALUE self, VALUE file)$/
67
+ debug_event_hook ruby_debug.c /^debug_event_hook(rb_event_t event, NODE *node, VAL/
68
+ debug_frame_t ruby_debug.c /^} debug_frame_t;$/
69
+ debug_is_started ruby_debug.c /^debug_is_started(VALUE self)$/
70
+ debug_keep_frame_binding ruby_debug.c /^debug_keep_frame_binding(VALUE self)$/
71
+ debug_last_interrupted ruby_debug.c /^debug_last_interrupted(VALUE self)$/
72
+ debug_post_mortem ruby_debug.c /^debug_post_mortem(VALUE self)$/
73
+ debug_remove_breakpoint ruby_debug.c /^debug_remove_breakpoint(VALUE self, VALUE id_value/
74
+ debug_resume ruby_debug.c /^debug_resume(VALUE self)$/
75
+ debug_set_catchpoint ruby_debug.c /^debug_set_catchpoint(VALUE self, VALUE value)$/
76
+ debug_set_keep_frame_binding ruby_debug.c /^debug_set_keep_frame_binding(VALUE self, VALUE val/
77
+ debug_set_post_mortem ruby_debug.c /^debug_set_post_mortem(VALUE self, VALUE value)$/
78
+ debug_set_tracing ruby_debug.c /^debug_set_tracing(VALUE self, VALUE value)$/
79
+ debug_skip ruby_debug.c /^debug_skip(VALUE self)$/
80
+ debug_start ruby_debug.c /^debug_start(VALUE self)$/
81
+ debug_stop ruby_debug.c /^debug_stop(VALUE self)$/
82
+ debug_stop_i ruby_debug.c /^debug_stop_i(VALUE self)$/
83
+ debug_suspend ruby_debug.c /^debug_suspend(VALUE self)$/
84
+ debug_thread_context ruby_debug.c /^debug_thread_context(VALUE self, VALUE thread)$/
85
+ debug_thread_inherited ruby_debug.c /^debug_thread_inherited(VALUE klass)$/
86
+ debug_tracing ruby_debug.c /^debug_tracing(VALUE self)$/
87
+ eval_expression ruby_debug.c /^eval_expression(VALUE args)$/
88
+ filename_cmp ruby_debug.c /^filename_cmp(VALUE source, char *file)$/
89
+ find_last_context_func ruby_debug.c /^find_last_context_func(VALUE key, VALUE value, VAL/
90
+ get_breakpoint_at ruby_debug.c /^get_breakpoint_at(int index) $/
91
+ get_event_name ruby_debug.c /^get_event_name(rb_event_t event)$/
92
+ get_top_frame ruby_debug.c /^get_top_frame(debug_context_t *debug_context)$/
93
+ id2ref ruby_debug.c /^id2ref(VALUE id)$/
94
+ id2ref_error ruby_debug.c /^id2ref_error()$/
95
+ id2ref_unprotected ruby_debug.c /^id2ref_unprotected(VALUE id)$/
96
+ is_in_locked ruby_debug.c /^is_in_locked(VALUE thread_id)$/
97
+ is_thread_alive ruby_debug.c /^is_thread_alive(VALUE thread)$/
98
+ isdirsep ruby_debug.c /^#define isdirsep(x) ((x) == '\/' || (x) == '\\\\')/
99
+ locked_thread_t ruby_debug.c /^} locked_thread_t;$/
100
+ min ruby_debug.c /^#define min(x,y) ((x) < (y) ? (x) : (y))$/
101
+ ref2id ruby_debug.c /^ref2id(VALUE obj)$/
102
+ remove_from_locked ruby_debug.c /^remove_from_locked()$/
103
+ ruby_method_ptr ruby_debug.c /^ruby_method_ptr(VALUE class, ID meth_id)$/
104
+ save_call_frame ruby_debug.c /^save_call_frame(VALUE self, char *file, int line, /
105
+ save_current_position ruby_debug.c /^save_current_position(debug_context_t *debug_conte/
106
+ save_top_binding ruby_debug.c /^save_top_binding(debug_context_t *debug_context, V/
107
+ set_current_skipped_status ruby_debug.c /^set_current_skipped_status(VALUE status)$/
108
+ set_dyna_vars ruby_debug.c /^set_dyna_vars(debug_context_t *debug_context)$/
109
+ set_frame_source ruby_debug.c /^set_frame_source(debug_context_t *debug_context, c/
110
+ thread_context_lookup ruby_debug.c /^thread_context_lookup(VALUE thread, VALUE *context/
111
+ threads_table_check_i ruby_debug.c /^threads_table_check_i(VALUE key, VALUE value, VALU/
112
+ threads_table_clear ruby_debug.c /^threads_table_clear(VALUE table)$/
113
+ threads_table_clear_i ruby_debug.c /^threads_table_clear_i(VALUE key, VALUE value, VALU/
114
+ threads_table_create ruby_debug.c /^threads_table_create()$/
115
+ threads_table_free ruby_debug.c /^threads_table_free(void* data)$/
116
+ threads_table_mark ruby_debug.c /^threads_table_mark(void* data)$/
117
+ threads_table_mark_keyvalue ruby_debug.c /^threads_table_mark_keyvalue(VALUE key, VALUE value/
118
+ threads_table_t ruby_debug.c /^} threads_table_t;$/
@@ -0,0 +1,230 @@
1
+ require 'ruby_debug.so'
2
+
3
+ SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
4
+ SCRIPT_TIMESTAMPS__ = {} unless defined? SCRIPT_TIMESTAMPS__
5
+
6
+ module Debugger
7
+ class Context
8
+ def interrupt
9
+ self.stop_next = 1
10
+ end
11
+
12
+ alias __c_frame_binding frame_binding
13
+ def frame_binding(frame)
14
+ __c_frame_binding(frame) || hbinding(frame)
15
+ end
16
+
17
+ private
18
+
19
+ def hbinding(frame)
20
+ hash = frame_locals(frame)
21
+ code = hash.keys.map{|k| "#{k} = hash['#{k}']"}.join(';') + ';binding'
22
+ if obj = frame_self(frame)
23
+ obj.instance_eval code
24
+ else
25
+ eval code
26
+ end
27
+ end
28
+
29
+ def handler
30
+ Debugger.handler or raise 'No interface loaded'
31
+ end
32
+
33
+ def at_breakpoint(breakpoint)
34
+ handler.at_breakpoint(self, breakpoint)
35
+ end
36
+
37
+ def at_catchpoint(excpt)
38
+ handler.at_catchpoint(self, excpt)
39
+ end
40
+
41
+ def at_tracing(file, line)
42
+ handler.at_tracing(self, file, line)
43
+ end
44
+
45
+ def at_line(file, line)
46
+ handler.at_line(self, file, line)
47
+ end
48
+ end
49
+
50
+ @reload_source_on_change = false
51
+
52
+ class << self
53
+ # interface modules provide +handler+ object
54
+ attr_accessor :handler
55
+
56
+ # if <tt>true</tt>, checks the modification time of source files and reloads if it was modified
57
+ attr_accessor :reload_source_on_change
58
+
59
+ #
60
+ # Interrupts the current thread
61
+ #
62
+ def interrupt
63
+ current_context.interrupt
64
+ end
65
+
66
+ #
67
+ # Interrupts the last debugged thread
68
+ #
69
+ def interrupt_last
70
+ if context = last_context
71
+ return nil unless context.thread.alive?
72
+ context.interrupt
73
+ end
74
+ context
75
+ end
76
+
77
+ def source_for(file) # :nodoc:
78
+ finder = lambda do
79
+ if File.exists?(file)
80
+ if SCRIPT_LINES__[file].nil? || SCRIPT_LINES__[file] == true
81
+ SCRIPT_LINES__[file] = File.readlines(file)
82
+ end
83
+
84
+ change_time = test(?M, file)
85
+ SCRIPT_TIMESTAMPS__[file] ||= change_time
86
+ if @reload_source_on_change && SCRIPT_TIMESTAMPS__[file] < change_time
87
+ SCRIPT_LINES__[file] = File.readlines(file)
88
+ end
89
+
90
+ SCRIPT_LINES__[file]
91
+ end
92
+ end
93
+
94
+ Dir.chdir(File.dirname($0)){finder.call} || finder.call ||
95
+ (SCRIPT_LINES__[file] == true ? nil : SCRIPT_LINES__[file])
96
+ end
97
+
98
+ def source_reload
99
+ SCRIPT_LINES__.keys.each do |file|
100
+ next unless File.exists?(file)
101
+ SCRIPT_LINES__[file] = nil
102
+ end
103
+ end
104
+
105
+ def line_at(file, line) # :nodoc:
106
+ lines = source_for(file)
107
+ if lines
108
+ line = lines[line-1]
109
+ return "\n" unless line
110
+ return "#{line.gsub(/^\s+/, '').chomp}\n"
111
+ end
112
+ return "\n"
113
+ end
114
+
115
+ #
116
+ # Activates the post-mortem mode. There are two ways of using it:
117
+ #
118
+ # == Global post-mortem mode
119
+ # By calling Debugger.post_mortem method without a block, you install
120
+ # at_exit hook that intercepts any unhandled by your script exceptions
121
+ # and enables post-mortem mode.
122
+ #
123
+ # == Local post-mortem mode
124
+ #
125
+ # If you know that a particular block of code raises an exception you can
126
+ # enable post-mortem mode by wrapping this block with Debugger.post_mortem, e.g.
127
+ #
128
+ # def offender
129
+ # raise 'error'
130
+ # end
131
+ # Debugger.post_mortem do
132
+ # ...
133
+ # offender
134
+ # ...
135
+ # end
136
+ def post_mortem
137
+ raise "Post-mortem is already activated" if self.post_mortem?
138
+ self.post_mortem = true
139
+ if block_given?
140
+ begin
141
+ yield
142
+ rescue Exception => exp
143
+ handle_post_mortem(exp)
144
+ raise
145
+ ensure
146
+ self.post_mortem = false
147
+ end
148
+ else
149
+ debug_at_exit do
150
+ handle_post_mortem($!) if $! && post_mortem?
151
+ end
152
+ end
153
+ end
154
+
155
+ def handle_post_mortem(exp)
156
+ return if exp.__debug_context.stack_size == 0
157
+ Debugger.suspend
158
+ orig_tracing = Debugger.tracing, Debugger.current_context.tracing
159
+ Debugger.tracing = Debugger.current_context.tracing = false
160
+ handler.at_line(exp.__debug_context, exp.__debug_file, exp.__debug_line)
161
+ ensure
162
+ Debugger.tracing, Debugger.current_context.tracing = orig_tracing
163
+ Debugger.resume
164
+ end
165
+ private :handle_post_mortem
166
+ end
167
+
168
+ class DebugThread # :nodoc:
169
+ end
170
+
171
+ class ThreadsTable # :nodoc:
172
+ end
173
+ end
174
+
175
+ class Exception # :nodoc:
176
+ attr_reader :__debug_file, :__debug_line, :__debug_binding, :__debug_context
177
+ end
178
+
179
+ module Kernel
180
+ #
181
+ # Stops the current thread after a number of _steps_ made.
182
+ #
183
+ def debugger(steps = 1)
184
+ Debugger.current_context.stop_next = steps
185
+ end
186
+
187
+ #
188
+ # Returns a binding of n-th call frame
189
+ #
190
+ def binding_n(n = 0)
191
+ Debugger.current_context.frame_binding[n+1]
192
+ end
193
+ end
194
+
195
+ class Module
196
+ #
197
+ # Wraps the +meth+ method with Debugger.start {...} block.
198
+ #
199
+ def debug_method(meth)
200
+ old_meth = "__debugee_#{meth}"
201
+ old_meth = "#{$1}_set" if old_meth =~ /^(.+)=$/
202
+ alias_method old_meth.to_sym, meth
203
+ class_eval <<-EOD
204
+ def #{meth}(*args, &block)
205
+ Debugger.start do
206
+ debugger 2
207
+ #{old_meth}(*args, &block)
208
+ end
209
+ end
210
+ EOD
211
+ end
212
+
213
+ #
214
+ # Wraps the +meth+ method with Debugger.post_mortem {...} block.
215
+ #
216
+ def post_mortem_method(meth)
217
+ old_meth = "__postmortem_#{meth}"
218
+ old_meth = "#{$1}_set" if old_meth =~ /^(.+)=$/
219
+ alias_method old_meth.to_sym, meth
220
+ class_eval <<-EOD
221
+ def #{meth}(*args, &block)
222
+ Debugger.start do |dbg|
223
+ dbg.post_mortem do
224
+ #{old_meth}(*args, &block)
225
+ end
226
+ end
227
+ end
228
+ EOD
229
+ end
230
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: ruby-debug-base
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.8"
7
+ date: 2007-03-14 22:41:18 -04:00
8
+ summary: Fast Ruby debugger
9
+ require_paths:
10
+ - lib
11
+ email: ksibilev@yahoo.com
12
+ homepage: http://rubyforge.org/projects/ruby-debug/
13
+ rubyforge_project: ruby-debug
14
+ description: ruby-debug is a fast implementation of the standard Ruby debugger debug.rb. It's implemented by utilizing a new hook Ruby C API.
15
+ autorequire: ruby-debug-base
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.8.2
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Kent Sibilev
31
+ files:
32
+ - README
33
+ - LICENSE
34
+ - CHANGES
35
+ - AUTHORS
36
+ - lib/ruby-debug-base.rb
37
+ - ext/extconf.rb
38
+ - ext/ruby_debug.c
39
+ - ext/tags
40
+ - ext/win32
41
+ test_files: []
42
+
43
+ rdoc_options: []
44
+
45
+ extra_rdoc_files:
46
+ - README
47
+ - ext/ruby_debug.c
48
+ executables: []
49
+
50
+ extensions:
51
+ - ext/extconf.rb
52
+ requirements: []
53
+
54
+ dependencies: []
55
+