ruby-breakpoint 0.5.0 → 0.5.1
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/Manifest +38 -35
- data/NEWS +14 -0
- data/README +4 -4
- data/TODO +4 -0
- data/bin/breakpoint_client +1 -212
- data/doc/classes/Binding.html +237 -220
- data/doc/classes/Breakpoint.html +552 -539
- data/doc/classes/Breakpoint/CommandBundle.html +206 -206
- data/doc/classes/Breakpoint/CommandBundle/Client.html +232 -200
- data/doc/classes/Breakpoint/FailedAssertError.html +117 -117
- data/doc/classes/Handlers.html +230 -0
- data/doc/created.rid +1 -1
- data/doc/files/COPYING.html +162 -162
- data/doc/files/NEWS.html +168 -134
- data/doc/files/README.html +154 -153
- data/doc/files/TODO.html +166 -161
- data/doc/files/lib/binding_of_caller_rb.html +100 -100
- data/doc/files/lib/breakpoint_client_rb.html +131 -0
- data/doc/files/lib/breakpoint_rb.html +201 -201
- data/doc/fr_class_index.html +31 -30
- data/doc/fr_file_index.html +32 -31
- data/doc/fr_method_index.html +41 -37
- data/doc/index.html +23 -23
- data/doc/rdoc-style.css +207 -207
- data/lib/binding_of_caller.rb +16 -2
- data/lib/breakpoint.rb +34 -7
- data/lib/breakpoint_client.rb +214 -0
- metadata +63 -57
data/lib/binding_of_caller.rb
CHANGED
@@ -32,12 +32,26 @@ class Binding; end # for RDoc
|
|
32
32
|
# If you don't do this an Exception will be raised. Because of
|
33
33
|
# the way that Binding.of_caller is implemented it has to be
|
34
34
|
# done this way.
|
35
|
+
#
|
36
|
+
# Please note that currently bindings returned by
|
37
|
+
# Binding.of_caller() will have a wrong self context which
|
38
|
+
# means you can not call methods, access instance variables and
|
39
|
+
# so on on the calling object. You can work around this by
|
40
|
+
# defining the method which uses the binding on all objects and
|
41
|
+
# telling your users to use them without a receiver. This is
|
42
|
+
# how ruby-breakpoint works around the problem.
|
43
|
+
#
|
44
|
+
# This is believed to be a bug in Ruby and has been reported to
|
45
|
+
# ruby-core. See http://www.ruby-forum.com/topic/67255
|
35
46
|
def Binding.of_caller(&block)
|
36
47
|
old_critical = Thread.critical
|
37
48
|
Thread.critical = true
|
38
49
|
count = 0
|
39
50
|
cc, result, error, extra_data = Continuation.create(nil, nil)
|
40
|
-
|
51
|
+
if error then
|
52
|
+
Thread.critical = old_critical
|
53
|
+
error.call
|
54
|
+
end
|
41
55
|
|
42
56
|
tracer = lambda do |*args|
|
43
57
|
type, context, extra_data = args[0], args[4], args
|
@@ -53,7 +67,7 @@ def Binding.of_caller(&block)
|
|
53
67
|
# this is impossible without overloading set_trace_func
|
54
68
|
# in current Ruby.
|
55
69
|
set_trace_func(nil)
|
56
|
-
cc.call(
|
70
|
+
cc.call(context, nil, extra_data)
|
57
71
|
end
|
58
72
|
elsif type == "line" then
|
59
73
|
nil
|
data/lib/breakpoint.rb
CHANGED
@@ -22,13 +22,13 @@ require 'drb/acl'
|
|
22
22
|
require 'thread'
|
23
23
|
|
24
24
|
module Breakpoint
|
25
|
-
id = %q$Id: breakpoint.rb
|
25
|
+
id = %q$Id: breakpoint.rb 118 2006-05-28 11:44:14Z flgr $
|
26
26
|
current_version = id.split(" ")[2]
|
27
27
|
unless defined?(Version)
|
28
28
|
# The Version of ruby-breakpoint you are using as String of the
|
29
29
|
# 1.2.3 form where the digits stand for release, major and minor
|
30
30
|
# version respectively.
|
31
|
-
Version = "0.5.
|
31
|
+
Version = "0.5.1"
|
32
32
|
end
|
33
33
|
|
34
34
|
extend self
|
@@ -54,7 +54,7 @@ module Breakpoint
|
|
54
54
|
# breakpoints can also return a value. They will execute
|
55
55
|
# a supplied block for getting a default return value.
|
56
56
|
# A custom value can be returned from the session by doing
|
57
|
-
#
|
57
|
+
# <code>throw(:debug_return, value)</code>.
|
58
58
|
#
|
59
59
|
# You can also give names to break points which will be
|
60
60
|
# used in the message that is displayed upon execution
|
@@ -107,6 +107,16 @@ module Breakpoint
|
|
107
107
|
# breakpoint_client.rb which is distributed with this
|
108
108
|
# library. See the documentation of Breakpoint.activate_drb
|
109
109
|
# for details.
|
110
|
+
#
|
111
|
+
# Please use breakpoint() instead of Breakpoint.breakpoint().
|
112
|
+
# If you use Breakpoint.breakpoint() you might get a shell with
|
113
|
+
# a wrong self context meaning that you will not be able to
|
114
|
+
# access instance variables, call methods on the object where
|
115
|
+
# you are breakpointing and so on. You will however still be
|
116
|
+
# able to access local variables.
|
117
|
+
#
|
118
|
+
# The former is believed to be caused by a bug in Ruby and it has
|
119
|
+
# been reported to ruby-core: http://www.ruby-forum.com/topic/67255
|
110
120
|
def breakpoint(id = nil, context = nil, &block)
|
111
121
|
callstack = caller
|
112
122
|
callstack.slice!(0, 3) if callstack.first["breakpoint"]
|
@@ -144,6 +154,16 @@ module Breakpoint
|
|
144
154
|
@eval_handler.call(code)
|
145
155
|
end
|
146
156
|
|
157
|
+
# Need to work around an odd RubyGems issue that causes it
|
158
|
+
# to not load libraries...
|
159
|
+
def require(*args, &block)
|
160
|
+
begin
|
161
|
+
method_missing(:require__, *args, &block)
|
162
|
+
rescue LoadError
|
163
|
+
method_missing(:require, *args, &block)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
147
167
|
# Will execute the specified statement at the client.
|
148
168
|
def method_missing(method, *args, &block)
|
149
169
|
if args.empty? and not block
|
@@ -155,7 +175,7 @@ module Breakpoint
|
|
155
175
|
# is that we would have to handle special expressions
|
156
176
|
# like "self", "nil" or constants ourself which is hard.
|
157
177
|
remote = eval %{
|
158
|
-
result = lambda { |block, *args| #{method}
|
178
|
+
result = lambda { |block, *args| self.send(#{method.inspect}, *args, &block) }
|
159
179
|
def result.call_with_block(*args, &block)
|
160
180
|
call(block, *args)
|
161
181
|
end
|
@@ -290,8 +310,12 @@ module Breakpoint
|
|
290
310
|
def initialize
|
291
311
|
@handler = @eval_handler = @collision_handler = nil
|
292
312
|
|
293
|
-
|
294
|
-
|
313
|
+
begin
|
314
|
+
IRB.instance_eval { @CONF[:RC] = true }
|
315
|
+
IRB.init_config(nil)
|
316
|
+
IRB.run_config
|
317
|
+
rescue Exception
|
318
|
+
end
|
295
319
|
end
|
296
320
|
|
297
321
|
def collision
|
@@ -504,7 +528,9 @@ module IRB # :nodoc:
|
|
504
528
|
if Breakpoint.use_drb? then
|
505
529
|
result = old_evaluate(*args)
|
506
530
|
if args[0] != :no_proxy and
|
507
|
-
not [true, false, nil].include?(result)
|
531
|
+
not [true, false, nil].include?(result) and
|
532
|
+
not result.is_a?(String) and
|
533
|
+
not result.is_a?(Numeric)
|
508
534
|
then
|
509
535
|
result.extend(DRbUndumped) rescue nil
|
510
536
|
end
|
@@ -529,6 +555,7 @@ module DRb # :nodoc:
|
|
529
555
|
class DRbObject # :nodoc:
|
530
556
|
undef :inspect if method_defined?(:inspect)
|
531
557
|
undef :clone if method_defined?(:clone)
|
558
|
+
undef :to_yaml if method_defined?(:to_yaml)
|
532
559
|
end
|
533
560
|
end
|
534
561
|
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'breakpoint'
|
2
|
+
require 'optparse'
|
3
|
+
require 'timeout'
|
4
|
+
require 'tmpdir'
|
5
|
+
|
6
|
+
# Uses the following standard options overwritten by options that might
|
7
|
+
# have been previously defined.
|
8
|
+
Options = {} unless defined?(Options)
|
9
|
+
Options.replace({
|
10
|
+
:ClientURI => nil,
|
11
|
+
:ServerURI => "druby://localhost:42531",
|
12
|
+
:RetryDelay => 3,
|
13
|
+
:Permanent => false,
|
14
|
+
:Verbose => false
|
15
|
+
}.merge(Options))
|
16
|
+
|
17
|
+
ARGV.options do |opts|
|
18
|
+
script_name = File.basename($0)
|
19
|
+
opts.banner = [
|
20
|
+
"Usage: ruby #{script_name} [Options] [server uri]",
|
21
|
+
"",
|
22
|
+
"This tool lets you connect to a breakpoint service ",
|
23
|
+
"which was started via Breakpoint.activate_drb.",
|
24
|
+
"",
|
25
|
+
"The server uri defaults to druby://localhost:42531",
|
26
|
+
"",
|
27
|
+
"Having trouble or need help?",
|
28
|
+
"* Homepage: http://ruby-breakpoint.rubyforge.org/ (has FAQ!)",
|
29
|
+
"* Author: Florian Gross, flgr@ccan.de (Read homepage first!)"
|
30
|
+
].join("\n")
|
31
|
+
|
32
|
+
opts.separator ""
|
33
|
+
|
34
|
+
opts.on("-c", "--client-uri=uri",
|
35
|
+
"Run the client on the specified uri.",
|
36
|
+
"This can be used to specify the port",
|
37
|
+
"that the client uses to allow for back",
|
38
|
+
"connections from the server.",
|
39
|
+
"Default: Find a good URI automatically.",
|
40
|
+
"Example: -c druby://localhost:12345"
|
41
|
+
) { |Options[:ClientURI]| }
|
42
|
+
|
43
|
+
opts.on("-s", "--server-uri=uri",
|
44
|
+
"Connect to the server specified at the",
|
45
|
+
"specified uri.",
|
46
|
+
"Default: druby://localhost:42531"
|
47
|
+
) { |Options[:ServerURI]| }
|
48
|
+
|
49
|
+
opts.on("-R", "--retry-delay=delay", Integer,
|
50
|
+
"Automatically try to reconnect to the",
|
51
|
+
"server after delay seconds when the",
|
52
|
+
"connection failed or timed out.",
|
53
|
+
"A value of 0 disables automatical",
|
54
|
+
"reconnecting completely.",
|
55
|
+
"Default: 10"
|
56
|
+
) { |Options[:RetryDelay]| }
|
57
|
+
|
58
|
+
opts.on("-P", "--[no-]permanent",
|
59
|
+
"Run the breakpoint client in permanent mode.",
|
60
|
+
"This means that the client will keep continue",
|
61
|
+
"running even after the server has closed the",
|
62
|
+
"connection. Useful for example in Rails.",
|
63
|
+
"Default: non-permanent"
|
64
|
+
) { |Options[:Permanent]| }
|
65
|
+
|
66
|
+
opts.on("-V", "--[no-]verbose",
|
67
|
+
"Run the breakpoint client in verbose mode.",
|
68
|
+
"Will produce more messages, for example between",
|
69
|
+
"individual breakpoints. This might help in seeing",
|
70
|
+
"that the breakpoint client is still alive, but adds",
|
71
|
+
"quite a bit of clutter.",
|
72
|
+
"Default: non-verbose"
|
73
|
+
) { |Options[:Verbose]| }
|
74
|
+
|
75
|
+
opts.separator ""
|
76
|
+
|
77
|
+
opts.on("-h", "--help",
|
78
|
+
"Show this help message."
|
79
|
+
) { puts opts; exit }
|
80
|
+
opts.on("-v", "--version",
|
81
|
+
"Display the version information."
|
82
|
+
) do
|
83
|
+
id = %q$Id: breakpoint_client 80 2005-07-28 18:15:20Z flgr $
|
84
|
+
puts id.sub("Id: ", "")
|
85
|
+
puts "(Breakpoint::Version = #{Breakpoint::Version})"
|
86
|
+
exit
|
87
|
+
end
|
88
|
+
|
89
|
+
opts.parse!
|
90
|
+
end
|
91
|
+
|
92
|
+
Options[:ServerURI] = ARGV[0] if ARGV[0]
|
93
|
+
Options[:ClientURI] ||= case Options[:ServerURI]
|
94
|
+
when /^drbunix:(.+)$/i then
|
95
|
+
"drbunix:" << File.join(Dir.tmpdir, $1.gsub(/\W/, "_")) << ".breakpoint_client"
|
96
|
+
when %r{^druby://(localhost|127\.0\.0\.1|::1):(\d+)$}i then
|
97
|
+
"druby://" << $1 << ":" << $2.succ
|
98
|
+
end
|
99
|
+
puts "ClientURI is #{Options[:ClientURI] || "unspecified"}" if Options[:Verbose]
|
100
|
+
|
101
|
+
module Handlers
|
102
|
+
extend self
|
103
|
+
|
104
|
+
def breakpoint_handler(workspace, message)
|
105
|
+
puts message
|
106
|
+
IRB.start(nil, nil, workspace)
|
107
|
+
|
108
|
+
puts ""
|
109
|
+
if Options[:Verbose] then
|
110
|
+
puts "Resumed execution. Waiting for next breakpoint...", ""
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def eval_handler(code)
|
115
|
+
result = eval(code, TOPLEVEL_BINDING)
|
116
|
+
if result then
|
117
|
+
DRbObject.new(result)
|
118
|
+
else
|
119
|
+
result
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def collision_handler()
|
124
|
+
msg = [
|
125
|
+
" *** Breakpoint service collision ***",
|
126
|
+
" Another Breakpoint service tried to use the",
|
127
|
+
" port already occupied by this one. It will",
|
128
|
+
" keep waiting until this Breakpoint service",
|
129
|
+
" is shut down.",
|
130
|
+
" ",
|
131
|
+
" If you are using the Breakpoint library for",
|
132
|
+
" debugging a Rails or other CGI application",
|
133
|
+
" this likely means that this Breakpoint",
|
134
|
+
" session belongs to an earlier, outdated",
|
135
|
+
" request and should be shut down via 'exit'."
|
136
|
+
].join("\n")
|
137
|
+
|
138
|
+
if RUBY_PLATFORM["win"] then
|
139
|
+
# This sucks. Sorry, I'm not doing this because
|
140
|
+
# I like funky message boxes -- I need to do this
|
141
|
+
# because on Windows I have no way of displaying
|
142
|
+
# my notification via puts() when gets() is still
|
143
|
+
# being performed on STDIN. I have not found a
|
144
|
+
# better solution.
|
145
|
+
begin
|
146
|
+
require 'tk'
|
147
|
+
root = TkRoot.new { withdraw }
|
148
|
+
Tk.messageBox('message' => msg, 'type' => 'ok')
|
149
|
+
root.destroy
|
150
|
+
rescue Exception
|
151
|
+
puts "", msg, ""
|
152
|
+
end
|
153
|
+
else
|
154
|
+
puts "", msg, ""
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Used for checking whether we are currently in the reconnecting loop.
|
160
|
+
reconnecting = false
|
161
|
+
|
162
|
+
loop do
|
163
|
+
DRb.start_service(Options[:ClientURI])
|
164
|
+
|
165
|
+
begin
|
166
|
+
service = DRbObject.new(nil, Options[:ServerURI])
|
167
|
+
|
168
|
+
begin
|
169
|
+
ehandler = Handlers.method(:eval_handler)
|
170
|
+
chandler = Handlers.method(:collision_handler)
|
171
|
+
handler = Handlers.method(:breakpoint_handler)
|
172
|
+
service.eval_handler = ehandler
|
173
|
+
service.collision_handler = chandler
|
174
|
+
service.handler = handler
|
175
|
+
|
176
|
+
reconnecting = false
|
177
|
+
if Options[:Verbose] then
|
178
|
+
puts "Connection established. Waiting for breakpoint...", ""
|
179
|
+
end
|
180
|
+
|
181
|
+
loop do
|
182
|
+
begin
|
183
|
+
service.ping
|
184
|
+
rescue DRb::DRbConnError => error
|
185
|
+
puts "Server exited. Closing connection...", ""
|
186
|
+
DRb.stop_service
|
187
|
+
exit! unless Options[:Permanent]
|
188
|
+
break
|
189
|
+
end
|
190
|
+
|
191
|
+
sleep(0.5)
|
192
|
+
end
|
193
|
+
ensure
|
194
|
+
service.eval_handler = nil
|
195
|
+
service.collision_handler = nil
|
196
|
+
service.handler = nil
|
197
|
+
end
|
198
|
+
rescue Exception => error
|
199
|
+
if Options[:RetryDelay] > 0 then
|
200
|
+
if not reconnecting then
|
201
|
+
reconnecting = true
|
202
|
+
puts "No connection to breakpoint service at #{Options[:ServerURI]} " +
|
203
|
+
"(#{error.class})"
|
204
|
+
puts error.backtrace if $DEBUG
|
205
|
+
puts "Tries to connect will be made every #{Options[:RetryDelay]} seconds..."
|
206
|
+
end
|
207
|
+
|
208
|
+
sleep Options[:RetryDelay]
|
209
|
+
retry
|
210
|
+
else
|
211
|
+
raise
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
metadata
CHANGED
@@ -1,82 +1,88 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.11
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-breakpoint
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.5.
|
7
|
-
date:
|
6
|
+
version: 0.5.1
|
7
|
+
date: 2006-06-05 00:00:00 +02:00
|
8
8
|
summary: ruby-breakpoint lets you inspect and modify state at run time.
|
9
9
|
require_paths:
|
10
|
-
|
10
|
+
- lib
|
11
11
|
email: flgr@ccan.de
|
12
12
|
homepage: http://ruby-breakpoint.rubyforge.org/
|
13
13
|
rubyforge_project: ruby-breakpoint
|
14
|
-
description:
|
15
|
-
to diagnose bugs, patch applications and more all via IRB by simply doing a
|
16
|
-
method call at the place you want to investigate."
|
14
|
+
description: ruby-breakpoint lets you inspect and modify state at run time. This allows you to diagnose bugs, patch applications and more all via IRB by simply doing a method call at the place you want to investigate.
|
17
15
|
autorequire: breakpoint.rb
|
18
16
|
default_executable:
|
19
17
|
bindir: bin
|
20
18
|
has_rdoc: true
|
21
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
22
20
|
requirements:
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
version: 1.8.2
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.2
|
27
24
|
version:
|
28
25
|
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
29
28
|
authors:
|
30
|
-
|
29
|
+
- Florian Gross
|
31
30
|
files:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
31
|
+
- bin
|
32
|
+
- COPYING
|
33
|
+
- doc
|
34
|
+
- GPL
|
35
|
+
- lib
|
36
|
+
- Manifest
|
37
|
+
- NEWS
|
38
|
+
- README
|
39
|
+
- setup.rb
|
40
|
+
- TODO
|
41
|
+
- bin/breakpoint_client
|
42
|
+
- doc/classes
|
43
|
+
- doc/created.rid
|
44
|
+
- doc/files
|
45
|
+
- doc/fr_class_index.html
|
46
|
+
- doc/fr_file_index.html
|
47
|
+
- doc/fr_method_index.html
|
48
|
+
- doc/index.html
|
49
|
+
- doc/rdoc-style.css
|
50
|
+
- doc/classes/Binding.html
|
51
|
+
- doc/classes/Breakpoint
|
52
|
+
- doc/classes/Breakpoint.html
|
53
|
+
- doc/classes/Handlers.html
|
54
|
+
- doc/classes/Breakpoint/CommandBundle
|
55
|
+
- doc/classes/Breakpoint/CommandBundle.html
|
56
|
+
- doc/classes/Breakpoint/FailedAssertError.html
|
57
|
+
- doc/classes/Breakpoint/CommandBundle/Client.html
|
58
|
+
- doc/files/COPYING.html
|
59
|
+
- doc/files/lib
|
60
|
+
- doc/files/NEWS.html
|
61
|
+
- doc/files/README.html
|
62
|
+
- doc/files/TODO.html
|
63
|
+
- doc/files/lib/binding_of_caller_rb.html
|
64
|
+
- doc/files/lib/breakpoint_client_rb.html
|
65
|
+
- doc/files/lib/breakpoint_rb.html
|
66
|
+
- lib/binding_of_caller.rb
|
67
|
+
- lib/breakpoint.rb
|
68
|
+
- lib/breakpoint_client.rb
|
67
69
|
test_files: []
|
70
|
+
|
68
71
|
rdoc_options:
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
72
|
+
- --inline-source
|
73
|
+
- --line-numbers
|
74
|
+
- --title
|
75
|
+
- ruby-breakpoint
|
73
76
|
extra_rdoc_files:
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
77
|
+
- README
|
78
|
+
- NEWS
|
79
|
+
- TODO
|
80
|
+
- COPYING
|
78
81
|
executables:
|
79
|
-
|
82
|
+
- breakpoint_client
|
80
83
|
extensions: []
|
84
|
+
|
81
85
|
requirements: []
|
82
|
-
|
86
|
+
|
87
|
+
dependencies: []
|
88
|
+
|