trepanning 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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