trepanning 0.0.4

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.
Files changed (219) hide show
  1. data/ChangeLog +4422 -0
  2. data/LICENSE +23 -0
  3. data/NEWS +12 -0
  4. data/README.textile +56 -0
  5. data/Rakefile +171 -0
  6. data/app/Makefile +7 -0
  7. data/app/breakpoint.rb +157 -0
  8. data/app/brkptmgr.rb +149 -0
  9. data/app/condition.rb +22 -0
  10. data/app/core.rb +203 -0
  11. data/app/default.rb +54 -0
  12. data/app/disassemble.rb +61 -0
  13. data/app/display.rb +148 -0
  14. data/app/file.rb +135 -0
  15. data/app/frame.rb +275 -0
  16. data/app/irb.rb +112 -0
  17. data/app/mock.rb +22 -0
  18. data/app/options.rb +122 -0
  19. data/app/run.rb +95 -0
  20. data/app/thread.rb +24 -0
  21. data/app/util.rb +32 -0
  22. data/bin/trepan +63 -0
  23. data/data/custom_require.rb +44 -0
  24. data/data/irbrc +55 -0
  25. data/data/prelude.rb +38 -0
  26. data/interface/base_intf.rb +95 -0
  27. data/interface/script.rb +103 -0
  28. data/interface/user.rb +90 -0
  29. data/io/base_io.rb +92 -0
  30. data/io/input.rb +111 -0
  31. data/io/string_array.rb +155 -0
  32. data/lib/Makefile +7 -0
  33. data/lib/trepanning.rb +277 -0
  34. data/processor/breakpoint.rb +108 -0
  35. data/processor/command/alias.rb +55 -0
  36. data/processor/command/backtrace.rb +95 -0
  37. data/processor/command/base/cmd.rb +97 -0
  38. data/processor/command/base/subcmd.rb +207 -0
  39. data/processor/command/base/submgr.rb +178 -0
  40. data/processor/command/base/subsubcmd.rb +102 -0
  41. data/processor/command/base/subsubmgr.rb +182 -0
  42. data/processor/command/break.rb +85 -0
  43. data/processor/command/condition.rb +64 -0
  44. data/processor/command/continue.rb +61 -0
  45. data/processor/command/debug.rb +85 -0
  46. data/processor/command/delete.rb +54 -0
  47. data/processor/command/directory.rb +43 -0
  48. data/processor/command/disable.rb +65 -0
  49. data/processor/command/disassemble.rb +103 -0
  50. data/processor/command/display.rb +81 -0
  51. data/processor/command/down.rb +56 -0
  52. data/processor/command/enable.rb +43 -0
  53. data/processor/command/exit.rb +54 -0
  54. data/processor/command/finish.rb +81 -0
  55. data/processor/command/frame.rb +117 -0
  56. data/processor/command/help.rb +146 -0
  57. data/processor/command/info.rb +28 -0
  58. data/processor/command/info_subcmd/args.rb +56 -0
  59. data/processor/command/info_subcmd/breakpoints.rb +162 -0
  60. data/processor/command/info_subcmd/file.rb +162 -0
  61. data/processor/command/info_subcmd/frame.rb +39 -0
  62. data/processor/command/info_subcmd/iseq.rb +83 -0
  63. data/processor/command/info_subcmd/locals.rb +88 -0
  64. data/processor/command/info_subcmd/program.rb +54 -0
  65. data/processor/command/info_subcmd/registers.rb +72 -0
  66. data/processor/command/info_subcmd/registers_subcmd/dfp.rb +38 -0
  67. data/processor/command/info_subcmd/registers_subcmd/helper.rb +40 -0
  68. data/processor/command/info_subcmd/registers_subcmd/lfp.rb +54 -0
  69. data/processor/command/info_subcmd/registers_subcmd/pc.rb +44 -0
  70. data/processor/command/info_subcmd/registers_subcmd/sp.rb +75 -0
  71. data/processor/command/info_subcmd/return.rb +40 -0
  72. data/processor/command/info_subcmd/thread.rb +106 -0
  73. data/processor/command/irb.rb +106 -0
  74. data/processor/command/kill.rb +58 -0
  75. data/processor/command/list.rb +327 -0
  76. data/processor/command/macro.rb +65 -0
  77. data/processor/command/next.rb +89 -0
  78. data/processor/command/nocache.rb +33 -0
  79. data/processor/command/print.rb +37 -0
  80. data/processor/command/ps.rb +40 -0
  81. data/processor/command/quit.rb +62 -0
  82. data/processor/command/raise.rb +47 -0
  83. data/processor/command/reload.rb +28 -0
  84. data/processor/command/reload_subcmd/command.rb +34 -0
  85. data/processor/command/restart.rb +57 -0
  86. data/processor/command/save.rb +60 -0
  87. data/processor/command/set.rb +47 -0
  88. data/processor/command/set_subcmd/auto.rb +27 -0
  89. data/processor/command/set_subcmd/auto_subcmd/eval.rb +67 -0
  90. data/processor/command/set_subcmd/auto_subcmd/irb.rb +49 -0
  91. data/processor/command/set_subcmd/auto_subcmd/list.rb +51 -0
  92. data/processor/command/set_subcmd/basename.rb +39 -0
  93. data/processor/command/set_subcmd/debug.rb +27 -0
  94. data/processor/command/set_subcmd/debug_subcmd/dbgr.rb +49 -0
  95. data/processor/command/set_subcmd/debug_subcmd/except.rb +35 -0
  96. data/processor/command/set_subcmd/debug_subcmd/macro.rb +35 -0
  97. data/processor/command/set_subcmd/debug_subcmd/skip.rb +35 -0
  98. data/processor/command/set_subcmd/debug_subcmd/stack.rb +45 -0
  99. data/processor/command/set_subcmd/different.rb +67 -0
  100. data/processor/command/set_subcmd/events.rb +71 -0
  101. data/processor/command/set_subcmd/max.rb +35 -0
  102. data/processor/command/set_subcmd/max_subcmd/list.rb +50 -0
  103. data/processor/command/set_subcmd/max_subcmd/stack.rb +60 -0
  104. data/processor/command/set_subcmd/max_subcmd/string.rb +53 -0
  105. data/processor/command/set_subcmd/max_subcmd/width.rb +50 -0
  106. data/processor/command/set_subcmd/return.rb +66 -0
  107. data/processor/command/set_subcmd/sp.rb +62 -0
  108. data/processor/command/set_subcmd/substitute.rb +25 -0
  109. data/processor/command/set_subcmd/substitute_subcmd/eval.rb +98 -0
  110. data/processor/command/set_subcmd/substitute_subcmd/path.rb +55 -0
  111. data/processor/command/set_subcmd/substitute_subcmd/string.rb +72 -0
  112. data/processor/command/set_subcmd/timer.rb +68 -0
  113. data/processor/command/set_subcmd/trace.rb +43 -0
  114. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +56 -0
  115. data/processor/command/set_subcmd/trace_subcmd/print.rb +54 -0
  116. data/processor/command/set_subcmd/trace_subcmd/var.rb +61 -0
  117. data/processor/command/show.rb +27 -0
  118. data/processor/command/show_subcmd/alias.rb +50 -0
  119. data/processor/command/show_subcmd/args.rb +50 -0
  120. data/processor/command/show_subcmd/auto.rb +27 -0
  121. data/processor/command/show_subcmd/auto_subcmd/eval.rb +38 -0
  122. data/processor/command/show_subcmd/auto_subcmd/irb.rb +34 -0
  123. data/processor/command/show_subcmd/auto_subcmd/list.rb +36 -0
  124. data/processor/command/show_subcmd/basename.rb +28 -0
  125. data/processor/command/show_subcmd/debug.rb +27 -0
  126. data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +31 -0
  127. data/processor/command/show_subcmd/debug_subcmd/except.rb +33 -0
  128. data/processor/command/show_subcmd/debug_subcmd/macro.rb +32 -0
  129. data/processor/command/show_subcmd/debug_subcmd/skip.rb +33 -0
  130. data/processor/command/show_subcmd/debug_subcmd/stack.rb +32 -0
  131. data/processor/command/show_subcmd/different.rb +37 -0
  132. data/processor/command/show_subcmd/events.rb +40 -0
  133. data/processor/command/show_subcmd/macro.rb +45 -0
  134. data/processor/command/show_subcmd/max.rb +31 -0
  135. data/processor/command/show_subcmd/max_subcmd/list.rb +39 -0
  136. data/processor/command/show_subcmd/max_subcmd/stack.rb +35 -0
  137. data/processor/command/show_subcmd/max_subcmd/string.rb +41 -0
  138. data/processor/command/show_subcmd/max_subcmd/width.rb +36 -0
  139. data/processor/command/show_subcmd/trace.rb +29 -0
  140. data/processor/command/show_subcmd/trace_subcmd/buffer.rb +84 -0
  141. data/processor/command/show_subcmd/trace_subcmd/print.rb +38 -0
  142. data/processor/command/source.rb +74 -0
  143. data/processor/command/step.rb +139 -0
  144. data/processor/command/stepi.rb +63 -0
  145. data/processor/command/unalias.rb +44 -0
  146. data/processor/command/undisplay.rb +63 -0
  147. data/processor/command/up.rb +92 -0
  148. data/processor/default.rb +45 -0
  149. data/processor/display.rb +17 -0
  150. data/processor/eval.rb +88 -0
  151. data/processor/eventbuf.rb +131 -0
  152. data/processor/frame.rb +230 -0
  153. data/processor/help.rb +72 -0
  154. data/processor/hook.rb +128 -0
  155. data/processor/load_cmds.rb +102 -0
  156. data/processor/location.rb +126 -0
  157. data/processor/main.rb +364 -0
  158. data/processor/mock.rb +100 -0
  159. data/processor/msg.rb +26 -0
  160. data/processor/running.rb +170 -0
  161. data/processor/subcmd.rb +159 -0
  162. data/processor/validate.rb +395 -0
  163. data/test/example/fname with blank.rb +1 -0
  164. data/test/example/gcd-xx.rb +18 -0
  165. data/test/example/gcd.rb +19 -0
  166. data/test/example/gcd1.rb +24 -0
  167. data/test/example/null.rb +1 -0
  168. data/test/example/thread1.rb +3 -0
  169. data/test/functional/fn_helper.rb +119 -0
  170. data/test/functional/test-break.rb +87 -0
  171. data/test/functional/test-condition.rb +59 -0
  172. data/test/functional/test-debugger-call-bug.rb +31 -0
  173. data/test/functional/test-delete.rb +71 -0
  174. data/test/functional/test-finish.rb +44 -0
  175. data/test/functional/test-immediate-step-bug.rb +35 -0
  176. data/test/functional/test-next.rb +77 -0
  177. data/test/functional/test-raise.rb +73 -0
  178. data/test/functional/test-return.rb +100 -0
  179. data/test/functional/test-step.rb +274 -0
  180. data/test/functional/test-stepbug.rb +40 -0
  181. data/test/functional/test-trace-var.rb +40 -0
  182. data/test/functional/tmp/b1.rb +5 -0
  183. data/test/functional/tmp/s1.rb +9 -0
  184. data/test/functional/tmp/t2.rb +6 -0
  185. data/test/integration/file-diff.rb +88 -0
  186. data/test/integration/helper.rb +52 -0
  187. data/test/integration/test-fname-with-blank.rb +11 -0
  188. data/test/integration/test-quit.rb +11 -0
  189. data/test/integration/try-test-enable.rb +11 -0
  190. data/test/unit/cmd-helper.rb +44 -0
  191. data/test/unit/test-app-brkpt.rb +30 -0
  192. data/test/unit/test-app-brkptmgr.rb +56 -0
  193. data/test/unit/test-app-disassemble.rb +60 -0
  194. data/test/unit/test-app-file.rb +46 -0
  195. data/test/unit/test-app-frame.rb +49 -0
  196. data/test/unit/test-app-options.rb +60 -0
  197. data/test/unit/test-app-run.rb +19 -0
  198. data/test/unit/test-app-thread.rb +25 -0
  199. data/test/unit/test-app-util.rb +17 -0
  200. data/test/unit/test-base-subcmd.rb +59 -0
  201. data/test/unit/test-bin-trepan.rb +48 -0
  202. data/test/unit/test-cmd-alias.rb +50 -0
  203. data/test/unit/test-cmd-break.rb +80 -0
  204. data/test/unit/test-cmd-endisable.rb +59 -0
  205. data/test/unit/test-cmd-help.rb +100 -0
  206. data/test/unit/test-cmd-kill.rb +47 -0
  207. data/test/unit/test-cmd-quit.rb +26 -0
  208. data/test/unit/test-cmd-step.rb +45 -0
  209. data/test/unit/test-intf-user.rb +45 -0
  210. data/test/unit/test-io-input.rb +26 -0
  211. data/test/unit/test-proc-eval.rb +26 -0
  212. data/test/unit/test-proc-frame.rb +77 -0
  213. data/test/unit/test-proc-help.rb +15 -0
  214. data/test/unit/test-proc-hook.rb +29 -0
  215. data/test/unit/test-proc-load_cmds.rb +40 -0
  216. data/test/unit/test-proc-main.rb +99 -0
  217. data/test/unit/test-proc-validate.rb +90 -0
  218. data/test/unit/test-subcmd-help.rb +48 -0
  219. metadata +358 -0
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,12 @@
1
+ Oct 8, 2010
2
+ First release under the name trepanning
3
+
4
+ * Add gdb-like "directory" command
5
+ * Add "set max list" to set number of lines to list by default.
6
+ * "break line" searches parent instruction sequences in the same file. This
7
+ should allow more line numbers to be breakpointable.
8
+ * Some small bug fixes
9
+
10
+ Sept 13, 2010
11
+
12
+ First public (gemcutter) release.
data/README.textile ADDED
@@ -0,0 +1,56 @@
1
+ A modular, testable debugger for Ruby 1.9.2. A total rewrite of _ruby-debug_.
2
+
3
+ __In order to use this debugger, you'll need a patched Ruby 1.9.2 and some additional packages. See the "installation instructions.":http://wiki.github.com/rocky/rb-trepanning/how-to-install-rbdbgr__
4
+
5
+ Right now this debugger is beta code.
6
+
7
+ There is a "google group mailing list":http://groups.google.com/group/ruby-debugger for Ruby debuggers.
8
+
9
+ If rb-trepanning is installed, here is how to run:
10
+
11
+ bc. trepan ruby-program [program]
12
+
13
+ If your program needs options of its own:
14
+
15
+ bc. trepan -- ruby-program [program args...]
16
+
17
+ If you want to run from the source tree you can do that too:
18
+
19
+ bc. cd place-where-trepan-is-installed:
20
+ ./bin/trepan -- ruby-program [program args...]
21
+
22
+ Running from inside _irb_:
23
+
24
+ bc. require 'trepanning'
25
+ Trepan.debug { your code }
26
+
27
+ The return value from Trepan is the return value of the block, i.e. the final value in the block.
28
+
29
+ You can run the same thing inside your Ruby program, but probably you don't want to give a block. Instead, you may want to have debugging start on the next statement in the code:
30
+
31
+ bc. require 'trepan'
32
+ Trepan.debug # Don't stop here...
33
+ work # but stop here.
34
+
35
+ or if you haven't mucked around with $0 and ARGV, you might try:
36
+
37
+ bc. Trepan.debug(:set_restart=>true)
38
+
39
+ which informs the debugger on how to restart the program (via the restart command) using the values of ARGV and $0 at the time Trepan.debug was called.
40
+
41
+ The above is really shorthand for something like:
42
+
43
+ bc. $trepan = Trepan.new(:set_restart=>true)
44
+ $trepan.debugger
45
+
46
+ The global variable $trepan set holds debugger settings, such as "autolist" or "autoeval" settings and breakpoint information.
47
+
48
+ Due to the line-event orientation in ruby-debug, it occasionally it was convenient to add a synchronous stop in your program. I don't think that will as necessary here, but if you do call to the debugger at the point of the call rather than the subsequent stopping point, set opts[:immediate] to true. Example:
49
+
50
+ bc. # ... work, work, work
51
+ mydbg.debugger(:immediate=>true) # enter debugger here
52
+ # ... work, work, work
53
+
54
+ There is extensive on-line help. Run "help" inside the debugger.
55
+
56
+
data/Rakefile ADDED
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env rake
2
+ # -*- Ruby -*-
3
+ require 'rubygems'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/rdoctask'
6
+ require 'rake/testtask'
7
+
8
+ ROOT_DIR = File.dirname(__FILE__)
9
+ require File.join %W(#{ROOT_DIR} app options)
10
+
11
+ def gemspec
12
+ @gemspec ||= eval(File.read('.gemspec'), binding, '.gemspec')
13
+ end
14
+
15
+ desc "Build the gem"
16
+ task :package=>:gem
17
+ task :gem=>:gemspec do
18
+ Dir.chdir(ROOT_DIR) do
19
+ sh "gem build .gemspec"
20
+ FileUtils.mkdir_p 'pkg'
21
+ FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
22
+ end
23
+ end
24
+
25
+ desc "Install the gem locally"
26
+ task :install => :gem do
27
+ Dir.chdir(ROOT_DIR) do
28
+ sh %{gem install --local pkg/#{gemspec.name}-#{gemspec.version}}
29
+ end
30
+ end
31
+
32
+ desc "Test everything."
33
+ Rake::TestTask.new(:test) do |t|
34
+ t.libs << './lib'
35
+ t.pattern = 'test/test-*.rb'
36
+ t.verbose = true
37
+ end
38
+ task :test => :lib
39
+
40
+ desc "same as test"
41
+ task :check => :test
42
+
43
+ require 'rbconfig'
44
+ RUBY_PATH = File.join(RbConfig::CONFIG['bindir'],
45
+ RbConfig::CONFIG['RUBY_INSTALL_NAME'])
46
+
47
+ def run_standalone_ruby_file(directory)
48
+ puts ('*' * 10) + ' ' + directory + ' ' + ('*' * 10)
49
+ Dir.chdir(directory) do
50
+ Dir.glob('*.rb').each do |ruby_file|
51
+ puts ('-' * 20) + ' ' + ruby_file + ' ' + ('-' * 20)
52
+ system(RUBY_PATH, ruby_file)
53
+ end
54
+ end
55
+ end
56
+
57
+ desc 'Create a GNU-style ChangeLog via git2cl'
58
+ task :ChangeLog do
59
+ system('git log --pretty --numstat --summary | git2cl > ChangeLog')
60
+ end
61
+
62
+ desc 'Test units - the smaller tests'
63
+ task :'test:unit' do |t|
64
+ Rake::TestTask.new(:'test:unit') do |t|
65
+ t.test_files = FileList['test/unit/**/test-*.rb']
66
+ # t.pattern = 'test/**/*test-*.rb' # instead of above
67
+ t.verbose = true
68
+ end
69
+ end
70
+
71
+ desc 'Test functional - the medium-sized tests'
72
+ task :'test:functional' do |t|
73
+ Rake::TestTask.new(:'test:functional') do |t|
74
+ t.test_files = FileList['test/functional/**/test-*.rb']
75
+ t.verbose = true
76
+ end
77
+ end
78
+
79
+ desc 'Test integration - end-to-end blackbox tests'
80
+ task :'test:integration' do |t|
81
+ Rake::TestTask.new(:'test:integration') do |t|
82
+ t.test_files = FileList['test/integration/**/test-*.rb']
83
+ t.verbose = true
84
+ end
85
+ end
86
+
87
+ desc 'Test everything - unit tests for now.'
88
+ task :test do
89
+ exceptions = %w(test:unit test:functional test:integration).collect do |task|
90
+ begin
91
+ Rake::Task[task].invoke
92
+ nil
93
+ rescue => e
94
+ e
95
+ end
96
+ end.compact
97
+
98
+ exceptions.each {|e| puts e;puts e.backtrace }
99
+ raise "Test failures" unless exceptions.empty?
100
+ end
101
+
102
+ desc "Run each library Ruby file in standalone mode."
103
+ task :'check:app' do
104
+ run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} app)))
105
+ end
106
+
107
+ desc "Run each command in standalone mode."
108
+ task :'check:commands' do
109
+ run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} processor command)))
110
+ end
111
+
112
+ desc "Run each processor Ruby file in standalone mode."
113
+ task :'check:lib' do
114
+ run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} lib)))
115
+ end
116
+
117
+ desc "Run each processor Ruby file in standalone mode."
118
+ task :'check:processor' do
119
+ run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} processor)))
120
+ end
121
+
122
+ desc "Run each processor Ruby file in standalone mode."
123
+ task :'check:unit' do
124
+ run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} test unit)))
125
+ end
126
+
127
+ task :'check:functional' do
128
+ run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} test functional)))
129
+ end
130
+
131
+ task :'check:integration' do
132
+ run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} test integration)))
133
+ end
134
+
135
+ task :check => %w(check:lib check:processor check:commands).map{|c| c.to_sym}
136
+
137
+ desc "Test everything - same as test."
138
+ task :default => :test
139
+
140
+ desc "Generate the gemspec"
141
+ task :generate do
142
+ puts gemspec.to_ruby
143
+ end
144
+
145
+ desc "Validate the gemspec"
146
+ task :gemspec do
147
+ gemspec.validate
148
+ end
149
+
150
+ # --------- RDoc Documentation ------
151
+ desc "Generate rdoc documentation"
152
+ Rake::RDocTask.new("rdoc") do |rdoc|
153
+ rdoc.rdoc_dir = 'doc'
154
+ rdoc.title = "Trepanning #{Trepanning::VERSION} Documentation"
155
+
156
+ rdoc.rdoc_files.include('lib/*.rb', 'app/*.rb', 'bin/trepan')
157
+ end
158
+ desc "Same as rdoc"
159
+ task :doc => :rdoc
160
+
161
+ desc "Remove built files"
162
+ task :clean => [:clobber_package, :clobber_rdoc]
163
+
164
+ task :clobber_package do
165
+ FileUtils.rm_rf File.join(ROOT_DIR, 'pkg')
166
+ end
167
+
168
+ task :clobber_rdoc do
169
+ FileUtils.rm_rf File.join(ROOT_DIR, 'doc')
170
+ end
171
+
data/app/Makefile ADDED
@@ -0,0 +1,7 @@
1
+ # Whatever it is you want to do, it should be forwarded to the
2
+ # to top-level irectories
3
+ .PHONY: check all
4
+ all: check
5
+
6
+ %:
7
+ $(MAKE) -C .. $@
data/app/breakpoint.rb ADDED
@@ -0,0 +1,157 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'thread_frame'
4
+
5
+ # Breakpoint objects
6
+ module Trepanning
7
+ class Breakpoint
8
+ attr_accessor :condition # If non-nil, this is a String to be eval'd
9
+ # which must be true to enter the debugger
10
+ attr_accessor :hits # Fixnum. The number of timea a breakpoint
11
+ # has been hit (with a true condition). Do
12
+ # we want to (also) record hits independent
13
+ # of the condition?
14
+ attr_reader :id # Fixnum. Name of breakpoint
15
+ attr_reader :ignore # Fixnum. Number of times encountered to ignore
16
+ attr_reader :iseq # Instruction sequence associated with this
17
+ # breakpoint. From this we can derive
18
+ # information such as source location.
19
+ attr_reader :offset # Fixnum. Offset into an instruction
20
+ # sequence for the location of the
21
+ # breakpoint
22
+ attr_reader :type # String. 'line' if breakpoint requested
23
+ # at "line" boundary or 'offset'
24
+ # requested at a specific offset
25
+ @@next_id = 1
26
+
27
+ BRKPT_DEFAULT_SETTINGS = {
28
+ :condition => 'true',
29
+ :enabled => 'true',
30
+ :ignore => 0,
31
+ :temp => false,
32
+ :type => 'line',
33
+ } unless defined?(BRKPT_DEFAULT_SETTINGS)
34
+
35
+ def initialize(iseq, offset, opts = {})
36
+ raise TypeError,
37
+ "#{iseq} is not an instruction sequence" unless
38
+ iseq.is_a?(RubyVM::InstructionSequence)
39
+ @iseq = iseq
40
+
41
+ raise TypeError,
42
+ "offset #{offset.inspect} not found in instruction sequence" unless
43
+ iseq.offset2lines(offset)
44
+ @offset = iseq
45
+
46
+ raise TypeError,
47
+ "type mismatch: #{offset.class} given, Fixnum expected" unless
48
+ offset.is_a?(Fixnum)
49
+ @offset = offset
50
+
51
+ opts = BRKPT_DEFAULT_SETTINGS.merge(opts)
52
+ opts.keys.each do |key|
53
+ self.instance_variable_set('@'+key.to_s, opts[key])
54
+ end
55
+
56
+ @hits = 0
57
+
58
+ unless @id
59
+ @id = @@next_id
60
+ @@next_id += 1
61
+ end
62
+ set
63
+ end
64
+
65
+ def condition?(bind)
66
+ if eval(@condition, bind)
67
+ if @ignore > 0
68
+ @ignore -= 1
69
+ return false
70
+ else
71
+ @hits += 1
72
+ return true
73
+ end
74
+ else
75
+ return false
76
+ end
77
+ end
78
+
79
+ def disable
80
+ @enabled = false
81
+ end
82
+
83
+ def enabled
84
+ @enabled = true
85
+ end
86
+
87
+ def enabled=(bool)
88
+ @enabled = bool
89
+ end
90
+
91
+ def enabled?
92
+ @enabled
93
+ end
94
+
95
+ # Return a one-character "icon" giving the state of the breakpoint
96
+ # 't': temporary breakpoint
97
+ # 'B': enabled breakpoint
98
+ # 'b': disabled breakpoint
99
+ def icon_char
100
+ temp? ? 't' : (enabled? ? 'B' : 'b')
101
+ end
102
+
103
+ def set
104
+ @iseq.brkpt_set(@offset)
105
+ end
106
+
107
+ def source_container
108
+ @iseq.source_container
109
+ end
110
+
111
+ def source_location
112
+ @iseq.offset2lines(@offset)
113
+ end
114
+
115
+ def temp?
116
+ @temp
117
+ end
118
+
119
+ def remove!
120
+ @iseq.brkpt_unset(@offset)
121
+ end
122
+
123
+ # Really shouldn't need this after next_id is removed.
124
+ def self.reset
125
+ @@next_id = 1
126
+ end
127
+
128
+ end
129
+ end
130
+
131
+ if __FILE__ == $0
132
+ tf = RubyVM::ThreadFrame.current
133
+ iseq = tf.iseq
134
+ b1 = Trepanning::Breakpoint.new(iseq, 0)
135
+ p b1
136
+ p b1.source_location
137
+ p b1.source_container
138
+ b2 = Trepanning::Breakpoint.new(iseq, 0, :temp => true)
139
+ p b2
140
+ puts "b2 id: #{b2.id}"
141
+ puts "b2 hits: #{b2.hits}"
142
+ puts "b2.condition? #{b2.condition?(tf.binding)}"
143
+ puts "b2 hits: #{b2.hits}"
144
+ begin
145
+ b3 = Breakpoint.new(iseq, iseq.iseq_size)
146
+ rescue TypeError => e
147
+ puts "TypeError (expected): #{e}"
148
+ end
149
+ begin
150
+ b3 = Trepanning::Breakpoint.new(5, iseq.iseq_size)
151
+ rescue TypeError => e
152
+ puts "TypeError (expected): #{e}"
153
+ end
154
+ puts Trepanning::Breakpoint.class_variable_get('@@next_id')
155
+ Trepanning::Breakpoint.reset
156
+ puts Trepanning::Breakpoint.class_variable_get('@@next_id')
157
+ end
data/app/brkptmgr.rb ADDED
@@ -0,0 +1,149 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'set'
3
+ require_relative 'breakpoint'
4
+ class BreakpointMgr
5
+
6
+ attr_reader :list
7
+ attr_reader :set
8
+
9
+ def initialize
10
+ @list = []
11
+ @next_id = 1
12
+ @set = Set.new
13
+ end
14
+
15
+ def <<(brkpt)
16
+ @list << brkpt
17
+ @set.add(set_key(brkpt))
18
+ end
19
+
20
+ def [](index)
21
+ raise TypeError,
22
+ "index #{index} should be a Fixnum, is #{index.class}" unless
23
+ index.is_a?(Fixnum)
24
+ @list.detect {|bp| bp.id == index }
25
+ end
26
+
27
+ alias detect []
28
+
29
+ def delete(index)
30
+ bp = detect(index)
31
+ if bp
32
+ delete_by_brkpt(bp)
33
+ return bp
34
+ else
35
+ return nil
36
+ end
37
+ end
38
+
39
+ def delete_by_brkpt(delete_bp)
40
+ @list = @list.reject{|candidate| candidate == delete_bp}
41
+ @set = Set.new(@list.map{|bp| set_key(bp)})
42
+ delete_bp.remove! unless @set.member?(set_key(delete_bp))
43
+ return delete_bp
44
+ end
45
+
46
+ def add(*args)
47
+ if args[2]
48
+ unless args[2].member?(:id)
49
+ args[2][:id] = @next_id
50
+ @next_id += 1
51
+ end
52
+ else
53
+ args[2] = {:id => @next_id}
54
+ @next_id += 1
55
+ end
56
+
57
+ brkpt = Trepanning::Breakpoint.new(*args)
58
+ @list << brkpt
59
+ @set.add(set_key(brkpt))
60
+ return brkpt
61
+ end
62
+
63
+ def empty?
64
+ @list.empty?
65
+ end
66
+
67
+ def line_breaks(container)
68
+ result = {}
69
+ @list.each do |bp|
70
+ if bp.source_container == container
71
+ bp.source_location.each do |line|
72
+ result[line] = bp
73
+ end
74
+ end
75
+ end
76
+ result
77
+ end
78
+
79
+ def find(iseq, offset, bind)
80
+ @list.detect do |bp|
81
+ if bp.enabled? && bp.iseq.equal?(iseq) && bp.offset == offset
82
+ begin
83
+ return bp if bp.condition?(bind)
84
+ rescue
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ def max
91
+ @list.map{|bp| bp.id}.max
92
+ end
93
+
94
+ # Key used in @set to list unique instruction-sequence offsets.
95
+ def set_key(bp)
96
+ [bp.iseq, bp.offset]
97
+ end
98
+
99
+ def size
100
+ @list.size
101
+ end
102
+
103
+ def reset
104
+ @list.each{|bp| bp.remove!}
105
+ @list = []
106
+ @set = Set.new
107
+ end
108
+
109
+ end
110
+ if __FILE__ == $0
111
+ def bp_status(brkpts, i)
112
+ puts "list size: #{brkpts.list.size}"
113
+ puts "set size: #{brkpts.set.size}"
114
+ puts "max: #{brkpts.max}"
115
+ p brkpts
116
+ puts "--- #{i} ---"
117
+ end
118
+
119
+ frame = RubyVM::ThreadFrame.current
120
+ iseq = frame.iseq
121
+ brkpts = BreakpointMgr.new
122
+ brkpts.add(iseq, 0)
123
+ p brkpts[2]
124
+ bp_status(brkpts, 1)
125
+ offset = frame.pc_offset
126
+ b2 = Trepanning::Breakpoint.new(iseq, offset)
127
+ brkpts << b2
128
+ p brkpts.find(b2.iseq, b2.offset, nil)
129
+ p brkpts[2]
130
+ puts '--- 2 ---'
131
+ p brkpts.line_breaks(iseq.source_container)
132
+ p brkpts.delete(2)
133
+ p brkpts[2]
134
+ bp_status(brkpts, 3)
135
+
136
+ # Two of the same breakpoints but delete 1 and see that the
137
+ # other still stays
138
+ offset = frame.pc_offset
139
+ b2 = Trepanning::Breakpoint.new(iseq, offset)
140
+ brkpts << b2
141
+ bp_status(brkpts, 4)
142
+ b3 = Trepanning::Breakpoint.new(iseq, offset)
143
+ brkpts << b3
144
+ bp_status(brkpts, 5)
145
+ brkpts.delete_by_brkpt(b2)
146
+ bp_status(brkpts, 6)
147
+ brkpts.delete_by_brkpt(b3)
148
+ bp_status(brkpts, 7)
149
+ end
data/app/condition.rb ADDED
@@ -0,0 +1,22 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ class Trepan
3
+ module Condition
4
+ def valid_condition?(str)
5
+ begin
6
+ RubyVM::InstructionSequence.compile(str)
7
+ rescue SyntaxError
8
+ return nil
9
+ rescue
10
+ nil
11
+ end
12
+ end
13
+ module_function :valid_condition?
14
+ end
15
+ end
16
+ if __FILE__ == $0
17
+ include Trepan::Condition
18
+ p valid_condition?('a+2')
19
+ puts '-' * 20
20
+ p valid_condition?('1+')
21
+ puts '-' * 20
22
+ end