rb8-trepanning 0.1.3

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 (274) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGES +34 -0
  3. data/ChangeLog +875 -0
  4. data/README.textile +59 -0
  5. data/Rakefile +215 -0
  6. data/app/.gitignore +1 -0
  7. data/app/cmd_parse.kpeg +241 -0
  8. data/app/cmd_parse.rb +212 -0
  9. data/app/cmd_parser.rb +1948 -0
  10. data/app/complete.rb +79 -0
  11. data/app/default.rb +90 -0
  12. data/app/display.rb +148 -0
  13. data/app/eventbuffer.rb +147 -0
  14. data/app/frame.rb +166 -0
  15. data/app/irb.rb +114 -0
  16. data/app/options.rb +200 -0
  17. data/app/run.rb +74 -0
  18. data/app/util.rb +65 -0
  19. data/bin/.gitignore +1 -0
  20. data/bin/trepan8 +115 -0
  21. data/data/.gitignore +1 -0
  22. data/data/irbrc +41 -0
  23. data/interface/.gitignore +1 -0
  24. data/interface/base_intf.rb +109 -0
  25. data/interface/client.rb +82 -0
  26. data/interface/comcodes.rb +20 -0
  27. data/interface/script.rb +110 -0
  28. data/interface/server.rb +147 -0
  29. data/interface/user.rb +165 -0
  30. data/io/base_io.rb +148 -0
  31. data/io/input.rb +158 -0
  32. data/io/null_output.rb +46 -0
  33. data/io/string_array.rb +156 -0
  34. data/io/tcpclient.rb +129 -0
  35. data/io/tcpfns.rb +33 -0
  36. data/io/tcpserver.rb +141 -0
  37. data/lib/debugger.rb +8 -0
  38. data/lib/trepanning.rb +283 -0
  39. data/processor/.gitignore +1 -0
  40. data/processor/command-ruby-debug/breakpoints.rb +155 -0
  41. data/processor/command-ruby-debug/catchpoint.rb +55 -0
  42. data/processor/command-ruby-debug/condition.rb +49 -0
  43. data/processor/command-ruby-debug/control.rb +31 -0
  44. data/processor/command-ruby-debug/display.rb +120 -0
  45. data/processor/command-ruby-debug/enable.rb +202 -0
  46. data/processor/command-ruby-debug/frame.rb +199 -0
  47. data/processor/command-ruby-debug/help.rb +63 -0
  48. data/processor/command-ruby-debug/info.rb +359 -0
  49. data/processor/command-ruby-debug/method.rb +84 -0
  50. data/processor/command-ruby-debug/reload.rb +40 -0
  51. data/processor/command-ruby-debug/save.rb +90 -0
  52. data/processor/command-ruby-debug/set.rb +237 -0
  53. data/processor/command-ruby-debug/show.rb +251 -0
  54. data/processor/command-ruby-debug/source.rb +36 -0
  55. data/processor/command-ruby-debug/threads.rb +189 -0
  56. data/processor/command-ruby-debug/trace.rb +57 -0
  57. data/processor/command-ruby-debug/variables.rb +199 -0
  58. data/processor/command.rb +270 -0
  59. data/processor/command/.gitignore +1 -0
  60. data/processor/command/alias.rb +54 -0
  61. data/processor/command/backtrace.rb +123 -0
  62. data/processor/command/base/cmd.rb +177 -0
  63. data/processor/command/base/subcmd.rb +230 -0
  64. data/processor/command/base/submgr.rb +188 -0
  65. data/processor/command/base/subsubcmd.rb +128 -0
  66. data/processor/command/base/subsubmgr.rb +199 -0
  67. data/processor/command/break.rb +114 -0
  68. data/processor/command/catch.rb +71 -0
  69. data/processor/command/complete.rb +39 -0
  70. data/processor/command/continue.rb +57 -0
  71. data/processor/command/directory.rb +50 -0
  72. data/processor/command/disable.rb +85 -0
  73. data/processor/command/display.rb +78 -0
  74. data/processor/command/down.rb +54 -0
  75. data/processor/command/edit.rb +79 -0
  76. data/processor/command/enable.rb +48 -0
  77. data/processor/command/eval.rb +90 -0
  78. data/processor/command/exit.rb +66 -0
  79. data/processor/command/finish.rb +59 -0
  80. data/processor/command/frame.rb +97 -0
  81. data/processor/command/help.rb +230 -0
  82. data/processor/command/help/.gitignore +1 -0
  83. data/processor/command/help/README +10 -0
  84. data/processor/command/help/command.txt +58 -0
  85. data/processor/command/help/examples.txt +16 -0
  86. data/processor/command/help/filename.txt +40 -0
  87. data/processor/command/help/location.txt +37 -0
  88. data/processor/command/help/suffixes.txt +17 -0
  89. data/processor/command/info.rb +28 -0
  90. data/processor/command/info_subcmd/.gitignore +1 -0
  91. data/processor/command/info_subcmd/args.rb +39 -0
  92. data/processor/command/info_subcmd/breakpoints.rb +80 -0
  93. data/processor/command/info_subcmd/catch.rb +36 -0
  94. data/processor/command/info_subcmd/files.rb +39 -0
  95. data/processor/command/info_subcmd/globals.rb +64 -0
  96. data/processor/command/info_subcmd/line.rb +30 -0
  97. data/processor/command/info_subcmd/locals.rb +69 -0
  98. data/processor/command/info_subcmd/macro.rb +62 -0
  99. data/processor/command/info_subcmd/program.rb +51 -0
  100. data/processor/command/info_subcmd/ruby.rb +57 -0
  101. data/processor/command/info_subcmd/source.rb +74 -0
  102. data/processor/command/info_subcmd/stack.rb +25 -0
  103. data/processor/command/info_subcmd/threads.rb +75 -0
  104. data/processor/command/kill.rb +78 -0
  105. data/processor/command/list.rb +117 -0
  106. data/processor/command/macro.rb +68 -0
  107. data/processor/command/next.rb +79 -0
  108. data/processor/command/parsetree.rb +56 -0
  109. data/processor/command/pp.rb +40 -0
  110. data/processor/command/pr.rb +37 -0
  111. data/processor/command/ps.rb +40 -0
  112. data/processor/command/restart.rb +86 -0
  113. data/processor/command/save.rb +58 -0
  114. data/processor/command/set.rb +47 -0
  115. data/processor/command/set_subcmd/.gitignore +1 -0
  116. data/processor/command/set_subcmd/abbrev.rb +25 -0
  117. data/processor/command/set_subcmd/auto.rb +27 -0
  118. data/processor/command/set_subcmd/auto_subcmd/.gitignore +1 -0
  119. data/processor/command/set_subcmd/auto_subcmd/eval.rb +53 -0
  120. data/processor/command/set_subcmd/auto_subcmd/irb.rb +33 -0
  121. data/processor/command/set_subcmd/auto_subcmd/list.rb +33 -0
  122. data/processor/command/set_subcmd/basename.rb +25 -0
  123. data/processor/command/set_subcmd/callstyle.rb +46 -0
  124. data/processor/command/set_subcmd/confirm.rb +24 -0
  125. data/processor/command/set_subcmd/debug.rb +47 -0
  126. data/processor/command/set_subcmd/different.rb +61 -0
  127. data/processor/command/set_subcmd/highlight.rb +43 -0
  128. data/processor/command/set_subcmd/max.rb +26 -0
  129. data/processor/command/set_subcmd/max_subcmd/list.rb +49 -0
  130. data/processor/command/set_subcmd/max_subcmd/stack.rb +50 -0
  131. data/processor/command/set_subcmd/max_subcmd/string.rb +76 -0
  132. data/processor/command/set_subcmd/max_subcmd/width.rb +49 -0
  133. data/processor/command/set_subcmd/reload.rb +42 -0
  134. data/processor/command/set_subcmd/timer.rb +58 -0
  135. data/processor/command/set_subcmd/trace.rb +37 -0
  136. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +42 -0
  137. data/processor/command/set_subcmd/trace_subcmd/print.rb +41 -0
  138. data/processor/command/shell.rb +139 -0
  139. data/processor/command/show.rb +39 -0
  140. data/processor/command/show_subcmd/.gitignore +1 -0
  141. data/processor/command/show_subcmd/abbrev.rb +20 -0
  142. data/processor/command/show_subcmd/alias.rb +46 -0
  143. data/processor/command/show_subcmd/args.rb +34 -0
  144. data/processor/command/show_subcmd/auto.rb +28 -0
  145. data/processor/command/show_subcmd/auto_subcmd/eval.rb +27 -0
  146. data/processor/command/show_subcmd/auto_subcmd/irb.rb +23 -0
  147. data/processor/command/show_subcmd/auto_subcmd/list.rb +22 -0
  148. data/processor/command/show_subcmd/basename.rb +20 -0
  149. data/processor/command/show_subcmd/callstyle.rb +22 -0
  150. data/processor/command/show_subcmd/confirm.rb +18 -0
  151. data/processor/command/show_subcmd/debug.rb +26 -0
  152. data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +21 -0
  153. data/processor/command/show_subcmd/debug_subcmd/skip.rb +22 -0
  154. data/processor/command/show_subcmd/debug_subcmd/step.rb +22 -0
  155. data/processor/command/show_subcmd/different.rb +26 -0
  156. data/processor/command/show_subcmd/directories.rb +22 -0
  157. data/processor/command/show_subcmd/highlight.rb +24 -0
  158. data/processor/command/show_subcmd/max.rb +27 -0
  159. data/processor/command/show_subcmd/max_subcmd/list.rb +38 -0
  160. data/processor/command/show_subcmd/max_subcmd/stack.rb +36 -0
  161. data/processor/command/show_subcmd/max_subcmd/string.rb +42 -0
  162. data/processor/command/show_subcmd/max_subcmd/width.rb +37 -0
  163. data/processor/command/show_subcmd/reload.rb +18 -0
  164. data/processor/command/show_subcmd/timer.rb +18 -0
  165. data/processor/command/show_subcmd/trace.rb +29 -0
  166. data/processor/command/show_subcmd/trace_subcmd/buffer.rb +65 -0
  167. data/processor/command/show_subcmd/trace_subcmd/print.rb +23 -0
  168. data/processor/command/show_subcmd/version.rb +23 -0
  169. data/processor/command/source.rb +134 -0
  170. data/processor/command/step.rb +81 -0
  171. data/processor/command/tbreak.rb +19 -0
  172. data/processor/command/unalias.rb +44 -0
  173. data/processor/command/undisplay.rb +59 -0
  174. data/processor/command/up.rb +72 -0
  175. data/processor/default.rb +56 -0
  176. data/processor/display.rb +17 -0
  177. data/processor/eval.rb +113 -0
  178. data/processor/eventbuf.rb +105 -0
  179. data/processor/frame.rb +172 -0
  180. data/processor/help.rb +92 -0
  181. data/processor/helper.rb +76 -0
  182. data/processor/hook.rb +134 -0
  183. data/processor/load_cmds.rb +258 -0
  184. data/processor/location.rb +174 -0
  185. data/processor/main.rb +455 -0
  186. data/processor/mock.rb +136 -0
  187. data/processor/msg.rb +61 -0
  188. data/processor/processor.rb +674 -0
  189. data/processor/running.rb +168 -0
  190. data/processor/stepping.rb +18 -0
  191. data/processor/subcmd.rb +161 -0
  192. data/processor/validate.rb +355 -0
  193. data/processor/virtual.rb +34 -0
  194. data/test/data/.gitignore +1 -0
  195. data/test/data/break_bad.cmd +19 -0
  196. data/test/data/break_bad.right +29 -0
  197. data/test/data/break_loop_bug.cmd +5 -0
  198. data/test/data/break_loop_bug.right +15 -0
  199. data/test/data/dollar-0.right +2 -0
  200. data/test/data/dollar-0a.right +2 -0
  201. data/test/data/dollar-0b.right +2 -0
  202. data/test/data/edit.cmd +14 -0
  203. data/test/data/edit.right +24 -0
  204. data/test/data/file-with-space.cmd +6 -0
  205. data/test/data/file-with-space.right +4 -0
  206. data/test/data/printvar.cmd +17 -0
  207. data/test/data/printvar.right +31 -0
  208. data/test/data/raise.cmd +11 -0
  209. data/test/data/raise.right +19 -0
  210. data/test/data/source.cmd +5 -0
  211. data/test/data/source.right +18 -0
  212. data/test/data/stepping-1.9.right +50 -0
  213. data/test/data/stepping.cmd +21 -0
  214. data/test/data/stepping.right +48 -0
  215. data/test/data/trepan8-save.1 +6 -0
  216. data/test/example/bp_loop_issue.rb +3 -0
  217. data/test/example/break-bug.rb +7 -0
  218. data/test/example/brkpt-class-bug.rb +8 -0
  219. data/test/example/classes.rb +11 -0
  220. data/test/example/dollar-0.rb +5 -0
  221. data/test/example/except-bug1.rb +4 -0
  222. data/test/example/except-bug2.rb +7 -0
  223. data/test/example/file with space.rb +1 -0
  224. data/test/example/gcd.rb +18 -0
  225. data/test/example/info-var-bug.rb +47 -0
  226. data/test/example/info-var-bug2.rb +2 -0
  227. data/test/example/null.rb +1 -0
  228. data/test/example/pm-bug.rb +3 -0
  229. data/test/example/pm.rb +11 -0
  230. data/test/example/raise.rb +3 -0
  231. data/test/integration/.gitignore +4 -0
  232. data/test/integration/config.yaml +8 -0
  233. data/test/integration/helper.rb +154 -0
  234. data/test/integration/test-break_bad.rb +26 -0
  235. data/test/integration/test-dollar-0.rb +31 -0
  236. data/test/integration/test-edit.rb +17 -0
  237. data/test/integration/test-file-with-space.rb +26 -0
  238. data/test/integration/test-printvar.rb +17 -0
  239. data/test/integration/test-raise.rb +21 -0
  240. data/test/integration/test-source.rb +16 -0
  241. data/test/integration/test-stepping.rb +24 -0
  242. data/test/unit/.gitignore +1 -0
  243. data/test/unit/cmd-helper.rb +52 -0
  244. data/test/unit/mock-helper.rb +12 -0
  245. data/test/unit/test-app-cmd_parse.rb +97 -0
  246. data/test/unit/test-app-cmd_parser.rb +23 -0
  247. data/test/unit/test-app-complete.rb +39 -0
  248. data/test/unit/test-app-frame.rb +32 -0
  249. data/test/unit/test-app-options.rb +92 -0
  250. data/test/unit/test-app-run.rb +14 -0
  251. data/test/unit/test-app-util.rb +44 -0
  252. data/test/unit/test-base-cmd.rb +45 -0
  253. data/test/unit/test-base-subcmd.rb +57 -0
  254. data/test/unit/test-base-submgr.rb +23 -0
  255. data/test/unit/test-base-subsubcmd.rb +17 -0
  256. data/test/unit/test-cmd-alias.rb +48 -0
  257. data/test/unit/test-cmd-exit.rb +27 -0
  258. data/test/unit/test-cmd-help.rb +104 -0
  259. data/test/unit/test-cmd-kill.rb +46 -0
  260. data/test/unit/test-cmd-source.rb +34 -0
  261. data/test/unit/test-completion.rb +42 -0
  262. data/test/unit/test-intf-user.rb +46 -0
  263. data/test/unit/test-io-input.rb +27 -0
  264. data/test/unit/test-io-tcp.rb +33 -0
  265. data/test/unit/test-io-tcpclient.rb +54 -0
  266. data/test/unit/test-io-tcpfns.rb +17 -0
  267. data/test/unit/test-io-tcpserver.rb +50 -0
  268. data/test/unit/test-proc-eval.rb +36 -0
  269. data/test/unit/test-proc-hook.rb +30 -0
  270. data/test/unit/test-proc-load_cmds.rb +50 -0
  271. data/test/unit/test-proc-location.rb +79 -0
  272. data/test/unit/test-subcmd-help.rb +44 -0
  273. data/trepan8.gemspec +52 -0
  274. metadata +391 -0
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../base/subcmd'
5
+
6
+ class Trepan::Subcommand::InfoRuby < Trepan::Subcommand
7
+ unless defined?(HELP)
8
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
9
+ HELP = <<-EOH
10
+ #{CMD} [-v|--verbose|-no-verbose]
11
+
12
+ Show Ruby version information such as you'd get from
13
+ "ruby -v" (which is really just the value of RUBY_RELEASE_DATE).
14
+
15
+ See also constants: RUBY_DESCRIPITON, RUBY_VERSION, and RUBY_RELEASE_DATE."
16
+ EOH
17
+ MIN_ABBREV = 'ru'.size
18
+ NEED_STACK = false
19
+ MIN_ARGS = 0
20
+ MAX_ARGS = 0
21
+ SHORT_HELP = 'Ruby version information'
22
+ end
23
+
24
+ def parse_options(args) # :nodoc
25
+ options = {}
26
+ parser = OptionParser.new do |opts|
27
+ opts.on("-v",
28
+ "--[no-]verbose", "show additional version information") do
29
+ |v|
30
+ options[:verbose] = v
31
+ end
32
+ end
33
+ parser.parse(args)
34
+ return options
35
+ end
36
+
37
+ def run(args)
38
+ options = parse_options(args[2..-1])
39
+ msg RUBY_DESCRIPTION
40
+ if options[:verbose]
41
+ # To be completed
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ if __FILE__ == $0
48
+ # Demo it.
49
+ $0 = __FILE__ + 'notagain' # So we don't run this again
50
+ require_relative '../../mock'
51
+ cmd = MockDebugger::sub_setup(Trepan::Subcommand::InfoRuby, false)
52
+ cmd.run(cmd.prefix)
53
+ %w(-v --verbose --no-verbose).each do |opt|
54
+ puts '-' * 10 + " #{opt}"
55
+ cmd.run(cmd.prefix + [opt])
56
+ end
57
+ end
@@ -0,0 +1,74 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require 'pp'
5
+ begin
6
+ require 'linecache'
7
+ rescue LoadError
8
+ require 'linecache19'
9
+ end
10
+ require 'columnize'
11
+ require_relative '../base/subcmd'
12
+ require_relative '../../../app/complete'
13
+
14
+ class Trepan::Subcommand::InfoSource < Trepan::Subcommand
15
+ unless defined?(HELP)
16
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
17
+ DEFAULT_FILE_ARGS = %w(size mtime sha1)
18
+
19
+ HELP = <<-EOH
20
+ #{CMD}
21
+
22
+ Show information about the current source file.
23
+ EOH
24
+ MAX_ARGS = 0
25
+ MIN_ABBREV = 'so'.size # Note we have "info frame"
26
+ NEED_STACK = true
27
+ end
28
+
29
+ # completion %w(all brkpts iseq sha1 size stat)
30
+
31
+ include Trepanning
32
+
33
+ # Get file information
34
+ def run(args)
35
+ if not @proc.frame
36
+ errmsg('No frame - no default file.')
37
+ return false
38
+ end
39
+ frame_file = @proc.frame.file
40
+ filename = LineCache::unmap_file(frame_file) || File.expand_path(frame_file)
41
+ canonic_name = @proc.canonic_file(filename)
42
+ canonic_name = LineCache::unmap_file(canonic_name) || canonic_name
43
+ m = filename
44
+ if LineCache::cached?(canonic_name)
45
+ m += ' is cached in debugger'
46
+ if canonic_name != filename
47
+ m += (' as:\n ' + canonic_name)
48
+ end
49
+ m += '.'
50
+ msg(m)
51
+ end
52
+ max_line = LineCache::size(canonic_name)
53
+ msg 'File has %d lines.' % max_line if max_line
54
+ msg('SHA1 is %s.' % LineCache::sha1(canonic_name))
55
+ msg('Possible breakpoint line numbers:')
56
+ lines = LineCache.trace_line_numbers(canonic_name)
57
+ fmt_lines = columnize_numbers(lines)
58
+ msg(fmt_lines)
59
+ msg("Stat info:\n\t%s" % LineCache::stat(canonic_name).pretty_inspect)
60
+ end
61
+ end
62
+
63
+ if __FILE__ == $0
64
+ if !(ARGV.size == 1 && ARGV[0] == 'noload')
65
+ ISEQS__ = {}
66
+ SCRIPT_ISEQS__ = {}
67
+ ARGV[0..-1] = ['noload']
68
+ load(__FILE__)
69
+ else
70
+ require_relative '../../mock'
71
+ cmd = MockDebugger::sub_setup(Trepan::Subcommand::InfoSource, false)
72
+ cmd.run(cmd.prefix)
73
+ end
74
+ end
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../base/subcmd'
5
+
6
+
7
+ class Trepan::Subcommand::InfoStack < Trepan::Subcommand
8
+ unless defined?(HELP)
9
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
10
+ HELP = 'Same thing as "backtrace"'
11
+ MIN_ABBREV = 'st'.size
12
+ NEED_STACK = true
13
+ end
14
+
15
+ def run(args)
16
+ @proc.commands['backtrace'].run(['backtrace'] + args[2..-1])
17
+ end
18
+ end
19
+
20
+ if __FILE__ == $0
21
+ # Demo it.
22
+ require_relative '../../mock'
23
+ cmd = MockDebugger::sub_setup(Trepan::Subcommand::InfoStack, false)
24
+ cmd.run(cmd.prefix)
25
+ end
@@ -0,0 +1,75 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../base/subcmd'
5
+
6
+ class Trepan::Subcommand::InfoThreads < Trepan::Subcommand
7
+ unless defined?(HELP)
8
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
9
+ HELP = 'Show IDs of currently-known threads'
10
+ MIN_ABBREV = 'th'.size
11
+ MIN_ARGS = 0
12
+ MAX_ARGS = 0
13
+ NEED_STACK = true
14
+ end
15
+
16
+ def display_context(c, show_top_frame=true)
17
+ c_flag = c.thread == Thread.current ? '+' : ' '
18
+ c_flag = '$' if c.suspended?
19
+ d_flag = c.ignored? ? '!' : ' '
20
+ str = "%s%s" % [c_flag, d_flag]
21
+ str += "%d " % c.thnum
22
+ str += "%s\t" % c.thread.inspect
23
+ if c.stack_size > 0 and show_top_frame
24
+ str += "%s:%d" % [@proc.canonic_file(c.frame_file(0)), c.frame_line(0)]
25
+ end
26
+ msg str
27
+ end
28
+
29
+ def get_context(thnum)
30
+ Debugger.contexts.find{|c| c.thnum == thnum}
31
+ end
32
+
33
+ def parse_thread_num(subcmd, arg)
34
+ if '' == arg
35
+ errmsg "'%s' needs a thread number\n" % subcmd
36
+ nil
37
+ else
38
+ thread_num = @proc.get_int(arg,
39
+ :cmdname => "thread #{subcmd}",
40
+ :default => 1)
41
+ return nil unless thread_num
42
+ get_context(thread_num)
43
+ end
44
+ end
45
+
46
+ def parse_thread_num_for_cmd(subcmd, arg)
47
+ c = parse_thread_num(subcmd, arg)
48
+ return nil unless c
49
+ case
50
+ when nil == c
51
+ errmsg "No such thread."
52
+ when @proc.context == c
53
+ errmsg "It's the current thread."
54
+ when c.ignored?
55
+ errmsg "Can't #{subcmd} to the debugger thread #{arg}."
56
+ else # Everything is okay
57
+ return c
58
+ end
59
+ return nil
60
+ end
61
+
62
+ def run(args)
63
+ threads = Debugger.contexts.sort_by{|c| c.thnum}.each do |c|
64
+ display_context(c)
65
+ end
66
+ end
67
+ end
68
+
69
+ if __FILE__ == $0
70
+ # Demo it.
71
+ $0 = __FILE__ + 'notagain' # So we don't run this again
72
+ require_relative '../../mock'
73
+ cmd = MockDebugger::sub_setup(Trepan::Subcommand::InfoThreads, false)
74
+ cmd.run(cmd.prefix)
75
+ end
@@ -0,0 +1,78 @@
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'rubygems'; require 'require_relative'
3
+ require_relative 'base/cmd'
4
+ class Trepan::Command::KillCommand < Trepan::Command
5
+
6
+ unless defined?(HELP)
7
+ NAME = File.basename(__FILE__, '.rb')
8
+ HELP = <<-HELP
9
+ #{NAME} [signal-number|signal-name]
10
+
11
+ Kill execution of program being debugged.
12
+
13
+ Equivalent of Process.kill('KILL', Process.pid). This is an unmaskable
14
+ signal. When all else fails, e.g. in thread code, use this.
15
+
16
+ If you are in interactive mode, you are prompted to confirm killing.
17
+ However when this command is aliased from a command ending in !, no
18
+ questions are asked.
19
+
20
+ Examples:
21
+
22
+ #{NAME}
23
+ #{NAME} unconditionally
24
+ #{NAME} KILL # same as above
25
+ #{NAME} kill # same as above
26
+ #{NAME} -9 # same as above
27
+ #{NAME} 9 # same as above
28
+ #{NAME}! 9 # same as above, but no questions asked.
29
+ HELP
30
+
31
+ ALIASES = %w(kill!)
32
+ CATEGORY = 'running'
33
+ MAX_ARGS = 1 # Need at most this many
34
+ SHORT_HELP = 'Send this process a POSIX signal (default "9" is "kill -9")'
35
+ end
36
+
37
+ def complete(prefix)
38
+ completions = Signal.list.keys +
39
+ Signal.list.values.map{|i| i.to_s} +
40
+ Signal.list.values.map{|i| (-i).to_s}
41
+ Trepan::Complete.complete_token(completions, prefix)
42
+ end
43
+
44
+ # This method runs the command
45
+ def run(args) # :nodoc
46
+ unconditional = ('!' == args[0][-1..-1])
47
+ if args.size > 1
48
+ sig = Integer(args[1]) rescue args[1]
49
+ unless sig.is_a?(Integer) || Signal.list.member?(sig.upcase)
50
+ errmsg("Signal name '#{sig}' is not a signal I know about.\n")
51
+ return false
52
+ end
53
+ else
54
+ if not (unconditional || confirm('Really quit?', false))
55
+ msg('Kill not confirmed.')
56
+ return
57
+ else
58
+ sig = 'KILL'
59
+ end
60
+ end
61
+ begin
62
+ ## @proc.intf.finalize if 'KILL' == sig || Signal['KILL'] == sig
63
+ Process.kill(sig, Process.pid)
64
+ rescue Errno::ESRCH
65
+ errmsg "Unable to send kill #{sig} to process #{Process.pid}"
66
+ end
67
+ end
68
+ end
69
+
70
+ if __FILE__ == $0
71
+ require_relative '../mock'
72
+ dbgr, cmd = MockDebugger::setup
73
+ %w(fooo 1 -1 HUP -9).each do |arg|
74
+ puts "#{cmd.name} #{arg}"
75
+ cmd.run([cmd.name, arg])
76
+ puts '=' * 40
77
+ end
78
+ end
@@ -0,0 +1,117 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative './base/cmd'
5
+
6
+ class Trepan::Command::ListCommand < Trepan::Command
7
+ unless defined?(HELP)
8
+ NAME = File.basename(__FILE__, '.rb')
9
+ HELP = <<-HELP
10
+ #{NAME}
11
+ #{NAME} -
12
+ #{NAME} =
13
+ #{NAME} mm-nn
14
+
15
+ #{NAME} source code.
16
+
17
+ In the first form without arguments, prints lines starting at
18
+ the line. If this is the first #{NAME} command issued since the debugger
19
+ command loop was entered, then the current line is the current
20
+ frame. If a subsequent #{NAME} command was issued with no intervening
21
+ frame changing, then that is start the line after we last one
22
+ previously shown.
23
+
24
+ In the second form, list lines before the preciding list or
25
+ the current line.
26
+
27
+ In the third form, list lines centered around the current line.
28
+
29
+ Use 'set max list' or 'show max list' to see or set the value.
30
+ HELP
31
+
32
+ ALIASES = %W(l)
33
+ CATEGORY = 'files'
34
+ MAX_ARGS = 2
35
+ SHORT_HELP = 'List source code'
36
+ end
37
+
38
+ # Show FILE from line B to E where CURRENT is the current line number.
39
+ # If we can show from B to E then we return B, otherwise we return the
40
+ # previous line @state.previous_line.
41
+ def display_list(b, e, file, current)
42
+ opts = {
43
+ :reload_on_change => settings[:reload],
44
+ :output => settings[:highlight]
45
+ }
46
+ lines = LineCache::getlines(file, opts)
47
+ if lines
48
+ b = lines.size - (e - b) if b >= lines.size
49
+ e = lines.size if lines.size < e
50
+ msg "[%d, %d] in %s" % [b, e, file]
51
+ [b, 1].max.upto(e) do |n|
52
+ if n > 0 && lines[n-1]
53
+ if n == current
54
+ msg "=> %3d %s" % [n, lines[n-1].chomp], :unlimited => true
55
+ else
56
+ msg " %3d %s" % [n, lines[n-1].chomp], :unlimited => true
57
+ end
58
+ end
59
+ end
60
+ else
61
+ errmsg "No sourcefile available for %s\n" % file
62
+ return @proc.state.previous_line
63
+ end
64
+ return b
65
+ end
66
+
67
+ def run(args)
68
+ listsize = settings[:maxlist]
69
+ if args.size == 1
70
+ b = @proc.state.previous_line ?
71
+ @proc.state.previous_line + listsize : @proc.frame.line - (listsize/2)
72
+ e = b + listsize - 1
73
+ elsif args[1] == '-'
74
+ b = if @proc.state.previous_line
75
+ if @proc.state.previous_line > 0
76
+ @proc.state.previous_line - listsize
77
+ else
78
+ @proc.state.previous_line
79
+ end
80
+ else
81
+ @proc.state.line - (listsize/2)
82
+ end
83
+ e = b + listsize - 1
84
+ elsif args[1] == '='
85
+ @proc.state.previous_line = nil
86
+ b = @proc.state.line - (listsize/2)
87
+ e = b + listsize -1
88
+ else
89
+ b, e = args[1].split(/[-,]/)
90
+ if e
91
+ b = b.to_i
92
+ e = e.to_i
93
+ else
94
+ b = b.to_i - (listsize/2)
95
+ e = b + listsize - 1
96
+ end
97
+ end
98
+ @proc.state.previous_line =
99
+ display_list(b, e, @proc.frame.file, @proc.frame.line)
100
+ end
101
+
102
+ end
103
+
104
+ if __FILE__ == $0
105
+ require_relative '../mock'
106
+ dbgr, cmd = MockDebugger::setup
107
+
108
+ def run_cmd(cmd, args)
109
+ cmd.proc.instance_variable_set('@cmd_argstr', args[1..-1].join(' '))
110
+ cmd.run(args)
111
+ puts '-' * 20
112
+ end
113
+
114
+ LineCache::cache(__FILE__)
115
+ run_cmd(cmd, [cmd.name])
116
+ run_cmd(cmd, [cmd.name, __FILE__ + ':10'])
117
+ end
@@ -0,0 +1,68 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'base/cmd'
5
+ require_relative '../eval'
6
+ class Trepan::Command::MacroCommand < Trepan::Command
7
+
8
+ unless defined?(HELP)
9
+ NAME = File.basename(__FILE__, '.rb')
10
+ HELP = <<-HELP
11
+ #{NAME} MACRO-NAME PROC-OBJECT
12
+
13
+ Define MACRO-NAME as a debugger macro. Debugger macros get a list of
14
+ arguments.
15
+
16
+ The macro should return either a String or an Array of Strings which
17
+ is substituted for the command. If the return is a String, that gets
18
+ tokenized by a simple String#split . Note that macro processing is
19
+ done right after splitting on ;; so if the macro returns a string
20
+ containing ;; this will not be handled on the string returned.
21
+
22
+ If instead, Array of Strings is returned, then the first string is
23
+ unshifted from the array and executed. The remaning strings are pushed
24
+ onto the command queue. In contrast to the first string, subsequent
25
+ strings can contain other macros, and ;; in those strings will be
26
+ split into separate commands.
27
+
28
+ Here is an example. The below creates a macro called finish+ which
29
+ issues two commands 'finish' followed by 'step':
30
+
31
+ macro fin+ Proc.new{|*args| %w(finish step)}
32
+
33
+ See also 'show macro'.
34
+ HELP
35
+
36
+ CATEGORY = 'support'
37
+ MIN_ARGS = 2 # Need at least this many
38
+ SHORT_HELP = 'Define a macro'
39
+ end
40
+
41
+ def run(args)
42
+ cmd_name = args[1]
43
+ cmd_argstr = @proc.cmd_argstr[cmd_name.size..-1].lstrip
44
+ proc_obj = @proc.debug_eval(cmd_argstr, @proc.settings[:maxstring])
45
+ if proc_obj
46
+ if proc_obj.is_a?(Proc)
47
+ @proc.macros[cmd_name] = [proc_obj, cmd_argstr]
48
+ msg "Macro \"#{cmd_name}\" defined."
49
+ else
50
+ errmsg "Expecting a Proc object; got: #{cmd_argstr}"
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ if __FILE__ == $0
57
+ require_relative '../mock'
58
+ dbgr, cmd = MockDebugger::setup
59
+ cmdproc = cmd.proc
60
+ ["#{cmd.name} foo Proc.new{|x, y| 'x+y'}",
61
+ "#{cmd.name} bad2 1+2"].each do |cmdline|
62
+ args = cmdline.split
63
+ cmd_argstr = cmdline[args[0].size..-1].lstrip
64
+ cmdproc.instance_variable_set('@cmd_argstr', cmd_argstr)
65
+ cmd.run(args)
66
+ end
67
+ p cmdproc.macros
68
+ end