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,182 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative 'subcmd'
4
+ require_relative '../../subcmd'
5
+ require_relative '../../help'
6
+
7
+ class Trepan::SubSubcommandMgr < Trepan::Subcommand
8
+
9
+ include Trepan::Help
10
+
11
+ unless defined?(CATEGORY)
12
+ CATEGORY = 'status'
13
+ MIN_ARGS = 0
14
+ MAX_ARGS = nil
15
+ NAME = '?' # FIXME: Need to define this, but should
16
+ # pick this up from class/file name.
17
+ NEED_STACK = false
18
+ end
19
+
20
+ attr_accessor :pname
21
+ attr_accessor :subcmds # Array of instantiated Trepan::Subcommand objects
22
+
23
+ # Initialize show subcommands. Note: instance variable name
24
+ # has to be setcmds ('set' + 'cmds') for subcommand completion
25
+ # to work.
26
+ # FIXME: do we need proc still?
27
+ def initialize(proc, parent)
28
+ name = obj_const(self, :NAME)
29
+ @name = name.to_sym
30
+ @subcmds = Trepan::Subcmd.new(self)
31
+ @parent = parent
32
+ @pname = parent.name
33
+ @proc = parent.proc
34
+
35
+ # Set class constant SHORT_HELP to be the first line of HELP
36
+ # unless it has been defined in the class already.
37
+ # The below was the simplest way I could find to do this since
38
+ # we are the super class but want to set the subclass's constant.
39
+ # defined? didn't seem to work here.
40
+ c = self.class.constants
41
+ self.class.const_set('SHORT_HELP',
42
+ self.class.const_get('HELP')) if
43
+ c.member?(:HELP) and !c.member?(:SHORT_HELP)
44
+
45
+ load_debugger_subsubcommands(name, self)
46
+ end
47
+
48
+ # Create an instance of each of the debugger subcommands. Commands
49
+ # are found by importing files in the directory 'name' + 'sub'. Some
50
+ # files are excluded via an array set in initialize. For each of
51
+ # the remaining files, we import them and scan for class names
52
+ # inside those files and for each class name, we will create an
53
+ # instance of that class. The set of TrepanCommand class instances
54
+ # form set of possible debugger commands.
55
+ def load_debugger_subsubcommands(name, obj)
56
+
57
+ # Initialization
58
+ cmd_names = []
59
+ cmd_dir = File.dirname(__FILE__)
60
+ subcmd_dir = File.join(cmd_dir, '..', @pname + '_subcmd', name + '_subcmd')
61
+ files = Dir.glob(File.join(subcmd_dir, '*.rb'))
62
+ files.each do |rb|
63
+ cmd_names << name.capitalize + File.basename(rb, '.rb').capitalize
64
+ require rb
65
+ end if File.directory?(subcmd_dir)
66
+
67
+ subcommands = {}
68
+ cmd_names.each do |subname|
69
+ cmd_name = "#{pname}#{subname.downcase}"
70
+ subclass_name = "#{@pname.capitalize}#{subname}"
71
+ next unless
72
+ Trepan::SubSubcommand.constants.member?(subclass_name.to_sym)
73
+ cmd = self.instance_eval("Trepan::SubSubcommand::" + subclass_name +
74
+ ".new(self, @parent, '#{cmd_name}')")
75
+ @subcmds.add(cmd, cmd_name)
76
+ end
77
+ end
78
+
79
+ # Give help for a command which has subcommands. This can be
80
+ # called in several ways:
81
+ # help cmd
82
+ # help cmd subcmd
83
+ # help cmd commands
84
+ #
85
+ # Our shtick is to give help for the overall command only if
86
+ # subcommand or 'commands' is not given. If a subcommand is given and
87
+ # found, then specific help for that is given. If 'commands' is given
88
+ # we will list the all the subcommands.
89
+ def help(args)
90
+ if args.size <= 3
91
+ # "help cmd". Give the general help for the command part.
92
+ doc = self.class.const_get(:HELP)
93
+ if doc
94
+ return doc
95
+ else
96
+ errmsg('Sorry - author mess up. ' +
97
+ 'No help registered for command' +
98
+ @name)
99
+ return nil
100
+ end
101
+ end
102
+
103
+ prefix = my_const(:PREFIX)
104
+ subcmd_name = args[prefix.size+1]
105
+ prefix_str = prefix.join(' ')
106
+
107
+ if '*' == subcmd_name
108
+ help_text = ["List of subcommands for '%s':" % prefix_str]
109
+ cmd_names = @subcmds.list.map{|c| c[prefix_str.size-1..-1]}
110
+ help_text << columnize_commands(cmd_names)
111
+ return help_text
112
+ end
113
+
114
+ # "help cmd subcmd". Give help specific for that subcommand if
115
+ # the command matches uniquely, or show a list of matching
116
+ # subcommands
117
+ keyprefix_str = prefix.join('')
118
+ key_str = keyprefix_str + subcmd_name
119
+ cmd = @subcmds.lookup(key_str, false)
120
+ if cmd
121
+ doc = obj_const(cmd, :HELP)
122
+ if doc
123
+ return doc
124
+ else
125
+ errmsg('Sorry - author mess up. ' +
126
+ 'No help registered for subcommand: ' +
127
+ subcmd_name + ', of command: ' +
128
+ @name)
129
+ return nil
130
+ end
131
+ else
132
+ matches = @subcmds.list.grep(/^#{key_str}/).sort
133
+ if matches.empty?
134
+ errmsg("No #{name} subcommands found matching /^#{subcmd_name}/. Try \"help #{@name}\".")
135
+ return nil
136
+ elsif 1 == matches.size
137
+ args[-1] = matches[0].to_s[keyprefix_str.size..-1]
138
+ help(args)
139
+ else
140
+ help_text = ["Subcommands of \"#{@name}\" matching /^#{subcmd_name}/:"]
141
+ help_text << columnize_commands(matches.sort)
142
+ return help_text
143
+ end
144
+ end
145
+ end
146
+
147
+ def run(args)
148
+ args = @parent.last_args if args.size == 0
149
+ if args.size < 3 || args.size == 3 && args[-1] == '*'
150
+ summary_list(obj_const(self, :NAME), @subcmds)
151
+ return false
152
+ end
153
+
154
+ subcmd_prefix = args[0..2].join('')
155
+ # We were given: cmd subcmd ...
156
+ # Run that.
157
+ subcmd = @subcmds.lookup(subcmd_prefix)
158
+ if subcmd
159
+ subcmd.run(args[2..-1])
160
+ else
161
+ undefined_subcmd(obj_const(self, :PREFIX).join(' '), args[-1])
162
+ end
163
+ end
164
+
165
+ end
166
+
167
+ if __FILE__ == $0
168
+ # Demo it.
169
+ require_relative '../../mock'
170
+ dbgr = MockDebugger::MockDebugger.new
171
+ cmds = dbgr.core.processor.commands
172
+ cmd = cmds['info']
173
+ Trepan::SubSubcommandMgr.new(dbgr.core.processor, cmd)
174
+ puts cmd.help(%w(help info registers))
175
+ puts '=' * 40
176
+ puts cmd.help(%w(help info registers *))
177
+ puts '=' * 40
178
+ # FIXME
179
+ # require_relative '../../lib/trepanning'
180
+ # Trepan.debug(:set_restart => true)
181
+ # puts cmd.help(%w(help info registers p.*))
182
+ end
@@ -0,0 +1,85 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require_relative 'base/cmd'
3
+ require_relative '../breakpoint'
4
+ require_relative '../../app/breakpoint'
5
+ class Trepan::Command::BreakCommand < Trepan::Command
6
+
7
+ unless defined?(HELP)
8
+ HELP =
9
+ 'break [line number|offset]
10
+
11
+ With a line number argument, set a break there in the current
12
+ instruction sequence. With an offset (a number prefaced with an "O")
13
+ set a breakpoint at that instruction offset.
14
+
15
+ Examples:
16
+ break
17
+ break 10 # set breakpoint on line 10
18
+ break o20 # set breakpoint VM Instruction Sequence offset 20
19
+ '
20
+
21
+ ALIASES = %w(b)
22
+ CATEGORY = 'breakpoints'
23
+ NAME = File.basename(__FILE__, '.rb')
24
+ SHORT_HELP = 'Set a breakpoint'
25
+ end
26
+
27
+ # This method runs the command
28
+ def run(args) # :nodoc
29
+ # FIXME: handle more conditions
30
+ # a line number
31
+ if args.size == 1
32
+ # usage is "break" which means break right here
33
+ # FIXME: should handle condition
34
+ bp = @proc.breakpoint_offset(@proc.frame.pc_offset,
35
+ @proc.frame.iseq)
36
+ else
37
+ position, iseq, use_offset, condition, name =
38
+ @proc.breakpoint_position(args[1..-1])
39
+ return false unless position && iseq
40
+ bp =
41
+ if use_offset
42
+ @proc.breakpoint_offset(position, iseq)
43
+ else
44
+ @proc.breakpoint_line(position, iseq)
45
+ end
46
+ end
47
+ if bp
48
+ bp.condition = condition
49
+
50
+ mess = "Breakpoint %d set at " % bp.id
51
+
52
+ line_loc = "line %s in %s" %
53
+ [bp.source_location.join(', '),
54
+ @proc.canonic_container(bp.iseq.source_container).join(' ')]
55
+
56
+ vm_loc = "VM offset %d of instruction sequence \"%s\"" %
57
+ [bp.offset, bp.iseq.name]
58
+
59
+ loc, other_loc =
60
+ if 'line' == bp.type
61
+ [line_loc, vm_loc]
62
+ else # 'offset' == bp.type
63
+ [vm_loc, line_loc]
64
+ end
65
+ msg(mess + loc + ",\n\t" + other_loc + ".")
66
+ end
67
+ end
68
+ end
69
+
70
+ if __FILE__ == $0
71
+ require_relative '../mock'
72
+ name = File.basename(__FILE__, '.rb')
73
+ dbgr, cmd = MockDebugger::setup(name)
74
+ cmd.run([name])
75
+ cmd.run([name, __LINE__.to_s])
76
+ require 'thread_frame'
77
+ tf = RubyVM::ThreadFrame.current
78
+ pc_offset = tf.pc_offset
79
+ cmd.run([name, "O#{pc_offset}"])
80
+ def foo
81
+ 5
82
+ end
83
+ cmd.run([name, 'foo', (__LINE__-2).to_s])
84
+ cmd.run([name, 'foo'])
85
+ end
@@ -0,0 +1,64 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative 'base/cmd'
4
+ require_relative '../breakpoint'
5
+ require_relative '../../app/breakpoint'
6
+ require_relative '../../app/condition'
7
+
8
+ class Trepan::Command::ConditionCommand < Trepan::Command
9
+
10
+ unless defined?(HELP)
11
+ HELP =
12
+ 'condition BP_NUMBER CONDITION
13
+
14
+ BP_NUMBER is a breakpoint number. CONDITION is an expression which
15
+ must evaluate to True before the breakpoint is honored. If CONDITION
16
+ is absent, any existing condition is removed; i.e., the breakpoint is
17
+ made unconditional.
18
+
19
+ Examples:
20
+ condition 5 x > 10 # Breakpoint 5 now has condition x > 10
21
+ condition 5 # Remove above condition
22
+ '
23
+
24
+ ALIASES = %w(cond)
25
+ CATEGORY = 'breakpoints'
26
+ MIN_ARGS = 1
27
+ NAME = File.basename(__FILE__, '.rb')
28
+ NEED_STACK = false
29
+ SHORT_HELP = 'Specify breakpoint number N to break only if COND is true'
30
+ end
31
+
32
+ include Trepan::Condition
33
+
34
+ def run(args)
35
+ bpnum = @proc.get_an_int(args[1])
36
+ bp = @proc.breakpoint_find(bpnum)
37
+ return unless bp
38
+
39
+ if args.size > 2
40
+ condition = args[2..-1].join(' ')
41
+ return unless valid_condition?(condition)
42
+ else
43
+ condition = 'true'
44
+ msg('Breakpoint %d is now unconditional.' % bp.id)
45
+ end
46
+ bp.condition = condition
47
+ end
48
+ end
49
+
50
+ if __FILE__ == $0
51
+ require 'thread_frame'
52
+ require_relative '../mock'
53
+ name = File.basename(__FILE__, '.rb')
54
+ dbgr, cmd = MockDebugger::setup(name)
55
+ cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
56
+
57
+ cmd.run([name, '1'])
58
+ cmdproc = dbgr.core.processor
59
+ cmds = cmdproc.commands
60
+ break_cmd = cmds['break']
61
+ break_cmd.run(['break', cmdproc.frame.source_location[0].to_s])
62
+ cmd.run([name, '1', 'x' '>' '10'])
63
+ cmd.run([name, '1'])
64
+ end
@@ -0,0 +1,61 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require_relative 'base/cmd'
3
+ require_relative '../running'
4
+ require_relative '../../app/breakpoint' # FIXME: possibly temporary
5
+ class Trepan::Command::ContinueCommand < Trepan::Command
6
+
7
+ unless defined?(HELP)
8
+ HELP =
9
+ 'continue [offset|line number]
10
+
11
+ Leave the debugger loop and continue execution. Subsequent entry to
12
+ the debugger however may occur via breakpoints or explicit calls, or
13
+ exceptions.
14
+
15
+ If a parameter is given, a temporary breakpoint is set at that position
16
+ before continuing. Offset are numbers preficed with an "O" otherwise
17
+ the parameter is taken as a line number.
18
+
19
+ Examples:
20
+ continue
21
+ continue 10 # continue to line 10
22
+ continue o20 # continue to VM Instruction Sequence offset 20
23
+ '
24
+
25
+ ALIASES = %w(c)
26
+ CATEGORY = 'running'
27
+ MAX_ARGS = 1 # Need at most this many
28
+ NAME = File.basename(__FILE__, '.rb')
29
+ NEED_RUNNING = true
30
+ SHORT_HELP = 'Continue execution of debugged program'
31
+ end
32
+
33
+ # This method runs the command
34
+ def run(args) # :nodoc
35
+ if args.size == 1
36
+ # Form is: "continue"
37
+ @proc.continue
38
+ else
39
+ # FIXME: handle more general condition parameter rather than just
40
+ # a line number
41
+ position, iseq, use_offset, condition =
42
+ @proc.breakpoint_position(args[1..-1])
43
+ return false unless position && iseq
44
+ bp =
45
+ if use_offset
46
+ @proc.breakpoint_offset(position, iseq, true)
47
+ else
48
+ @proc.breakpoint_line(position, iseq, true)
49
+ end
50
+ return unless bp
51
+ @proc.continue
52
+ end
53
+ end
54
+ end
55
+
56
+ if __FILE__ == $0
57
+ require_relative '../mock'
58
+ name = File.basename(__FILE__, '.rb')
59
+ dbgr, cmd = MockDebugger::setup(name)
60
+ p cmd.run([name])
61
+ end
@@ -0,0 +1,85 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'thread_frame'
4
+ require_relative 'base/cmd'
5
+
6
+ class Trepan::Command::DebugCommand < Trepan::Command
7
+ unless defined?(HELP)
8
+ HELP =
9
+ "debug RUBY-CODE
10
+
11
+ Enter the debugger recursively on RUBY-CODE."
12
+
13
+ CATEGORY = 'data'
14
+ MIN_ARGS = 1
15
+ MAX_ARG = nil
16
+ NAME = File.basename(__FILE__, '.rb')
17
+ NEED_STACK = false
18
+ SHORT_HELP = 'recursive debugging of an expression'
19
+
20
+ EXTRA_DEBUG_SETUP_CALLS = 4
21
+ end
22
+
23
+ def run(args)
24
+ th = Thread.current
25
+ frame = @proc.frame # gets messed up in recursive call
26
+ arg_str = args[1..-1].join(' ')
27
+ hidelevels = @proc.hidelevels[th]
28
+
29
+ stack_diff = RubyVM::ThreadFrame.current.stack_size - frame.stack_size
30
+
31
+ # Ignore tracing in support routines:
32
+ tf = @proc.dbgr.trace_filter
33
+ [self.method(:run), @proc.method(:debug_eval),
34
+ @proc.method(:debug_eval_with_exception),
35
+ @proc.method(:get_binding_and_filename),
36
+ @proc.method(:fake_eval_filename)].each do |m|
37
+ tf << m unless tf.member?(m)
38
+ end
39
+
40
+ @proc.hidelevels[th] += stack_diff + EXTRA_DEBUG_SETUP_CALLS
41
+
42
+ # Values we need to save before munging them
43
+ old_tracing = th.tracing
44
+ old_exec_event_tracing = th.exec_event_tracing
45
+ old_mutex = @proc.core.mutex
46
+ old_next_level = @proc.next_level
47
+ old_step_count = @proc.core.step_count
48
+
49
+ msg 'ENTERING NESTED DEBUGGER'
50
+
51
+ # Things we need to do to allow entering the debugger again
52
+ @proc.debug_nest += 1
53
+ @proc.core.mutex = Mutex.new
54
+ th.tracing = false
55
+ th.exec_event_tracing = false
56
+ @proc.core.step_count = 0
57
+ @proc.next_level = 32000
58
+
59
+ RubyVM::ThreadFrame.current.trace_off = false
60
+ retval = @proc.debug_eval(arg_str)
61
+
62
+ # Restore munged values
63
+ th.exec_event_tracing = old_exec_event_tracing
64
+ th.tracing = old_tracing
65
+ @proc.core.mutex = old_mutex
66
+ @proc.frame_setup(frame)
67
+ @proc.hidelevels[th] = hidelevels
68
+ @proc.core.step_count = old_step_count
69
+ @proc.next_level = old_next_level
70
+ @proc.print_location
71
+ @proc.debug_nest -= 1
72
+ msg 'LEAVING NESTED DEBUGGER'
73
+ msg "R=> #{retval.inspect}"
74
+ end
75
+ end
76
+
77
+ if __FILE__ == $0
78
+ require_relative '../mock'
79
+ name = File.basename(__FILE__, '.rb')
80
+ dbgr, cmd = MockDebugger::setup(name)
81
+ name = File.basename(__FILE__, '.rb')
82
+ cmd.proc.hidelevels[Thread.current] = 0
83
+ cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
84
+ cmd.run([name, 'x = 1; y = 2'])
85
+ end
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative 'base/cmd'
4
+ require_relative '../breakpoint'
5
+ require_relative '../../app/breakpoint'
6
+ class Trepan::Command::DeleteCommand < Trepan::Command
7
+
8
+ unless defined?(HELP)
9
+ HELP =
10
+ 'delete [bpnumber [bpnumber...]] - Delete some breakpoints.
11
+
12
+ Arguments are breakpoint numbers with spaces in between. To delete
13
+ all breakpoints, give no argument. those breakpoints. Without
14
+ argument, clear all breaks (but first ask confirmation).
15
+
16
+ See also the "clear" command which clears breakpoints by line/file
17
+ number.
18
+ '
19
+
20
+ CATEGORY = 'breakpoints'
21
+ NAME = File.basename(__FILE__, '.rb')
22
+ SHORT_HELP = 'Delete some breakpoints'
23
+ end
24
+
25
+ def run(args)
26
+ if args.size == 1
27
+ if confirm('Delete all breakpoints?', false)
28
+ @proc.brkpts.reset
29
+ return
30
+ end
31
+ end
32
+ first = args.shift
33
+ args.each do |num_str|
34
+ i = @proc.get_an_int(num_str)
35
+ success = @proc.delete_breakpoint_by_number(num_str.to_i, false) if i
36
+ msg('Deleted breakpoint %d.' % i) if success
37
+ end
38
+ end
39
+ end
40
+
41
+ if __FILE__ == $0
42
+ require_relative '../mock'
43
+ name = File.basename(__FILE__, '.rb')
44
+ dbgr, cmd = MockDebugger::setup(name)
45
+ cmd.run([name])
46
+ cmd.run([name, '1'])
47
+ cmdproc = dbgr.core.processor
48
+ cmds = dbgr.core.processor.commands
49
+ break_cmd = cmds['break']
50
+ break_cmd.run(['break', cmdproc.frame.source_location[0].to_s])
51
+ # require_relative '../../lib/trepanning'
52
+ # Trepan.debug(:set_restart => true)
53
+ cmd.run([name, '1'])
54
+ end
@@ -0,0 +1,43 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require_relative 'base/cmd'
3
+ class Trepan::Command::DirectoryCommand < Trepan::Command
4
+
5
+ unless defined?(HELP)
6
+ ALIASES = %w(dir)
7
+ CATEGORY = 'files'
8
+ MAX_ARGS = 1 # Need at most this many
9
+ NAME = File.basename(__FILE__, '.rb')
10
+ HELP = <<-HELP
11
+ Add directory DIR to beginning of search path for source files.
12
+ DIR can also be $cwd for the current working directory, or $cdir for the
13
+ directory in which the debugged file start.
14
+ With no argument, reset the search path to $cdir:$cwd, the default.
15
+
16
+ This command may be useful for debugging into Rubinius methods such as
17
+ kernel/common/module.rb if have the source code somewhere.
18
+ HELP
19
+ SHORT_HELP =
20
+ 'Add directory DIR to beginning of search path for source files'
21
+ end
22
+
23
+ # This method runs the command
24
+ def run(args) # :nodoc
25
+ if args.size > 1
26
+ settings[:directory] = "#{args[1]}:#{settings[:directory]}"
27
+ msg "Source directories searched: #{settings[:directory]}"
28
+ else
29
+ if confirm('Reintialize source path to empty?', false)
30
+ settings[:directory] = '$cdir:$cwd'
31
+ msg 'Source directories searched: $cdir:$cwd'
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ if __FILE__ == $0
38
+ require_relative '../mock'
39
+ name = File.basename(__FILE__, '.rb')
40
+ dbgr, cmd = MockDebugger::setup(name)
41
+ cmd.run([name])
42
+ cmd.run([name, '/tmp'])
43
+ end
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative 'base/cmd'
4
+ require_relative '../breakpoint'
5
+ require_relative '../../app/breakpoint'
6
+
7
+ # disable breakpoint command. The difference however is that the
8
+ # parameter to @proc.en_disable_breakpoint_by_number is different (set
9
+ # as ENABLE_PARM below).
10
+ #
11
+ # NOTE: The enable command subclasses this, so beware when changing!
12
+ class Trepan::Command::DisableCommand < Trepan::Command
13
+
14
+ # Silence already initialized constant .. warnings
15
+ old_verbose = $VERBOSE
16
+ $VERBOSE = nil
17
+ HELP =
18
+ 'disable [display] bpnumber [bpnumber ...]
19
+
20
+ Disables the breakpoints given as a space separated list of breakpoint
21
+ numbers. See also "info break" to get a list.
22
+ '
23
+
24
+ CATEGORY = 'breakpoints'
25
+ NAME = File.basename(__FILE__, '.rb')
26
+ SHORT_HELP = 'Disable some breakpoints'
27
+
28
+ $VERBOSE = old_verbose
29
+
30
+ def initialize(proc)
31
+ super
32
+ @enable_parm = false # true if enable
33
+ end
34
+
35
+ def run(args)
36
+ if args.size == 1
37
+ errmsg('No breakpoint number given.')
38
+ return
39
+ end
40
+ # if args[1] == 'display'
41
+ # display_enable(args[2:], 0)
42
+ # end
43
+ first = args.shift
44
+ args.each do |num_str|
45
+ i = @proc.get_an_int(num_str)
46
+ success = @proc.en_disable_breakpoint_by_number(i, @enable_parm) if i
47
+ msg("Breakpoint %s #{@name}d." % i) if success
48
+ end
49
+ end
50
+ end
51
+
52
+ if __FILE__ == $0
53
+ require_relative '../mock'
54
+ name = File.basename(__FILE__, '.rb')
55
+ dbgr, cmd = MockDebugger::setup(name)
56
+ cmd.run([name])
57
+ cmd.run([name, '1'])
58
+ cmdproc = dbgr.core.processor
59
+ cmds = cmdproc.commands
60
+ break_cmd = cmds['break']
61
+ break_cmd.run(['break', cmdproc.frame.source_location[0].to_s])
62
+ # require_relative '../../lib/trepanning'
63
+ # Trepan.debug(:set_restart => true)
64
+ cmd.run([name, '1'])
65
+ end