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.
@@ -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
- error.call if error
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(eval("binding", context), nil, extra_data)
70
+ cc.call(context, nil, extra_data)
57
71
  end
58
72
  elsif type == "line" then
59
73
  nil
@@ -22,13 +22,13 @@ require 'drb/acl'
22
22
  require 'thread'
23
23
 
24
24
  module Breakpoint
25
- id = %q$Id: breakpoint.rb 52 2005-02-26 19:43:19Z flgr $
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.0"
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
- # +throw(:debug_return, value)+.
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}(*args, &block) }
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
- IRB.instance_eval { @CONF[:RC] = true }
294
- IRB.run_config
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.5
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.0
7
- date: 2005-03-04
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
- - lib
10
+ - lib
11
11
  email: flgr@ccan.de
12
12
  homepage: http://ruby-breakpoint.rubyforge.org/
13
13
  rubyforge_project: ruby-breakpoint
14
- description: "ruby-breakpoint lets you inspect and modify state at run time. This allows you
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
- - !ruby/object:Gem::Version
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
- - Florian Gross
29
+ - Florian Gross
31
30
  files:
32
- - bin
33
- - COPYING
34
- - doc
35
- - GPL
36
- - lib
37
- - Manifest
38
- - NEWS
39
- - README
40
- - setup.rb
41
- - TODO
42
- - bin/breakpoint_client
43
- - doc/classes
44
- - doc/created.rid
45
- - doc/files
46
- - doc/fr_class_index.html
47
- - doc/fr_file_index.html
48
- - doc/fr_method_index.html
49
- - doc/index.html
50
- - doc/rdoc-style.css
51
- - doc/classes/Binding.html
52
- - doc/classes/Breakpoint
53
- - doc/classes/Breakpoint.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_rb.html
65
- - lib/binding_of_caller.rb
66
- - lib/breakpoint.rb
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
- - "--inline-source"
70
- - "--line-numbers"
71
- - "--title"
72
- - ruby-breakpoint
72
+ - --inline-source
73
+ - --line-numbers
74
+ - --title
75
+ - ruby-breakpoint
73
76
  extra_rdoc_files:
74
- - README
75
- - NEWS
76
- - TODO
77
- - COPYING
77
+ - README
78
+ - NEWS
79
+ - TODO
80
+ - COPYING
78
81
  executables:
79
- - breakpoint_client
82
+ - breakpoint_client
80
83
  extensions: []
84
+
81
85
  requirements: []
82
- dependencies: []
86
+
87
+ dependencies: []
88
+