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,28 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative 'base/submgr'
4
+
5
+ class Trepan::Command::InfoCommand < Trepan::SubcommandMgr
6
+ unless defined?(HELP)
7
+ HELP =
8
+ 'Generic command for showing things about the program being debugged.
9
+
10
+ You can give unique prefix of the name of a subcommand to get
11
+ information about just that subcommand.
12
+
13
+ Type "info" for a list of "info" subcommands and what they do.
14
+ Type "help info *" for just a list of "info" subcommands.
15
+ '
16
+
17
+ ALIASES = %w(i)
18
+ CATEGORY = 'status'
19
+ NAME = File.basename(__FILE__, '.rb')
20
+ SHORT_HELP = 'Information about debugged program and its environment'
21
+ end
22
+ end
23
+
24
+ if __FILE__ == $0
25
+ require_relative '../mock'
26
+ name = File.basename(__FILE__, '.rb')
27
+ dbgr, cmd = MockDebugger::setup(name)
28
+ end
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../base/subcmd'
4
+ require_relative '../../../app/frame'
5
+
6
+ class Trepan::Subcommand::InfoArgs < Trepan::Subcommand
7
+ unless defined?(HELP)
8
+ HELP = 'Show argument variables of the current stack frame'
9
+ MIN_ABBREV = 'ar'.size
10
+ NAME = File.basename(__FILE__, '.rb')
11
+ NEED_STACK = true
12
+ PREFIX = %w(info args)
13
+ end
14
+
15
+ include Trepan::Frame
16
+ def run(args)
17
+ if 'CFUNC' == @proc.frame.type
18
+ argc = @proc.frame.argc
19
+ if argc > 0
20
+ 1.upto(argc).each do |i|
21
+ msg "#{i}: #{@proc.frame.sp(argc-i+3).inspect}"
22
+ end
23
+ else
24
+ msg("No parameters in C call.")
25
+ end
26
+ else
27
+ param_names = all_param_names(@proc.frame.iseq, false)
28
+ if param_names.empty?
29
+ msg("No parameters in call.")
30
+ else
31
+ param_names.each_with_index do |var_name, i|
32
+ var_value = @proc.safe_rep(@proc.debug_eval_no_errmsg(var_name).inspect)
33
+ msg("#{var_name} = #{var_value}")
34
+ end
35
+ unless 'call' == @proc.event and 0 == @proc.frame_index
36
+ msg("Values may have change from the initial call values.")
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ if __FILE__ == $0
44
+ # Demo it.
45
+ require_relative '../../mock'
46
+ require_relative '../../subcmd'
47
+ name = File.basename(__FILE__, '.rb')
48
+
49
+ # FIXME: DRY the below code
50
+ dbgr, cmd = MockDebugger::setup('info')
51
+ subcommand = Trepan::Subcommand::InfoArgs.new(cmd)
52
+ testcmdMgr = Trepan::Subcmd.new(subcommand)
53
+
54
+ name = File.basename(__FILE__, '.rb')
55
+ subcommand.summary_help(name)
56
+ end
@@ -0,0 +1,162 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../base/subcmd'
4
+
5
+ class Trepan::Subcommand::InfoBreakpoints < Trepan::Subcommand
6
+ unless defined?(HELP)
7
+ HELP = <<EOH
8
+ info breakpoints [num1 ...] [verbose]
9
+
10
+ Show status of user-settable breakpoints. If no breakpoint numbers are
11
+ given, the show all breakpoints. Otherwise only those breakpoints
12
+ listed are shown and the order given. If VERBOSE is given, more
13
+ information provided about each breakpoint.
14
+
15
+ The "Disp" column contains one of "keep", "del", the disposition of
16
+ the breakpoint after it gets hit.
17
+
18
+ The "enb" column indicates whether the breakpoint is enabled.
19
+
20
+ The "Where" column indicates where the breakpoint is located.
21
+ EOH
22
+
23
+ MIN_ABBREV = 'br'.size
24
+ NAME = File.basename(__FILE__, '.rb')
25
+ PREFIX = %w(info breakpoints)
26
+ SHORT_HELP = "Status of user-settable breakpoints"
27
+ end
28
+
29
+ def bpprint(bp, verbose=false)
30
+ disp = bp.temp? ? 'del ' : 'keep '
31
+ disp += bp.enabled? ? 'y ' : 'n '
32
+
33
+ iseq = bp.iseq
34
+ mess = '%-4dbreakpoint %s at ' % [bp.id, disp]
35
+
36
+ line_loc = '%s:%d' %
37
+ [iseq.source_container.join(' '),
38
+ iseq.offset2lines(bp.offset).join(', ')]
39
+ vm_loc = "VM offset %d of instruction sequence \"%s\"" %
40
+ [bp.offset, iseq.name]
41
+
42
+ loc, other_loc =
43
+ if 'line' == bp.type
44
+ [line_loc, vm_loc]
45
+ else # 'offset' == bp.type
46
+ [vm_loc, line_loc]
47
+ end
48
+ msg(mess + loc)
49
+ msg("\t#{other_loc}") if verbose
50
+
51
+ if bp.condition && bp.condition != 'true'
52
+ msg("\tstop only if %s" % bp.condition)
53
+ end
54
+ if bp.ignore > 0
55
+ msg("\tignore next %d hits" % bp.ignore)
56
+ end
57
+ if bp.hits > 0
58
+ ss = (bp.hits > 1) ? 's' : ''
59
+ msg("\tbreakpoint already hit %d time%s" %
60
+ [bp.hits, ss])
61
+ end
62
+ end
63
+
64
+ def save_command
65
+ bpmgr = @proc.brkpts
66
+ bpmgr.list.inject([]) do |res, bp|
67
+ iseq = bp.iseq
68
+ next unless 'file' == iseq.source_container[0]
69
+ loc = iseq.source_container[1] + ':'
70
+ loc +=
71
+ # if 'line' == bp.type
72
+ iseq.offset2lines(bp.offset)[0].to_s
73
+ # else
74
+ # 'O' + bp.offset.to_s
75
+ # end
76
+ res << "break #{loc}"
77
+ end
78
+ end
79
+
80
+ def run(args)
81
+ verbose = false
82
+ unless args.empty?
83
+ if 'verbose' == args[-1]
84
+ verbose = true
85
+ args.pop
86
+ end
87
+ end
88
+
89
+
90
+ show_all =
91
+ if args.size > 2
92
+ opts = {
93
+ :msg_on_error =>
94
+ "An '#{PREFIX.join(' ')}' argument must eval to a breakpoint between 1..#{@proc.brkpts.max}.",
95
+ :min_value => 1,
96
+ :max_value => @proc.brkpts.max
97
+ }
98
+ bp_nums = @proc.get_int_list(args[2..-1])
99
+ false
100
+ else
101
+ true
102
+ end
103
+
104
+ bpmgr = @proc.brkpts
105
+ if bpmgr.empty?
106
+ msg('No breakpoints.')
107
+ else
108
+ # There's at least one
109
+ msg("Num Type Disp Enb Where")
110
+ if show_all
111
+ bpmgr.list.each do |bp|
112
+ bpprint(bp, verbose)
113
+ end
114
+ else
115
+ notfound = []
116
+ bp_nums.each do |bp_num|
117
+ bp = @proc.brkpts[bp_num]
118
+ if bp
119
+ bpprint(bp, verbose)
120
+ else
121
+ notfound << bp_num
122
+ end
123
+ end
124
+ errmsg "No breakpoint number(s) #{not_found.join(' ')}." unless
125
+ notfound.empty?
126
+ end
127
+ end
128
+ end
129
+
130
+ end
131
+
132
+ if __FILE__ == $0
133
+ # Demo it.
134
+ require_relative '../../mock'
135
+ name = File.basename(__FILE__, '.rb')
136
+ dbgr, cmd = MockDebugger::setup('info')
137
+ subcommand = Trepan::Subcommand::InfoBreak.new(cmd)
138
+
139
+ puts '-' * 20
140
+ subcommand.run(%w(info break))
141
+ puts '-' * 20
142
+ subcommand.summary_help(name)
143
+ puts
144
+ puts '-' * 20
145
+
146
+ require 'thread_frame'
147
+ tf = RubyVM::ThreadFrame.current
148
+ pc_offset = tf.pc_offset
149
+ def foo
150
+ 5
151
+ end
152
+
153
+ brk_cmd = dbgr.core.processor.commands['break']
154
+ brk_cmd.run(['break', "O#{pc_offset}"])
155
+ cmd.run(%w(info break))
156
+ puts '-' * 20
157
+ brk_cmd.run(['break', 'foo'])
158
+ subcommand.run(%w(info break))
159
+ puts '-' * 20
160
+ p subcommand.save_command
161
+
162
+ end
@@ -0,0 +1,162 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'linecache'
4
+ require_relative '../base/subcmd'
5
+ require_relative '../../../app/file'
6
+
7
+ class Trepan::Subcommand::InfoFile < Trepan::Subcommand
8
+ unless defined?(HELP)
9
+ DEFAULT_FILE_ARGS = %w(size sha1)
10
+
11
+ HELP =
12
+ "info file [{FILENAME|.} [all | brkpts | iseq | sha1 | size | stat]]
13
+
14
+ Show information about the current file. If no filename is given and
15
+ the program is running then the current file associated with the
16
+ current stack entry is used. Sub options which can be shown about a file are:
17
+
18
+ brkpts -- Line numbers where there are statement boundaries.
19
+ These lines can be used in breakpoint commands.
20
+ iseq -- Instruction sequences from this file.
21
+ sha1 -- A SHA1 hash of the source text. This may be useful in comparing
22
+ source code.
23
+ size -- The number of lines in the file.
24
+ stat -- File.stat information
25
+
26
+ all -- All of the above information.
27
+
28
+ If no sub-options are given #{DEFAULT_FILE_ARGS.join(' ')} are assumed.
29
+ "
30
+ MIN_ABBREV = 'fi'.size # Note we have "info frame"
31
+ NAME = File.basename(__FILE__, '.rb')
32
+ NEED_STACK = false
33
+ PREFIX = %w(info file)
34
+ end
35
+
36
+ include Trepanning
37
+
38
+ # Get file information
39
+ def run(args)
40
+ return if args.size < 2
41
+ args << '.' if 2 == args.size
42
+ filename =
43
+ if '.' == args[2]
44
+ if not @proc.frame
45
+ errmsg("No frame - no default file.")
46
+ return false
47
+ nil
48
+ else
49
+ File.expand_path(@proc.frame.source_container[1])
50
+ end
51
+ else
52
+ args[2]
53
+ end
54
+ args += DEFAULT_FILE_ARGS if args.size == 3
55
+
56
+ m = filename + ' is'
57
+ canonic_name = LineCache::map_file(filename)
58
+ if LineCache::cached?(canonic_name)
59
+ m += " cached in debugger"
60
+ if canonic_name != filename
61
+ m += (' as:' + canonic_name)
62
+ end
63
+ m += '.'
64
+ msg(m)
65
+ elsif !(matches = find_scripts(filename)).empty?
66
+ if (matches.size > 1)
67
+ msg("Multiple files found:")
68
+ matches.each { |filename| msg("\t%s" % filename) }
69
+ return
70
+ else
71
+ msg('File "%s" just now cached.' % filename)
72
+ LineCache::cache(matches[0])
73
+ LineCache::remap_file(matches[0], filename)
74
+ canonic_name = matches[0]
75
+ end
76
+ else
77
+ msg(m + ' not cached in debugger.')
78
+ return
79
+ end
80
+ seen = {}
81
+ args[3..-1].each do |arg|
82
+ processed_arg = false
83
+
84
+ if %w(all size).member?(arg)
85
+ unless seen[:size]
86
+ max_line = LineCache::size(canonic_name)
87
+ msg "File has %d lines." % max_line if max_line
88
+ end
89
+ processed_arg = seen[:size] = true
90
+ end
91
+
92
+ if %w(all sha1).member?(arg)
93
+ unless seen[:sha1]
94
+ msg("SHA1 is %s." % LineCache::sha1(canonic_name))
95
+ end
96
+ processed_arg = seen[:sha1] = true
97
+ end
98
+
99
+ if %w(all brkpts).member?(arg)
100
+ unless seen[:brkpts]
101
+ msg("Possible breakpoint line numbers:")
102
+ lines = LineCache::trace_line_numbers(canonic_name)
103
+ fmt_lines = columnize_numbers(lines)
104
+ msg(fmt_lines)
105
+ end
106
+ processed_arg = seen[:brkpts] = true
107
+ end
108
+
109
+ if %w(all iseq).member?(arg)
110
+ unless seen[:iseq]
111
+ if SCRIPT_ISEQS__.member?(canonic_name)
112
+ msg("File contains instruction sequences:")
113
+ SCRIPT_ISEQS__[canonic_name].each do |iseq|
114
+ msg("\t %s %s" % [iseq, iseq.name.inspect])
115
+ end
116
+ else
117
+ msg("Instruction sequences not recorded; there may be some, though.")
118
+ end
119
+ end
120
+ processed_arg = seen[:iseq] = true
121
+ end
122
+
123
+ if %w(all stat).member?(arg)
124
+ unless seen[:stat]
125
+ msg("Stat info:\n\t%s." % LineCache::stat(canonic_name).inspect)
126
+ end
127
+ processed_arg = seen[:stat] = true
128
+ end
129
+
130
+ if not processed_arg
131
+ errmsg("I don't understand sub-option \"%s\"." % arg)
132
+ end
133
+ end unless args.empty?
134
+ end
135
+ end
136
+
137
+ if __FILE__ == $0
138
+ if not (ARGV.size == 1 && ARGV[0] == 'noload')
139
+ ISEQS__ = {}
140
+ SCRIPT_ISEQS__ = {}
141
+ ARGV[0..-1] = ['noload']
142
+ load(__FILE__)
143
+ else
144
+ require_relative '../../mock'
145
+ require_relative '../../subcmd'
146
+ name = File.basename(__FILE__, '.rb')
147
+ # FIXME: DRY the below code
148
+ dbgr, cmd = MockDebugger::setup('info')
149
+ subcommand = Trepan::Subcommand::InfoFile.new(cmd)
150
+ testcmdMgr = Trepan::Subcmd.new(subcommand)
151
+
152
+ [%w(info file nothere),
153
+ %w(info file .),
154
+ %w(info file),
155
+ %w(info file file.rb),
156
+ %w(info file . all),
157
+ %w(info file . lines size sha1 sha1)].each do |args|
158
+ subcommand.run(args)
159
+ puts '-' * 40
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../base/subcmd'
4
+
5
+ class Trepan::Subcommand::InfoFrame < Trepan::Subcommand
6
+ unless defined?(HELP)
7
+ HELP = 'Show all information about the selected frame'
8
+ MIN_ABBREV = 'fr'.size # Note we have "info file"
9
+ NAME = File.basename(__FILE__, '.rb')
10
+ NEED_STACK = true
11
+ PREFIX = %w(info frame)
12
+ end
13
+
14
+ def run(args)
15
+ frame = @proc.frame
16
+ msg("Line %s of %s at PC offset %d, type: %s" %
17
+ [@proc.frame_line, frame.source_container[1], frame.pc_offset,
18
+ frame.type])
19
+ if @proc.event == 'return'
20
+ msg("Return value class: #{@proc.frame.sp(1).class}")
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ if __FILE__ == $0
27
+ # Demo it.
28
+ require_relative '../../mock'
29
+ require_relative '../../subcmd'
30
+ name = File.basename(__FILE__, '.rb')
31
+
32
+ # FIXME: DRY the below code
33
+ dbgr, cmd = MockDebugger::setup('info')
34
+ subcommand = Trepan::Subcommand::InfoFrame.new(cmd)
35
+ testcmdMgr = Trepan::Subcmd.new(subcommand)
36
+
37
+ name = File.basename(__FILE__, '.rb')
38
+ subcommand.summary_help(name)
39
+ end
@@ -0,0 +1,83 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../base/subcmd'
4
+
5
+ class Trepan::Subcommand::InfoIseq < Trepan::Subcommand
6
+ unless defined?(HELP)
7
+ HELP =
8
+ 'info iseq [METHOD|.]
9
+
10
+ Show information about an instruction sequence.
11
+
12
+ Examples:
13
+ info iseq
14
+ info iseq .
15
+ info iseq require_relative
16
+ '
17
+ MIN_ABBREV = 'is'.size
18
+ NAME = File.basename(__FILE__, '.rb')
19
+ NEED_STACK = true
20
+ PREFIX = %w(info iseq)
21
+ SHORT_HELP = 'Information about an instruction sequence'
22
+ end
23
+
24
+ def run(args)
25
+ if 2 == args.size
26
+ iseq_name = '.'
27
+ else
28
+ iseq_name = args[2]
29
+ end
30
+ if '.' == iseq_name
31
+ iseq = frame = @proc.frame.iseq
32
+ elsif !(matches = find_iseqs(ISEQS__, iseq_name)).empty?
33
+ # FIXME: do something if there is more than one
34
+ iseq = matches[0]
35
+ else
36
+ iseq = nil
37
+ end
38
+
39
+ if iseq
40
+ msg('Instruction sequence:')
41
+ %w(name source_container arg_block arg_opts arg_post_len arg_rest
42
+ arg_simple argc arity iseq_size local_size orig
43
+ ).each do |field|
44
+ msg("\t#{field}: %s" % iseq.send(field).inspect)
45
+ end
46
+ msg("\tsha1: #{iseq.sha1}")
47
+ if iseq.brkpts
48
+ if iseq.brkpts.empty?
49
+ msg("Breakpoints have been allocated, but none have been set.")
50
+ else
51
+ s = iseq.brkpts.size > 1 ? 's' : ''
52
+ msg("Breakpoint%s at offset%s: %s" % [s, s, iseq.brkpts.join(', ')])
53
+ end
54
+ else
55
+ msg("Breakpoints have not been allocated.")
56
+ end
57
+ else
58
+ mess = "Can't find instruction sequence"
59
+ mess += " for #{args.join(' ')}" unless args.empty?
60
+ errmsg mess
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ if __FILE__ == $0
67
+ # Demo it.
68
+ ISEQS__ = {}
69
+ SCRIPT_ISEQS__ = {}
70
+
71
+ require_relative '../../mock'
72
+ require_relative '../../subcmd'
73
+ name = File.basename(__FILE__, '.rb')
74
+
75
+ # FIXME: DRY the below code
76
+ dbgr, cmd = MockDebugger::setup('info')
77
+ subcommand = Trepan::Subcommand::InfoIseq.new(cmd)
78
+ testcmdMgr = Trepan::Subcmd.new(subcommand)
79
+
80
+ subcommand.run_show_bool
81
+ name = File.basename(__FILE__, '.rb')
82
+ subcommand.summary_help(name)
83
+ end
@@ -0,0 +1,88 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'columnize'
4
+ require_relative '../base/subcmd'
5
+ require_relative '../../../app/frame'
6
+
7
+ class Trepan::Subcommand::InfoLocals < Trepan::Subcommand
8
+ unless defined?(HELP)
9
+ HELP = 'Show local variables of the current stack frame'
10
+ MAX_ARGS = 1
11
+ MIN_ABBREV = 'lo'.size
12
+ NAME = File.basename(__FILE__, '.rb')
13
+ NEED_STACK = true
14
+ PREFIX = %w(info locals)
15
+ end
16
+
17
+ include Trepan::Frame
18
+ def get_local_names
19
+ iseq = @proc.frame.iseq
20
+ 0.upto(iseq.local_size-2).map do
21
+ |i|
22
+ iseq.local_name(i)
23
+ end
24
+ end
25
+
26
+ def run(args)
27
+ if args.size == 3
28
+ if 0 == 'names'.index(args[-1].downcase)
29
+ if 'CFUNC' == @proc.frame.type
30
+ errmsg('info local names not supported for C frames')
31
+ else
32
+ local_names = get_local_names()
33
+ if local_names.empty?
34
+ msg "No local variables defined."
35
+ else
36
+ msg "Local variable names:"
37
+ width = settings[:maxwidth]
38
+ mess = Columnize::columnize(local_names,
39
+ @proc.settings[:maxwidth], ', ',
40
+ false, true, ' ' * 2).chomp
41
+ msg mess
42
+ end
43
+ end
44
+ else
45
+ errmsg("unrecognized argument #{args[2]}")
46
+ end
47
+ elsif args.size == 2
48
+ if 'CFUNC' == @proc.frame.type
49
+ argc = @proc.frame.argc
50
+ if argc > 0
51
+ 1.upto(argc).each do |i|
52
+ msg "#{i}: #{@proc.frame.sp(argc-i+3).inspect}"
53
+ end
54
+ else
55
+ msg("No parameters in C call; showing other C locals is not supported.")
56
+ end
57
+ else
58
+ local_names = get_local_names
59
+ if local_names.empty?
60
+ msg "No local variables defined."
61
+ else
62
+ msg "Local variables:"
63
+ get_local_names.each_with_index do |var_name, i|
64
+ var_value = @proc.safe_rep(@proc.debug_eval_no_errmsg(var_name).inspect)
65
+ msg("#{var_name} = #{var_value}")
66
+ end
67
+ end
68
+ end
69
+ else
70
+ errmsg("Wrong number of arguments #{args.size}")
71
+ end
72
+ end
73
+ end
74
+
75
+ if __FILE__ == $0
76
+ # Demo it.
77
+ require_relative '../../mock'
78
+ require_relative '../../subcmd'
79
+ name = File.basename(__FILE__, '.rb')
80
+
81
+ # FIXME: DRY the below code
82
+ dbgr, cmd = MockDebugger::setup('info')
83
+ subcommand = Trepan::Subcommand::InfoLocals.new(cmd)
84
+ testcmdMgr = Trepan::Subcmd.new(subcommand)
85
+
86
+ name = File.basename(__FILE__, '.rb')
87
+ subcommand.summary_help(name)
88
+ end
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../base/subcmd'
4
+
5
+ class Trepan::Subcommand::InfoProgram < Trepan::Subcommand
6
+ unless defined?(HELP)
7
+ HELP = 'Information about debugged program and its environment'
8
+ MIN_ABBREV = 'pr'.size
9
+ NAME = File.basename(__FILE__, '.rb')
10
+ NEED_STACK = true
11
+ PREFIX = %w(info program)
12
+ end
13
+
14
+ def run(args)
15
+ frame = @proc.frame
16
+ m = 'Program stop event: %s' % @proc.event
17
+ m +=
18
+ if frame.iseq
19
+ '; PC offset %d of instruction sequence: %s' %
20
+ [frame.pc_offset, frame.iseq.name]
21
+ else
22
+ '.'
23
+ end
24
+ msg m
25
+ if 'return' == @proc.event
26
+ msg 'R=> %s' % @proc.frame.sp(1).inspect
27
+ elsif 'raise' == @proc.event
28
+ msg @proc.core.hook_arg.inspect if @proc.core.hook_arg
29
+ end
30
+
31
+ if @proc.brkpt
32
+ msg('It is stopped at %sbreakpoint %d.' %
33
+ [@proc.brkpt.temp? ? 'temporary ' : '',
34
+ @proc.brkpt.id])
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ if __FILE__ == $0
41
+ # Demo it.
42
+ require_relative '../../mock'
43
+ name = File.basename(__FILE__, '.rb')
44
+
45
+ # FIXME: DRY the below code
46
+ dbgr, cmd = MockDebugger::setup('info')
47
+ subcommand = Trepan::Subcommand::InfoProgram.new(cmd)
48
+ testcmdMgr = Trepan::Subcmd.new(subcommand)
49
+
50
+ name = File.basename(__FILE__, '.rb')
51
+ subcommand.run([name])
52
+ subcommand.summary_help(name)
53
+ puts
54
+ end