ruby-breakpoint 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|