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
@@ -0,0 +1,72 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../base/subsubcmd'
4
+ require_relative '../base/subsubmgr'
5
+
6
+ class Trepan::SubSubcommand::InfoRegisters < Trepan::SubSubcommandMgr
7
+ unless defined?(HELP)
8
+ HELP =
9
+ 'List of contents for the registers of the current stack frame.
10
+ If a register name given, only only that register is show.
11
+
12
+ Examples:
13
+ info registers # show all registers
14
+ info register pc # show only the pc register
15
+ info reg sp # show all stack pointer registers
16
+ info reg sp 1 3 # show sp(1) and sp(3)
17
+ info reg sp size # show sp size
18
+ info reg lfp # show lfp(0)
19
+ '
20
+
21
+ MIN_ABBREV = 'reg'.size # Note we have "info return"
22
+ NAME = File.basename(__FILE__, '.rb')
23
+ NEED_STACK = true
24
+ PREFIX = %w(info registers)
25
+ end
26
+
27
+ def run(args)
28
+
29
+ args = @parent.last_args
30
+ unavailable_regs =
31
+ if 'CFUNC' == @proc.frame.type
32
+ %w(inforegisterslfp inforegisterspc)
33
+ else
34
+ []
35
+ end
36
+ all_regs = @subcmds.subcmds.keys.sort - unavailable_regs
37
+
38
+ if args.size == 2
39
+ # Form is: "info registers"
40
+ all_regs.sort.each do |subcmd_name|
41
+ @subcmds.subcmds[subcmd_name].run([])
42
+ end
43
+ else
44
+ subcmd_name = args[2]
45
+ key_name = PREFIX.join('') + subcmd_name
46
+ remain_args = args[3..-1]
47
+ if all_regs.member?(key_name)
48
+ @subcmds.subcmds[key_name].run(remain_args)
49
+ elsif unavailable_regs.member?(key_name)
50
+ msg("info registers: %s can not be displayed for frame type %s." %
51
+ [subcmd_name, @proc.frame.type])
52
+ else
53
+ errmsg("info registers: %s is not a valid register name" % subcmd_name)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ if __FILE__ == $0
60
+ # Demo it.
61
+ require_relative '../../mock'
62
+ dbgr = MockDebugger::MockDebugger.new
63
+ cmds = dbgr.core.processor.commands
64
+ info_cmd = cmds['info']
65
+ command = Trepan::SubSubcommand::InfoRegisters.new(dbgr.core.processor,
66
+ info_cmd)
67
+ name = File.basename(__FILE__, '.rb')
68
+ cmd_args = ['info', name]
69
+ info_cmd.instance_variable_set('@last_args', cmd_args)
70
+ command.proc.frame_setup(RubyVM::ThreadFrame::current)
71
+ command.run(cmd_args)
72
+ end
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../../base/subsubcmd'
4
+ require_relative 'helper'
5
+
6
+ class Trepan::Subcommand::InfoRegistersDfp < Trepan::SubSubcommand
7
+ unless defined?(HELP)
8
+ HELP = 'Show the value of the VM dynamic frame pointer (DFP)'
9
+ MIN_ABBREV = 'lf'.size
10
+ NAME = File.basename(__FILE__, '.rb')
11
+ NEED_STACK = true
12
+ PREFIX = %w(info registers dfp)
13
+ end
14
+
15
+ include Registers
16
+ def run(args)
17
+ register_array_index(PREFIX[-1], args)
18
+ end
19
+ end
20
+
21
+ if __FILE__ == $0
22
+ # Demo it.
23
+ require_relative '../../../mock'
24
+ require_relative '../../../subcmd'
25
+ name = File.basename(__FILE__, '.rb')
26
+
27
+ # FIXME: DRY the below code
28
+ dbgr, info_cmd = MockDebugger::setup('info')
29
+ testcmdMgr = Trepan::Subcmd.new(info_cmd)
30
+ cmd_name = Trepan::SubSubcommand::InfoRegistersDfp::PREFIX.join('')
31
+ infox_cmd = Trepan::SubSubcommand::InfoRegistersDfp.new(info_cmd.proc,
32
+ info_cmd,
33
+ cmd_name)
34
+ infox_cmd.run([])
35
+
36
+ # name = File.basename(__FILE__, '.rb')
37
+ # subcommand.summary_help(name)
38
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ module Registers
3
+ def register_array_index(name, args, max_value=nil)
4
+ if args.size == 0
5
+ # Form is: "info xx" which means "info xx 0"
6
+ lookup_pos = position = 0
7
+ else
8
+ position_str = args[0]
9
+ opts = {
10
+ :msg_on_error =>
11
+ "The 'info registers %s' command argument must eval to an integer. Got: %s" % [name, position_str],
12
+ # :min_value => 0,
13
+ :max_value => max_value
14
+ }
15
+ position = @proc.get_an_int(position_str, opts)
16
+ return nil unless position
17
+ end
18
+ lookup_pos =
19
+ if 'lfp' == name
20
+ max_value + 1 - position
21
+ elsif 'sp' == name && 'CFUNC' == @proc.frame.type
22
+ # && @proc.frame.next.type == 'IFUNC" # ?
23
+
24
+ # FIXME: In C frames there seems to be some vm_push_frame's
25
+ # via perhaps vm_yield_with_cfunc along with sp adjustments.
26
+ # I am not sure if this is under what conditions this
27
+ # *doesn't* happen so until I can figure out the better thing
28
+ # to do, possibly in the Ruby 1.9 interpeter, we'll handle
29
+ # this here. It is also conceivable to handle this in
30
+ # thread_frame's sp handling.
31
+ position + 2
32
+ else
33
+ position
34
+ end
35
+ msg("VM %s(%d) = %s" % [name, position,
36
+ @proc.frame.send(name, lookup_pos).inspect])
37
+ return position
38
+ end
39
+
40
+ end
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../../base/subsubcmd'
4
+ require_relative 'helper'
5
+
6
+ class Trepan::Subcommand::InfoRegistersLfp < Trepan::SubSubcommand
7
+ unless defined?(HELP)
8
+ HELP = 'Show the value of the VM local frame pointer (LFP).
9
+
10
+ When a local variable is defined for the first time, this stack
11
+ is pushed and the value for local variable is assigned to this stack entry.
12
+
13
+ See also "info register sp".'
14
+
15
+ MIN_ABBREV = 'lf'.size
16
+ NAME = File.basename(__FILE__, '.rb')
17
+ NEED_STACK = true
18
+ PREFIX = %w(info registers lfp)
19
+ end
20
+
21
+ include Registers
22
+ def run(args)
23
+ frame = @proc.frame
24
+ if 'CFUNC' == frame.type
25
+ msg "local_name not available for C function"
26
+ else
27
+ iseq = frame.iseq
28
+ index = register_array_index(PREFIX[-1], args, iseq.local_size-1)
29
+ msg("local_name(%d)=%s" % [index, iseq.local_name(index)]) if index
30
+ end
31
+ end
32
+ end
33
+
34
+ if __FILE__ == $0
35
+ # Demo it.
36
+ require_relative '../../../mock'
37
+ require_relative '../../../subcmd'
38
+ name = File.basename(__FILE__, '.rb')
39
+
40
+ # FIXME: DRY the below code
41
+ dbgr, info_cmd = MockDebugger::setup('info')
42
+ testcmdMgr = Trepan::Subcmd.new(info_cmd)
43
+ cmd_name = Trepan::SubSubcommand::InfoRegistersSp::PREFIX.join('')
44
+ infox_cmd = Trepan::SubSubcommand::InfoRegistersSp.new(info_cmd.proc,
45
+ info_cmd,
46
+ cmd_name)
47
+ # require_relative '../../../../lib/trepanning'
48
+ # dbgr = Trepan.new(:set_restart => true)
49
+ # dbgr.debugger
50
+ infox_cmd.run([])
51
+
52
+ # name = File.basename(__FILE__, '.rb')
53
+ # subcommand.summary_help(name)
54
+ end
@@ -0,0 +1,44 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../../base/subsubcmd'
4
+
5
+ class Trepan::SubSubcommand::InfoRegistersPc < Trepan::SubSubcommand
6
+ unless defined?(HELP)
7
+ HELP = 'Show the value of the VM program counter (PC).
8
+
9
+ The VM program is an offset into the instruction sequence for the next
10
+ VM instruction in the sequence to be executed.
11
+
12
+ See also "info disassemble" and "info registers".'
13
+ MIN_ABBREV = 'pc'.size
14
+ NAME = File.basename(__FILE__, '.rb')
15
+ NEED_STACK = true
16
+ PREFIX = %w(info registers pc)
17
+ end
18
+
19
+ def run(args)
20
+ msg("VM pc = %d" % @proc.frame.pc_offset)
21
+ end
22
+ end
23
+
24
+ if __FILE__ == $0
25
+ # Demo it.
26
+ require_relative '../../../mock'
27
+ require_relative '../../../subcmd'
28
+ name = File.basename(__FILE__, '.rb')
29
+
30
+ # FIXME: DRY the below code
31
+ dbgr, info_cmd = MockDebugger::setup('info')
32
+ testcmdMgr = Trepan::Subcmd.new(info_cmd)
33
+ cmd_name = Trepan::SubSubcommand::InfoRegistersPc::PREFIX.join('')
34
+ infox_cmd = Trepan::SubSubcommand::InfoRegistersPc.new(info_cmd.proc,
35
+ info_cmd,
36
+ cmd_name)
37
+ # require_relative '../../../../trepanning'
38
+ # dbgr = Trepan.new(:set_restart => true)
39
+ # dbgr.debugger
40
+ infox_cmd.run([])
41
+
42
+ # name = File.basename(__FILE__, '.rb')
43
+ # subcommand.summary_help(name)
44
+ end
@@ -0,0 +1,75 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../../base/subsubcmd'
4
+ require_relative 'helper'
5
+
6
+ class Trepan::Subcommand::InfoRegistersSp < Trepan::SubSubcommand
7
+ unless defined?(HELP)
8
+ HELP = 'Show information about the VM stack pointer (SP).
9
+
10
+ usage:
11
+ info register sp [NUMBER NUMBER ...|size]
12
+
13
+ With no arguments, all SP values for the current frame of the debugged
14
+ program are shown. If a number is given, then the entry at that
15
+ location is shown. If "size" is given, then we show the number items
16
+ in the stack of the current frame.
17
+
18
+ The VM uses a stack to store temporary values in computations. For
19
+ example to compute "a + b", the values of "a" and "b" are pushed onto
20
+ a stack pointed to by SP. Just before the addition is perofrmed, sp(1)
21
+ will have the value "a" contians and sp(2) will contain the value of
22
+ "b"
23
+
24
+ See also "info register LFP"'
25
+
26
+ MIN_ABBREV = 'sp'.size
27
+ NAME = File.basename(__FILE__, '.rb')
28
+ NEED_STACK = true
29
+ PREFIX = %w(info registers sp)
30
+ end
31
+
32
+ include Registers
33
+ def run(args)
34
+ if args.size == 0
35
+ 1.upto(@proc.frame.sp_size-1) do |i|
36
+ msg "%s%d: %s" % [' ' * 2, i, @proc.frame.sp(i).inspect]
37
+ end if @proc.frame.sp_size
38
+ elsif args.size == 1 and 'size' == args[0]
39
+ msg "Number of stack items in frame is #{@proc.frame.sp_size}."
40
+ else
41
+ args.each do |arg|
42
+ register_array_index(PREFIX[-1], arg, @proc.frame.sp_size)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ if __FILE__ == $0
49
+ # Demo it.
50
+ require_relative '../../../mock'
51
+ require_relative '../../../subcmd'
52
+ name = File.basename(__FILE__, '.rb')
53
+
54
+ # FIXME: DRY the below code
55
+ dbgr, info_cmd = MockDebugger::setup('info')
56
+ testcmdMgr = Trepan::Subcmd.new(info_cmd)
57
+ cmd_name = Trepan::SubSubcommand::InfoRegistersSp::PREFIX.join('')
58
+ infox_cmd = Trepan::SubSubcommand::InfoRegistersSp.new(info_cmd.proc,
59
+ info_cmd,
60
+ cmd_name)
61
+ infox_cmd.summary_help(name)
62
+ puts
63
+ # require_relative '../../../../lib/trepanning'
64
+ # dbgr = Trepan.new(:set_restart => true)
65
+ # dbgr.debugger
66
+ infox_cmd.run([])
67
+ puts
68
+ %w(0 1 10).each do |val|
69
+ infox_cmd.run([val])
70
+ puts '-' * 40
71
+ end
72
+ infox_cmd.run(['size'])
73
+
74
+ name = File.basename(__FILE__, '.rb')
75
+ end
@@ -0,0 +1,40 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../base/subcmd'
4
+
5
+ class Trepan::Subcommand::InfoReturn < Trepan::Subcommand
6
+ unless defined?(HELP)
7
+ HELP = 'Show the value about to be returned'
8
+ MIN_ABBREV = 'ret'.size # Note we have "info registers"
9
+ NAME = File.basename(__FILE__, '.rb')
10
+ NEED_STACK = true
11
+ PREFIX = %w(info return)
12
+ end
13
+
14
+ def run(args)
15
+ event = @proc.event
16
+ if %w(return c-return).member?(event)
17
+ ret_val = Trepan::Frame.value_returned(@proc.frame, event)
18
+ msg('Return value: %s' % ret_val.inspect)
19
+ else
20
+ errmsg('You need to be in a return event to do this. Event is %s' %
21
+ event)
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ if __FILE__ == $0
28
+ # Demo it.
29
+ require_relative '../../mock'
30
+ require_relative '../../subcmd'
31
+ name = File.basename(__FILE__, '.rb')
32
+
33
+ # FIXME: DRY the below code
34
+ dbgr, cmd = MockDebugger::setup('info')
35
+ subcommand = Trepan::Subcommand::InfoReturn.new(cmd)
36
+ testcmdMgr = Trepan::Subcmd.new(subcommand)
37
+
38
+ name = File.basename(__FILE__, '.rb')
39
+ subcommand.summary_help(name)
40
+ end
@@ -0,0 +1,106 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../base/subcmd'
4
+ require_relative '../../../app/thread'
5
+ require_relative '../../../app/frame'
6
+
7
+ class Trepan::Subcommand::InfoThread < Trepan::Subcommand
8
+ unless defined?(HELP)
9
+ HELP =
10
+ 'info thread [THREAD-ARG1 THREAD-ARG2.. ]
11
+
12
+ Show frame information for thread(s). If no thread arguments are
13
+ given, then the top frame information is shown for all threads.
14
+
15
+ If arguments are given, each number should be either the object id of
16
+ the thread, a position number in the list of threads, "M", or ".". The
17
+ object id and list position are given when "info thread" is run. The
18
+ name "M" in upper- or lower- case refers to the "main thread" and "."
19
+ refers to the current thread.
20
+
21
+ Examples:
22
+ info thread # Show summary frame information
23
+ info thread M # information for main thread
24
+ info thread . # information for current thread
25
+ info thread 1 2 m # information for thread in list 1, 2, and main
26
+ info thread 92562770 # ifnormation for thread with object id 92562770
27
+ '
28
+ MIN_ABBREV = 'thr'.size
29
+ NAME = File.basename(__FILE__, '.rb')
30
+ NEED_STACK = true
31
+ PREFIX = %w(info thread)
32
+ SHORT_HELP = 'Show frame(s) for threads'
33
+ end
34
+
35
+ include Trepan::ThreadHelper
36
+ include Trepan::Frame # To show stack
37
+
38
+ def list_threads(verbose=false)
39
+ Thread.list.each_with_index do |th, i|
40
+ main_str =
41
+ if th == Thread.main
42
+ '(main thread) '
43
+ else
44
+ ''
45
+ end
46
+ frame, line_no, mark =
47
+ if th == Thread.current
48
+ [@proc.frame, @proc.frame_line, '+']
49
+ else
50
+ [th.threadframe,
51
+ (@proc.frame.source_location && @proc.frame.source_location[0]),
52
+ ' ']
53
+ end
54
+ frame_info = format_stack_call(frame, {})
55
+
56
+ source_container = @proc.frame_container(frame, false)
57
+ loc = @proc.source_location_info(source_container, line_no, frame)
58
+
59
+ msg("%s %2d %s%d %s\n\t%s\n\t%s" %
60
+ [mark, i, main_str, th.object_id, th.inspect, frame_info, loc])
61
+ end
62
+ end
63
+
64
+ def run(args)
65
+ if args.size == 2
66
+ list_threads
67
+ elsif args.size > 2
68
+ args[2..-1].each do |id_or_num_str|
69
+ th = @proc.get_thread_from_string(id_or_num_str)
70
+ if th
71
+ frame = @proc.get_frame_from_thread(th)
72
+ print_stack_trace(frame, {:maxstack => settings[:maxstack]})
73
+ end
74
+ end
75
+ else
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ if __FILE__ == $0
82
+ # Demo it.
83
+ require_relative '../../mock'
84
+ name = File.basename(__FILE__, '.rb')
85
+
86
+ dbgr, cmd = MockDebugger::setup('info')
87
+ # FIXME: shouldn't have to do this:
88
+ cmd.proc.settings[:maxstring] = 150
89
+
90
+ name = File.basename(__FILE__, '.rb')
91
+ cmd_args = ['info', name]
92
+
93
+ cmd.proc.instance_variable_set('@last_args', cmd_args)
94
+ cmd_args = ['info', name]
95
+ cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
96
+ cmd.run(cmd_args)
97
+ puts '-' * 20
98
+ Thread.new do
99
+ cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
100
+ cmd.run(cmd_args)
101
+ puts '-' * 10
102
+ cmd.run(cmd_args + [0])
103
+ puts '-' * 10
104
+ cmd.run(cmd_args + [1])
105
+ end.join
106
+ end
@@ -0,0 +1,106 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'irb'
3
+ require_relative 'base/cmd'
4
+ require_relative '../../app/irb'
5
+ class Trepan::Command::IRBCommand < Trepan::Command
6
+
7
+ unless defined?(HELP)
8
+ HELP =
9
+ " irb [-d]\tstarts an Interactive Ruby (IRB) session.
10
+
11
+ If -d is added you can get access to debugger frame the global variables
12
+ $trepan_frame and $trepan_cmdproc.
13
+
14
+ irb is extended with methods 'cont', 'dbgr', 'n', and, 'q', 'step' which
15
+ run the corresponding debugger commands.
16
+
17
+ To issue a debugger command, inside irb nested inside a debugger use
18
+ 'dbgr'. For example:
19
+
20
+ dbgr %%w(info program)
21
+ dbgr('info', 'program') # Same as above
22
+ dbgr 'info program' # Single quoted string also works
23
+
24
+ But arguments have to be quoted because irb will evaluate them:
25
+
26
+ dbgr info program # wrong!
27
+ dbgr info, program # wrong!
28
+ dbgr(info, program) # What I say 3 times is wrong!
29
+
30
+ Here then is a loop to query VM stack values:
31
+ (-1..1).each {|i| dbgr(\"info reg sp \#{i}\")}
32
+ "
33
+
34
+ CATEGORY = 'support'
35
+ MAX_ARGS = 1 # Need at most this many
36
+ NAME = File.basename(__FILE__, '.rb')
37
+ SHORT_HELP = 'Run interactive Ruby session irb as a command subshell'
38
+ end
39
+
40
+ # This method runs the command
41
+ def run(args) # :nodoc
42
+ add_debugging =
43
+ if args.size > 1
44
+ '-d' == args[1]
45
+ else
46
+ false
47
+ end
48
+
49
+ # unless @state.interface.kind_of?(LocalInterface)
50
+ # print "Command is available only in local mode.\n"
51
+ # throw :debug_error
52
+ # end
53
+
54
+ save_trap = trap('SIGINT') do
55
+ throw :IRB_EXIT, :cont if $trepan_in_irb
56
+ end
57
+
58
+ $trepan = @proc.dbgr
59
+ if add_debugging
60
+ $trepan_cmdproc = @proc
61
+ $trepan_frame = @proc.frame
62
+ end
63
+ $trepan_in_irb = true
64
+ $trepan_irb_statements = nil
65
+ $trepan_command = nil
66
+
67
+ conf = {:BACK_TRACE_LIMIT => settings[:maxstack]}
68
+ cont = IRB.start_session(@proc.frame.binding, @proc, conf)
69
+ trap('SIGINT', save_trap) # Restore old trap
70
+
71
+ back_trace_limit = IRB.CurrentContext.back_trace_limit
72
+ if settings[:maxstack] != back_trace_limit
73
+ msg("\nSetting debugger's BACK_TRACE_LIMIT (%d) to match irb's last setting (%d)" %
74
+ [settings[:maxstack], back_trace_limit])
75
+ settings[:maxstack]= IRB.CurrentContext.back_trace_limit
76
+ end
77
+
78
+ case cont
79
+ when :continue
80
+ @proc.continue
81
+ when :finish
82
+ @proc.finish
83
+ when :next
84
+ @proc.next # (1, {})
85
+ when :quit
86
+ @proc.quit
87
+ when :step
88
+ @proc.step # (1, {})
89
+ else
90
+ @proc.print_location
91
+ end
92
+ ensure
93
+ $trepan_in_irb = false
94
+ # restore old trap if any
95
+ trap('SIGINT', save_trap) if save_trap
96
+ end
97
+ end
98
+
99
+ if __FILE__ == $0
100
+ require 'thread_frame'
101
+ require_relative '../mock'
102
+ name = File.basename(__FILE__, '.rb')
103
+ dbgr, cmd = MockDebugger::setup(name)
104
+ # Get an IRB session -- the hard way :-)
105
+ cmd.run([name]) if ARGV.size > 0
106
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require_relative 'base/cmd'
3
+ class Trepan::Command::KillCommand < Trepan::Command
4
+
5
+ unless defined?(HELP)
6
+ HELP =
7
+ "Kill execution of program being debugged.
8
+
9
+ Equivalent of Process.kill('KILL', Process.pid). This is an unmaskable
10
+ signal. When all else fails, e.g. in thread code, use this.
11
+
12
+ If 'unconditionally' is given, no questions are asked. Otherwise, if
13
+ we are in interactive mode, we'll prompt to make sure."
14
+
15
+ CATEGORY = 'running'
16
+ MAX_ARGS = 1 # Need at most this many
17
+ NAME = File.basename(__FILE__, '.rb')
18
+ SHORT_HELP = 'Send this process a POSIX signal (default "9" is "kill -9")'
19
+ end
20
+
21
+ # This method runs the command
22
+ def run(args) # :nodoc
23
+ if args.size > 1
24
+ sig = Integer(args[1]) rescue args[1]
25
+ unless sig.is_a?(Integer) || Signal.list.member?(sig)
26
+ errmsg("Signal name '#{sig}' is not a signal I know about.\n")
27
+ return false
28
+ end
29
+ # FIXME: reinstate
30
+ # if 'KILL' == sig || Signal['KILL'] == sig
31
+ # @proc.intf.finalize
32
+ # end
33
+ else
34
+ if not confirm('Really kill?', false)
35
+ msg('Kill not confirmed.')
36
+ return
37
+ else
38
+ sig = 'KILL'
39
+ end
40
+ end
41
+ begin
42
+ Process.kill(sig, Process.pid)
43
+ rescue Errno::ESRCH
44
+ errmsg "Unable to send kill #{sig} to process #{Process.pid}"
45
+ end
46
+ end
47
+ end
48
+
49
+ if __FILE__ == $0
50
+ require_relative '../mock'
51
+ name = File.basename(__FILE__, '.rb')
52
+ dbgr, cmd = MockDebugger::setup(name)
53
+ %w(fooo 1 -1 HUP -9).each do |arg|
54
+ puts "#{name} #{arg}"
55
+ cmd.run([name, arg])
56
+ puts '=' * 40
57
+ end
58
+ end