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,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../../base/subsubcmd'
4
+
5
+ class Trepan::SubSubcommand::ShowTracePrint < Trepan::ShowBoolSubSubcommand
6
+ unless defined?(HELP)
7
+ HELP = "Show tracing print status"
8
+ MIN_ABBREV = 'p'.size
9
+ NAME = File.basename(__FILE__, '.rb')
10
+ PREFIX = %w(show trace buffer)
11
+ SHORT_HELP = "Show tracing print status"
12
+ end
13
+
14
+ end
15
+
16
+ if __FILE__ == $0
17
+ # Demo it.
18
+ require_relative '../../../mock'
19
+ require_relative '../../../subcmd'
20
+ name = File.basename(__FILE__, '.rb')
21
+
22
+ # FIXME: DRY the below code
23
+ dbgr, show_cmd = MockDebugger::setup('show')
24
+ testcmdMgr = Trepan::Subcmd.new(show_cmd)
25
+ trace_cmd = Trepan::SubSubcommand::ShowTrace.new(dbgr.core.processor,
26
+ show_cmd)
27
+
28
+ # FIXME: remove the 'join' below
29
+ cmd_name = Trepan::SubSubcommand::ShowTracePrint::PREFIX.join('')
30
+ tb_cmd = Trepan::SubSubcommand::ShowTracePrint.new(show_cmd.proc,
31
+ trace_cmd,
32
+ cmd_name)
33
+ # require_relative '../../../../lib/trepanning'
34
+ # dbgr = Trepan.new(:set_restart => true)
35
+ # dbgr.debugger
36
+ tb_cmd.run([])
37
+
38
+ end
@@ -0,0 +1,74 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+
4
+ # Our local modules
5
+ require_relative 'base/cmd'
6
+ require_relative '../../interface/script'
7
+ # Mfile = import_relative('file', '...lib', 'pydbgr')
8
+
9
+ class Trepan::Command::SourceCommand < Trepan::Command
10
+ unless defined?(HELP)
11
+ HELP = "source [-v][-Y|-N][-c] FILE
12
+
13
+ Read debugger commands from a file named FILE. Optional -v switch
14
+ (before the filename) causes each command in FILE to be echoed as it
15
+ is executed. Option -Y sets the default value in any confirmation
16
+ command to be 'yes' and -N sets the default value to 'no'.
17
+
18
+ Note that the command startup file '.pydbgrc' is read automatically
19
+ via a source command the debugger is started.
20
+
21
+ An error in any command terminates execution of the command file
22
+ unless option -c is given.
23
+ "
24
+ CATEGORY = 'support'
25
+ MIN_ARGS = 1 # Need at least this many
26
+ MAX_ARGS = nil
27
+ NAME = File.basename(__FILE__, '.rb')
28
+ SHORT_HELP = 'Read and run debugger commands from a file'
29
+ end
30
+
31
+ def run(args)
32
+ verbose = false
33
+ parms = args[1..-1]
34
+ opts = {}
35
+ parms.each do |arg|
36
+ case arg
37
+ when '-v'
38
+ opts[:verbose] = true
39
+ when '-Y'
40
+ opts[:confirm_val] = true
41
+ when '-N'
42
+ opts[:confirm_val] = false
43
+ when '-c'
44
+ opts[:abort_on_error] = false
45
+ end
46
+ end
47
+
48
+ filename = args[-1]
49
+
50
+ expanded_file = File.expand_path(filename)
51
+ unless File.readable?(expanded_file)
52
+ errmsg("Debugger command file '%s' is not a readable file" % filename)
53
+ return false
54
+ end
55
+
56
+ # Push a new debugger interface.
57
+ intf = @proc.dbgr.intf
58
+ script_intf = Trepan::ScriptInterface.new(expanded_file,
59
+ intf[-1].output,
60
+ opts)
61
+ intf << script_intf
62
+ return false
63
+ end
64
+ end
65
+
66
+ # Demo it
67
+ if __FILE__ == $0
68
+ require_relative '../mock'
69
+ name = File.basename(__FILE__, '.rb')
70
+ dbgr, cmd = MockDebugger::setup(name)
71
+ if ARGV.size > 1
72
+ cmd.run([name, *ARGV])
73
+ end
74
+ end
@@ -0,0 +1,139 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative 'base/cmd'
4
+ require_relative '../../app/condition'
5
+ class Trepan::Command::StepCommand < Trepan::Command
6
+
7
+ unless defined?(HELP)
8
+ HELP =
9
+ "step[+|=|-|<|>|!|<>] [into] [EVENT-NAME...] [count]
10
+ step until EXPRESSION
11
+ step thread
12
+ step to METHOD-NAME
13
+ step over
14
+ step out
15
+
16
+ Execute the current line, stopping at the next event. Sometimes this
17
+ is called 'step into'.
18
+
19
+ With an integer argument, step that many times. With an 'until'
20
+ expression that expression is evaluated and we stop the first time it
21
+ is true.
22
+
23
+ EVENT-NAME... is list of an event name which is one on 'call',
24
+ 'return', 'line', 'exception' 'c-call', 'c-return' or 'c-exception'.
25
+ If specified, only those stepping events will be considered. If no
26
+ list of event names is given, then any event triggers a stop when the
27
+ count is 0.
28
+
29
+ There is however another way to specify an *single* EVENT-NAME, by
30
+ suffixing one of the symbols '<', '>', or '!' after the command or on
31
+ an alias of that. A suffix of '+' on a command or an alias forces a
32
+ move to another position, while a suffix of '-' disables this
33
+ requirement. A suffix of '>' will continue until the next
34
+ call. ('finish' will run run until the return for that call.)
35
+
36
+ If no suffix is given, the debugger setting 'different' determines
37
+ this behavior.
38
+
39
+ Examples:
40
+ step # step 1 event, *any* event obeying 'set different' setting
41
+ step 1 # same as above
42
+ step+ # same but force stopping on a new line
43
+ step= # same but force stopping on a new line a new frame added
44
+ step- # same but force stopping on a new line a new frame added
45
+ step 5/5+0 # same as above
46
+ step line # step only line events
47
+ step call # step only call call events
48
+ step> # step call and C-call events
49
+ step< # step only return and C-return events
50
+ step call line # Step line *and* call events
51
+ step<> # same as step call c-call return c-return
52
+ step until a > b
53
+ step over # same as 'next'
54
+ step out # same as 'finish'
55
+ step thread # step stopping only in the current thread. Is the same
56
+ # as step until Thread.current.object_id == #object_id
57
+
58
+ Related and similar is the 'next' (step over) and 'finish' (step out)
59
+ commands. All of these are slower than running to a breakpoint.
60
+
61
+ See also the commands:
62
+ 'skip', 'jump' (there's no 'hop' yet), 'continue', 'return' and
63
+ 'finish' for other ways to progress execution.
64
+ "
65
+
66
+ ALIASES = %w(s step+ step- step< step> step<> step! s> s< s+ s-
67
+ s<> s! s=)
68
+ CATEGORY = 'running'
69
+ NAME = File.basename(__FILE__, '.rb')
70
+ NEED_RUNNING = true
71
+ SHORT_HELP = 'Step program (possibly entering called functions)'
72
+
73
+ Keyword_to_related_cmd = {
74
+ 'out' => 'finish',
75
+ 'over' => 'next',
76
+ 'into' => 'step',
77
+ }
78
+ end
79
+
80
+ include Trepan::Condition
81
+ # This method runs the command
82
+ def run(args) # :nodoc
83
+ opts = @proc.parse_next_step_suffix(args[0])
84
+ condition = nil
85
+ if args.size == 1
86
+ # Form is: "step" which means "step 1"
87
+ step_count = 0
88
+ else
89
+ replace_cmd = Keyword_to_related_cmd[args[1]]
90
+ if replace_cmd
91
+ cmd = @proc.commands[replace_cmd]
92
+ return cmd.run([replace_cmd] + args[2..-1])
93
+ elsif 'until' == args[1]
94
+ try_condition = args[2..-1].join(' ')
95
+ if valid_condition?(try_condition)
96
+ condition = try_condition
97
+ opts[:different_pos] = false
98
+ step_count = 0
99
+ end
100
+ elsif 'to' == args[1]
101
+ if args.size != 3
102
+ errmsg('Expecting a method name after "to"')
103
+ return
104
+ elsif !@proc.method?(args[2])
105
+ errmsg("#{args[2]} doesn't seem to be a method name")
106
+ return
107
+ else
108
+ opts[:to_method] = args[2]
109
+ opts[:different_pos] = false
110
+ step_count = 0
111
+ end
112
+ elsif 'thread' == args[1]
113
+ condition = "Thread.current.object_id == #{Thread.current.object_id}"
114
+ opts[:different_pos] = false
115
+ step_count = 0
116
+ else
117
+ count_str = args[1]
118
+ int_opts = {
119
+ :msg_on_error =>
120
+ "The 'step' command argument must eval to an integer. Got: %s" %
121
+ count_str,
122
+ :min_value => 1
123
+ }.merge(opts)
124
+ count = @proc.get_an_int(count_str, int_opts)
125
+ return unless count
126
+ # step 1 is core.step_count = 0 or "stop next event"
127
+ step_count = count - 1
128
+ end
129
+ end
130
+ @proc.step(step_count, opts, condition)
131
+ end
132
+ end
133
+
134
+ if __FILE__ == $0
135
+ require_relative '../mock'
136
+ name = File.basename(__FILE__, '.rb')
137
+ dbgr, cmd = MockDebugger::setup(name)
138
+ p cmd.run([name])
139
+ end
@@ -0,0 +1,63 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative 'base/cmd'
4
+ require_relative '../../app/condition'
5
+ class Trepan::Command::StepICommand < Trepan::Command
6
+
7
+ unless defined?(HELP)
8
+ HELP =
9
+ "stepi
10
+
11
+ Step by VM instruction(s).
12
+
13
+ Examples:
14
+ stepi # step 1 instruction
15
+ stepi 1 # same as above
16
+
17
+ Related and similar is the 'step', 'next' (step over) and 'finish' (step out)
18
+ commands. All of these are slower than running to a breakpoint.
19
+
20
+ See also the commands:
21
+ 'skip', 'jump' (there's no 'hop' yet), 'continue', 'return' and
22
+ 'finish' for other ways to progress execution.
23
+ "
24
+
25
+ CATEGORY = 'running'
26
+ NAME = File.basename(__FILE__, '.rb')
27
+ NEED_RUNNING = true
28
+ SHORT_HELP = 'Step VM instruction(s)'
29
+
30
+ end
31
+
32
+ include Trepan::Condition
33
+ # This method runs the command
34
+ def run(args) # :nodoc
35
+ opts = {:stop_events => Set.new(%w(insn))}
36
+ @proc.core.step_events |= Trace::INSN_EVENT_MASK
37
+ condition = nil
38
+ if args.size == 1
39
+ # Form is: "step" which means "step 1"
40
+ step_count = 0
41
+ else
42
+ count_str = args[1]
43
+ int_opts = {
44
+ :msg_on_error =>
45
+ "The 'step' command argument must eval to an integer. Got: %s" %
46
+ count_str,
47
+ :min_value => 1
48
+ }.merge(opts)
49
+ count = @proc.get_an_int(count_str, int_opts)
50
+ return unless count
51
+ # step 1 is core.step_count = 0 or "stop next event"
52
+ step_count = count - 1
53
+ end
54
+ @proc.step(step_count, opts, condition)
55
+ end
56
+ end
57
+
58
+ if __FILE__ == $0
59
+ require_relative '../mock'
60
+ name = File.basename(__FILE__, '.rb')
61
+ dbgr, cmd = MockDebugger::setup(name)
62
+ p cmd.run([name])
63
+ end
@@ -0,0 +1,44 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require_relative 'base/cmd'
3
+
4
+ class Trepan::Command::UnaliasCommand < Trepan::Command
5
+
6
+ unless defined?(HELP)
7
+ HELP =
8
+ "unalias COMMAND
9
+
10
+ Remove alias for COMMAND
11
+
12
+ See also 'alias'.
13
+ "
14
+
15
+ CATEGORY = 'support'
16
+ MIN_ARGS = 1
17
+ # MAX_ARGS = 1 # Need at most this many
18
+ NAME = File.basename(__FILE__, '.rb')
19
+ NEED_STACK = true
20
+ SHORT_HELP = 'Remove an alias'
21
+ end
22
+
23
+ # Run command.
24
+ def run(args)
25
+ args[1..-1].each do |arg|
26
+ if @proc.aliases.member?(arg)
27
+ @proc.aliases.delete(arg)
28
+ msg "Alias for #{arg} removed."
29
+ else
30
+ msg "No alias found for #{arg}."
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ if __FILE__ == $0
37
+ # Demo it.
38
+ require_relative '../mock'
39
+ name = File.basename(__FILE__, '.rb')
40
+ dbgr, cmd = MockDebugger::setup(name)
41
+ cmd.run %w(unalias s)
42
+ cmd.run %w(unalias s)
43
+ cmd.run %w(unalias foo bar n)
44
+ end
@@ -0,0 +1,63 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative 'base/cmd'
4
+
5
+ # undisplay display-number...
6
+ class Trepan::Command::UndisplayCommand < Trepan::Command
7
+
8
+ unless defined?(HELP)
9
+ HELP = <<EOH
10
+
11
+ undisplay DISPLAY_NUMBER ...
12
+ Cancel some expressions to be displayed when program stops.
13
+ Arguments are the code numbers of the expressions to stop displaying.
14
+ No argument means cancel all automatic-display expressions.
15
+ "delete display" has the same effect as this command.
16
+ Do "info display" to see current list of code numbers.
17
+ EOH
18
+
19
+ ALIASES = %w(und)
20
+ CATEGORY = 'data'
21
+ NAME = File.basename(__FILE__, '.rb')
22
+ NEED_STACK = false
23
+ SHORT_HELP = 'Cancel some expressions to be displayed when program stops'
24
+ end
25
+
26
+ def run(args)
27
+
28
+ if args.size == 1
29
+ @proc.displays.clear
30
+ return
31
+ end
32
+ opts = {}
33
+ args[1..-1].each do |arg|
34
+ opts[:msg_on_error] = '%s must be a display number' % arg
35
+ i = @proc.get_an_int(arg, opts)
36
+ if i
37
+ unless @proc.displays.delete_index(i)
38
+ errmsg("no display number %d." % i)
39
+ return
40
+ end
41
+ end
42
+ return false
43
+ end
44
+ end
45
+ end
46
+
47
+ if __FILE__ == $0
48
+ # demo it.
49
+ require 'thread_frame'
50
+ require_relative '../mock'
51
+ name = File.basename(__FILE__, '.rb')
52
+ dbgr, cmd = MockDebugger::setup(name)
53
+
54
+ def run_cmd(cmd, args)
55
+ cmd.run(args)
56
+ puts '==' * 10
57
+ end
58
+
59
+ cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
60
+
61
+ run_cmd(cmd, %w(undisplay z))
62
+ run_cmd(cmd, %w(undisplay 1 10))
63
+ end
@@ -0,0 +1,92 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require_relative 'base/cmd'
3
+
4
+ # up command. Like 'down' butthe direction (set by DIRECTION) is different.
5
+ #
6
+ # NOTE: The down command subclasses this, so beware when changing!
7
+ class Trepan::Command::UpCommand < Trepan::Command
8
+
9
+ # Silence already initialized constant .. warnings
10
+ old_verbose = $VERBOSE
11
+ $VERBOSE = nil
12
+ HELP =
13
+ "u(p) [count]
14
+
15
+ Move the current frame up in the stack trace (to an older frame). 0 is
16
+ the most recent frame. If no count is given, move up 1.
17
+
18
+ See also 'down' and 'frame'.
19
+ "
20
+
21
+ ALIASES = %w(u)
22
+ CATEGORY = 'stack'
23
+ MAX_ARGS = 1 # Need at most this many
24
+ NAME = File.basename(__FILE__, '.rb')
25
+ NEED_STACK = true
26
+ SHORT_HELP = 'Move frame in the direction of the caller of the last-selected frame'
27
+ $VERBOSE = old_verbose
28
+
29
+ require_relative '../../app/frame'
30
+ include Trepan::Frame
31
+
32
+ def initialize(proc)
33
+ super
34
+ @direction = +1 # -1 for down.
35
+ end
36
+
37
+ # Run 'up' command.
38
+ def run(args)
39
+
40
+ # FIXME: move into @proc and test based on NEED_STACK.
41
+ if not @proc.top_frame
42
+ errmsg('No frames recorded.')
43
+ return false
44
+ end
45
+
46
+ if args.size == 1
47
+ # Form is: "down" which means "down 1"
48
+ count = 1
49
+ else
50
+ stack_size = @proc.top_frame.stack_size - @proc.hide_level
51
+ count_str = args[1]
52
+ name_or_id = args[1]
53
+ opts = {
54
+ :msg_on_error =>
55
+ "The '#{NAME}' command argument requires a frame number. Got: %s" % count_str,
56
+ :min_value => -stack_size,
57
+ :max_value => stack_size-1
58
+ }
59
+ count = @proc.get_an_int(count_str, opts)
60
+ return false unless count
61
+ end
62
+ @proc.adjust_frame(@direction * count, false)
63
+ end
64
+ end
65
+
66
+ if __FILE__ == $0
67
+ # Demo it.
68
+ require 'thread_frame'
69
+ require_relative '../mock'
70
+ name = File.basename(__FILE__, '.rb')
71
+ dbgr, cmd = MockDebugger::setup(name)
72
+
73
+ def sep ; puts '=' * 40 end
74
+ cmd.run [name]
75
+ %w(-1 0 1 -2).each do |count|
76
+ puts "#{name} #{count}"
77
+ cmd.run([name, count])
78
+ sep
79
+ end
80
+ def foo(cmd, name)
81
+ cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
82
+ puts "#{name}"
83
+ cmd.run([name])
84
+ sep
85
+ %w(-2 -1).each do |count|
86
+ puts "#{name} #{count}"
87
+ cmd.run([name, count])
88
+ sep
89
+ end
90
+ end
91
+ foo(cmd, name)
92
+ end
@@ -0,0 +1,45 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require_relative '../app/default'
3
+ class Trepan
4
+ class CmdProcessor
5
+
6
+ DEFAULT_SETTINGS = {
7
+ :autoeval => true, # Ruby eval non-debugger commands
8
+ :autoirb => false, # Go into IRB in debugger command loop
9
+ :autolist => false, # Run 'list'
10
+
11
+ :basename => false, # Show basename of filenames only
12
+ :different => 'nostack', # stop *only* when different position?
13
+
14
+ :debugdbgr => false, # Debugging the debugger
15
+ :debugexcept => true, # Internal debugging of command exceptions
16
+ :debugmacro => false, # debugging macros
17
+ :debugskip => false, # Internal debugging of step/next skipping
18
+ :debugstack => false, # How hidden outer debugger stack frames
19
+ :directory => # last-resort path-search for files
20
+ '$cdir:$cwd', # that are not fully qualified.
21
+
22
+ :maxlist => 10, # Number of source lines to list
23
+ :maxstack => 10, # backtrace limit
24
+ :maxstring => 150, # Strings which are larger than this
25
+ # will be truncated to this length when
26
+ # printed
27
+ :maxwidth => (ENV['COLUMNS'] || '80').to_i,
28
+ :prompt => 'trepan', # core part of prompt. Additional info like
29
+ # debug nesting and
30
+ :save_cmdfile => nil, # If set, debugger command file to be
31
+ # used on restart
32
+ :timer => false, # show elapsed time between events
33
+ :traceprint => false, # event tracing printing
34
+ :tracebuffer => false, # save events to a trace buffer.
35
+ :user_cmd_dir => File.join(Trepanning::HOME_DIR, 'trepan', 'command'),
36
+ # User command directory
37
+ } unless defined?(DEFAULT_SETTINGS)
38
+ end
39
+ end
40
+
41
+ if __FILE__ == $0
42
+ # Show it:
43
+ require 'pp'
44
+ PP.pp(Trepan::CmdProcessor::DEFAULT_SETTINGS)
45
+ end
@@ -0,0 +1,17 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require_relative '../app/display'
3
+ class Trepan
4
+ class CmdProcessor
5
+ attr_reader :displays
6
+
7
+ def display_initialize
8
+ @displays = DisplayMgr.new
9
+ end
10
+
11
+ def run_eval_display(args={})
12
+ for line in @displays.display(@frame) do
13
+ msg(line)
14
+ end
15
+ end
16
+ end
17
+ end
data/processor/eval.rb ADDED
@@ -0,0 +1,88 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ class Trepan
3
+ class CmdProcessor
4
+
5
+ def debug_eval(str, max_fake_filename=15)
6
+ begin
7
+ debug_eval_with_exception(str, max_fake_filename)
8
+ rescue SyntaxError, StandardError, ScriptError => e
9
+ exception_dump(e, @settings[:stack_trace_on_error], $!.backtrace)
10
+ nil
11
+ end
12
+ end
13
+
14
+ def debug_eval_with_exception(str, max_fake_filename=15)
15
+ filename, b = get_binding_and_filename(str, max_fake_filename)
16
+ eval(str, b, filename)
17
+ end
18
+
19
+ def debug_eval_no_errmsg(str, max_fake_filename=15)
20
+ begin
21
+ debug_eval_with_exception(str, max_fake_filename)
22
+ rescue SyntaxError, StandardError, ScriptError => e
23
+ nil
24
+ end
25
+ end
26
+
27
+ def exception_dump(e, stack_trace, backtrace)
28
+ str = "#{e.class} Exception:\n\t#{e.message}"
29
+ if stack_trace
30
+ str += "\n" + backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil
31
+ end
32
+ msg str
33
+ # throw :debug_error
34
+ end
35
+
36
+ def fake_eval_filename(str, maxlen = 15)
37
+ fake_filename =
38
+ if maxlen < str.size
39
+ # FIXME: Guard against \" in positions 13..15?
40
+ str.inspect[0..maxlen-1] + '"...'
41
+ else
42
+ str.inspect
43
+ end
44
+ "(eval #{fake_filename})"
45
+ end
46
+
47
+ def get_binding_and_filename(str, maxlen)
48
+ b =
49
+ begin
50
+ @frame.binding
51
+ rescue
52
+ binding
53
+ end
54
+ filename = fake_eval_filename(str, maxlen)
55
+ return [filename, b]
56
+ end
57
+
58
+ end
59
+ end
60
+
61
+ if __FILE__ == $0
62
+ # Demo it.
63
+ cmdp = Trepan::CmdProcessor.new
64
+ puts cmdp.fake_eval_filename('x = 1; y = 2')
65
+ puts cmdp.fake_eval_filename('x = 1; y = 2', 7)
66
+
67
+ def cmdp.errmsg(msg)
68
+ puts "** #{msg}"
69
+ end
70
+ begin
71
+ 1/0
72
+ rescue Exception => exc
73
+ cmdp.exception_dump(exc, true, $!.backtrace)
74
+ puts '=' * 40
75
+ end
76
+
77
+ x = 1
78
+ require 'thread_frame'
79
+ cmdp.instance_variable_set('@frame', RubyVM::ThreadFrame.current)
80
+ cmdp.instance_variable_set('@settings', {:stack_trace_on_error => true})
81
+ def cmdp.errmsg(mess) ; puts mess end
82
+ puts cmdp.debug_eval('x = "#{x}"')
83
+ puts cmdp.debug_eval('x+')
84
+ puts cmdp.debug_eval_no_errmsg('y+')
85
+ puts '=' * 40
86
+ puts cmdp.debug_eval('y = 1; x+', 4)
87
+ puts '=' * 40
88
+ end