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
@@ -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