rbx-trepanning 0.0.2-universal-rubinius-1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. data/ChangeLog +376 -0
  2. data/LICENSE +25 -0
  3. data/NEWS +2 -0
  4. data/README.textile +35 -0
  5. data/Rakefile +165 -0
  6. data/THANKS +14 -0
  7. data/app/breakpoint.rb +218 -0
  8. data/app/breakpoint.rbc +3564 -0
  9. data/app/brkptmgr.rb +138 -0
  10. data/app/brkptmgr.rbc +2827 -0
  11. data/app/default.rb +61 -0
  12. data/app/default.rbc +1011 -0
  13. data/app/display.rb +35 -0
  14. data/app/display.rbc +968 -0
  15. data/app/frame.rb +98 -0
  16. data/app/frame.rbc +1808 -0
  17. data/app/irb.rb +112 -0
  18. data/app/irb.rbc +2111 -0
  19. data/app/iseq.rb +95 -0
  20. data/app/iseq.rbc +1801 -0
  21. data/app/method.rb +173 -0
  22. data/app/method.rbc +2492 -0
  23. data/app/mock.rb +13 -0
  24. data/app/mock.rbc +398 -0
  25. data/app/options.rb +123 -0
  26. data/app/options.rbc +2183 -0
  27. data/app/run.rb +86 -0
  28. data/app/run.rbc +1244 -0
  29. data/app/util.rb +49 -0
  30. data/app/util.rbc +1144 -0
  31. data/app/validate.rb +30 -0
  32. data/app/validate.rbc +676 -0
  33. data/bin/trepan.compiled.rbc +1043 -0
  34. data/bin/trepanx +63 -0
  35. data/bin/trepanx.compiled.rbc +985 -0
  36. data/interface/base_intf.rb +95 -0
  37. data/interface/base_intf.rbc +1742 -0
  38. data/interface/script.rb +104 -0
  39. data/interface/script.rbc +1642 -0
  40. data/interface/user.rb +91 -0
  41. data/interface/user.rbc +1418 -0
  42. data/io/base_io.rb +94 -0
  43. data/io/base_io.rbc +1404 -0
  44. data/io/input.rb +112 -0
  45. data/io/input.rbc +1979 -0
  46. data/io/null_output.rb +42 -0
  47. data/io/null_output.rbc +730 -0
  48. data/io/string_array.rb +156 -0
  49. data/io/string_array.rbc +2466 -0
  50. data/lib/trepanning.rb +398 -0
  51. data/lib/trepanning.rbc +6661 -0
  52. data/processor/breakpoint.rb +161 -0
  53. data/processor/command/alias.rb +55 -0
  54. data/processor/command/backtrace.rb +46 -0
  55. data/processor/command/base/cmd.rb +124 -0
  56. data/processor/command/base/subcmd.rb +213 -0
  57. data/processor/command/base/submgr.rb +179 -0
  58. data/processor/command/base/subsubcmd.rb +103 -0
  59. data/processor/command/base/subsubmgr.rb +184 -0
  60. data/processor/command/break.rb +100 -0
  61. data/processor/command/continue.rb +82 -0
  62. data/processor/command/delete.rb +30 -0
  63. data/processor/command/directory.rb +43 -0
  64. data/processor/command/disassemble.rb +103 -0
  65. data/processor/command/down.rb +54 -0
  66. data/processor/command/eval.rb +31 -0
  67. data/processor/command/exit.rb +58 -0
  68. data/processor/command/finish.rb +78 -0
  69. data/processor/command/frame.rb +89 -0
  70. data/processor/command/help.rb +146 -0
  71. data/processor/command/info.rb +28 -0
  72. data/processor/command/info_subcmd/breakpoints.rb +75 -0
  73. data/processor/command/info_subcmd/file.rb +153 -0
  74. data/processor/command/info_subcmd/method.rb +71 -0
  75. data/processor/command/info_subcmd/program.rb +59 -0
  76. data/processor/command/info_subcmd/variables.rb +40 -0
  77. data/processor/command/irb.rb +96 -0
  78. data/processor/command/kill.rb +70 -0
  79. data/processor/command/list.rb +296 -0
  80. data/processor/command/next.rb +66 -0
  81. data/processor/command/nexti.rb +59 -0
  82. data/processor/command/pr.rb +38 -0
  83. data/processor/command/ps.rb +40 -0
  84. data/processor/command/restart.rb +60 -0
  85. data/processor/command/set.rb +47 -0
  86. data/processor/command/set_subcmd/auto.rb +28 -0
  87. data/processor/command/set_subcmd/auto_subcmd/dis.rb +33 -0
  88. data/processor/command/set_subcmd/auto_subcmd/eval.rb +54 -0
  89. data/processor/command/set_subcmd/auto_subcmd/irb.rb +34 -0
  90. data/processor/command/set_subcmd/auto_subcmd/list.rb +34 -0
  91. data/processor/command/set_subcmd/basename.rb +26 -0
  92. data/processor/command/set_subcmd/debug.rb +27 -0
  93. data/processor/command/set_subcmd/debug_subcmd/dbgr.rb +36 -0
  94. data/processor/command/set_subcmd/debug_subcmd/skip.rb +23 -0
  95. data/processor/command/set_subcmd/debug_subcmd/step.rb +23 -0
  96. data/processor/command/set_subcmd/different.rb +60 -0
  97. data/processor/command/set_subcmd/hidelevel.rb +63 -0
  98. data/processor/command/set_subcmd/kernelstep.rb +61 -0
  99. data/processor/command/set_subcmd/max.rb +29 -0
  100. data/processor/command/set_subcmd/max_subcmd/list.rb +49 -0
  101. data/processor/command/set_subcmd/max_subcmd/stack.rb +50 -0
  102. data/processor/command/set_subcmd/max_subcmd/string.rb +54 -0
  103. data/processor/command/set_subcmd/max_subcmd/width.rb +49 -0
  104. data/processor/command/set_subcmd/substitute.rb +25 -0
  105. data/processor/command/set_subcmd/substitute_subcmd/path.rb +56 -0
  106. data/processor/command/set_subcmd/trace.rb +37 -0
  107. data/processor/command/set_subcmd/trace_subcmd/print.rb +57 -0
  108. data/processor/command/show.rb +27 -0
  109. data/processor/command/show_subcmd/alias.rb +43 -0
  110. data/processor/command/show_subcmd/args.rb +26 -0
  111. data/processor/command/show_subcmd/auto.rb +28 -0
  112. data/processor/command/show_subcmd/auto_subcmd/dis.rb +37 -0
  113. data/processor/command/show_subcmd/auto_subcmd/eval.rb +28 -0
  114. data/processor/command/show_subcmd/auto_subcmd/irb.rb +23 -0
  115. data/processor/command/show_subcmd/auto_subcmd/list.rb +22 -0
  116. data/processor/command/show_subcmd/basename.rb +22 -0
  117. data/processor/command/show_subcmd/debug.rb +27 -0
  118. data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +21 -0
  119. data/processor/command/show_subcmd/debug_subcmd/skip.rb +22 -0
  120. data/processor/command/show_subcmd/debug_subcmd/step.rb +22 -0
  121. data/processor/command/show_subcmd/different.rb +27 -0
  122. data/processor/command/show_subcmd/hidelevel.rb +42 -0
  123. data/processor/command/show_subcmd/kernelstep.rb +37 -0
  124. data/processor/command/show_subcmd/max.rb +30 -0
  125. data/processor/command/show_subcmd/max_subcmd/list.rb +38 -0
  126. data/processor/command/show_subcmd/max_subcmd/stack.rb +36 -0
  127. data/processor/command/show_subcmd/max_subcmd/string.rb +42 -0
  128. data/processor/command/show_subcmd/max_subcmd/width.rb +37 -0
  129. data/processor/command/show_subcmd/trace.rb +29 -0
  130. data/processor/command/show_subcmd/trace_subcmd/print.rb +38 -0
  131. data/processor/command/source.rb +83 -0
  132. data/processor/command/step.rb +49 -0
  133. data/processor/command/tbreak.rb +19 -0
  134. data/processor/command/unalias.rb +44 -0
  135. data/processor/command/up.rb +87 -0
  136. data/processor/default.rb +56 -0
  137. data/processor/disassemble.rb +32 -0
  138. data/processor/eval.rb +96 -0
  139. data/processor/frame.rb +211 -0
  140. data/processor/help.rb +72 -0
  141. data/processor/hook.rb +133 -0
  142. data/processor/load_cmds.rb +101 -0
  143. data/processor/location.rb +128 -0
  144. data/processor/main.rb +394 -0
  145. data/processor/mock.rb +137 -0
  146. data/processor/msg.rb +28 -0
  147. data/processor/running.rb +230 -0
  148. data/processor/stepping.rb +115 -0
  149. data/processor/subcmd.rb +160 -0
  150. data/processor/validate.rb +355 -0
  151. data/test/data/enable.right +36 -0
  152. data/test/data/fname-with-blank.cmd +6 -0
  153. data/test/data/fname-with-blank.right +1 -0
  154. data/test/data/quit-Xdebug.right +3 -0
  155. data/test/data/quit.cmd +5 -0
  156. data/test/data/quit.right +0 -0
  157. data/test/example/fname with blank.rb +1 -0
  158. data/test/example/gcd-xx.rb +18 -0
  159. data/test/example/gcd.rb +19 -0
  160. data/test/example/gcd1.rb +24 -0
  161. data/test/example/null.rb +1 -0
  162. data/test/example/thread1.rb +3 -0
  163. data/test/functional/fn_helper.rb +112 -0
  164. data/test/functional/test-break-name.rb +52 -0
  165. data/test/functional/test-break.rb +51 -0
  166. data/test/functional/test-finish.rb +70 -0
  167. data/test/functional/test-fn_helper.rb +43 -0
  168. data/test/functional/test-list.rb +55 -0
  169. data/test/functional/test-next-bug.rb +49 -0
  170. data/test/functional/test-next.rb +101 -0
  171. data/test/functional/test-step.rb +272 -0
  172. data/test/functional/test-step2.rb +35 -0
  173. data/test/functional/test-tbreak.rb +41 -0
  174. data/test/integration/file-diff.rb +89 -0
  175. data/test/integration/helper.rb +78 -0
  176. data/test/integration/test-fname-with-blank.rb +12 -0
  177. data/test/integration/test-quit.rb +25 -0
  178. data/test/unit/cmd-helper.rb +46 -0
  179. data/test/unit/test-app-brkpt.rb +30 -0
  180. data/test/unit/test-app-brkptmgr.rb +51 -0
  181. data/test/unit/test-app-iseq.rb +49 -0
  182. data/test/unit/test-app-method.rb +54 -0
  183. data/test/unit/test-app-options.rb +61 -0
  184. data/test/unit/test-app-run.rb +16 -0
  185. data/test/unit/test-app-util.rb +28 -0
  186. data/test/unit/test-app-validate.rb +18 -0
  187. data/test/unit/test-base-subcmd.rb +61 -0
  188. data/test/unit/test-bin-trepanx.rb +48 -0
  189. data/test/unit/test-cmd-alias.rb +49 -0
  190. data/test/unit/test-cmd-break.rb +23 -0
  191. data/test/unit/test-cmd-exit.rb +27 -0
  192. data/test/unit/test-cmd-help.rb +101 -0
  193. data/test/unit/test-cmd-kill.rb +48 -0
  194. data/test/unit/test-intf-user.rb +46 -0
  195. data/test/unit/test-io-input.rb +27 -0
  196. data/test/unit/test-proc-eval.rb +37 -0
  197. data/test/unit/test-proc-frame.rb +79 -0
  198. data/test/unit/test-proc-help.rb +16 -0
  199. data/test/unit/test-proc-hook.rb +30 -0
  200. data/test/unit/test-proc-load_cmds.rb +41 -0
  201. data/test/unit/test-proc-location.rb +48 -0
  202. data/test/unit/test-proc-main.rb +96 -0
  203. data/test/unit/test-proc-validate.rb +91 -0
  204. data/test/unit/test-subcmd-help.rb +51 -0
  205. metadata +337 -0
@@ -0,0 +1,128 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'rubygems'
3
+ require 'linecache'
4
+ require_relative 'disassemble'
5
+ require_relative 'msg'
6
+ require_relative 'frame'
7
+ class Trepan
8
+ class CmdProcessor
9
+ attr_accessor :reload_on_change
10
+
11
+ def location_initialize
12
+ @reload_on_change = nil
13
+ end
14
+
15
+ def resolve_file_with_dir(path_suffix)
16
+ settings[:directory].split(/:/).each do |dir|
17
+ dir =
18
+ if '$cwd' == dir
19
+ Dir.pwd
20
+ elsif '$cdir' == dir
21
+ Rubinius::OS_STARTUP_DIR
22
+ else
23
+ dir
24
+ end
25
+ next unless dir && File.directory?(dir)
26
+ try_file = File.join(dir, path_suffix)
27
+ return try_file if File.readable?(try_file)
28
+ end
29
+ nil
30
+ end
31
+
32
+ # Get line +line_number+ from file named +filename+. Return "\n"
33
+ # there was a problem. Leading blanks are stripped off.
34
+ def line_at(filename, line_number)
35
+ # We use linecache first to give precidence to user-remapped
36
+ # file names
37
+ line = LineCache::getline(filename, line_number, @reload_on_change)
38
+ unless line
39
+ # Try using search directories (set with command "directory")
40
+ if filename[0..0] != File::SEPARATOR
41
+ try_filename = resolve_file_with_dir(filename)
42
+ if try_filename &&
43
+ line = LineCache::getline(try_filename, line_number,
44
+ @reload_on_change)
45
+ LineCache::remap_file(filename, try_filename)
46
+ end
47
+ end
48
+ end
49
+ return nil unless line
50
+ return line.lstrip.chomp
51
+ end
52
+
53
+ def loc_and_text(loc)
54
+ vm_location = @frame.vm_location
55
+ filename = vm_location.method.active_path
56
+ line_no = vm_location.line
57
+ static = vm_location.static_scope
58
+
59
+ if @frame.eval?
60
+ file = LineCache::map_script(static.script)
61
+ text = LineCache::getline(static.script, line_no)
62
+ loc += " remapped #{canonic_file(file)}:#{line_no}"
63
+ else
64
+ text = line_at(filename, line_no)
65
+ map_file, map_line = LineCache::map_file_line(filename, line_no)
66
+ if [filename, line_no] != [map_file, map_line]
67
+ loc += " remapped #{canonic_file(map_file)}:#{map_line}"
68
+ end
69
+ end
70
+
71
+ [loc, line_no, text]
72
+ end
73
+
74
+ def print_location
75
+ # if %w(c-call call).member?(@event)
76
+ # # FIXME: Fix Ruby so we don't need this workaround?
77
+ # # See also where.rb
78
+ # opts = {}
79
+ # opts[:class] = @core.hook_arg if
80
+ # 'CFUNC' == @frame.type && @core.hook_arg && 0 == @frame_index
81
+ # msg format_stack_call(@frame, opts)
82
+ # elsif 'raise' == @core.event
83
+ # msg @core.hook_arg.inspect if @core.hook_arg # Exception object
84
+ # end
85
+
86
+ text = nil
87
+ # source_container = frame_container(@frame, false)
88
+ ev = if @event.nil? || 0 != @frame_index
89
+ ' '
90
+ else
91
+ (EVENT2ICON[@event] || @event)
92
+ end
93
+
94
+ @line_no = @frame.vm_location.line
95
+
96
+ loc = source_location_info
97
+ loc, @line_no, text = loc_and_text(loc)
98
+ ip_str = frame.method ? " @#{frame.next_ip}" : ''
99
+
100
+ msg "#{ev} (#{loc}#{ip_str})"
101
+
102
+ # if %w(return c-return).member?(@core.event)
103
+ # retval = Trepan::Frame.value_returned(@frame, @core.event)
104
+ # msg 'R=> %s' % retval.inspect
105
+ # end
106
+
107
+ if text && !text.strip.empty?
108
+ msg text
109
+ @line_no -= 1
110
+ else
111
+ show_bytecode
112
+ end
113
+ end
114
+
115
+ def source_location_info
116
+ filename = @frame.vm_location.method.active_path
117
+ canonic_filename =
118
+ if @frame.eval?
119
+ 'eval ' + safe_repr(@frame.eval_string.gsub("\n", ';').inspect, 20)
120
+ else
121
+ canonic_file(filename)
122
+ end
123
+ loc = "#{canonic_filename}:#{@frame.vm_location.line}"
124
+ return loc
125
+ end
126
+
127
+ end
128
+ end
data/processor/main.rb ADDED
@@ -0,0 +1,394 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # The main "driver" class for a command processor. Other parts of the
3
+ # command class and debugger command objects are pulled in from here.
4
+
5
+ require 'set'
6
+ require 'pathname' # For cleanpath
7
+
8
+ require 'rubygems'; require 'require_relative'
9
+ ## %w(default display eventbuf eval load_cmds location frame hook msg
10
+ ## validate).each do
11
+ %w(default breakpoint disassemble eval load_cmds location frame hook msg
12
+ running stepping validate).each do
13
+ |mod_str|
14
+ require_relative mod_str
15
+ end
16
+ ## require_relative '../app/brkptmgr'
17
+
18
+ class Trepan
19
+ class CmdProcessor
20
+
21
+ # SEE ALSO attr's in require_relative's of loop above.
22
+
23
+ attr_reader :cmd_name # command name before alias or macro resolution
24
+ attr_reader :cmd_argstr # Current command args, a String.
25
+ # This is current_command with the command
26
+ # name removed from the beginning.
27
+ ## attr_reader :core # Trepan core object
28
+ attr_reader :current_command # Current command getting run, a String.
29
+ attr_accessor :dbgr # Trepan instance (via
30
+ # Trepan::Core instance)
31
+ ## FIXME 1.9.2 has attr_reader !
32
+ attr_accessor :debug_nest # Number of nested debugs. Used in showing
33
+ # prompt.
34
+ attr_accessor :different_pos # Same type as settings[:different]
35
+ # this is the temporary value for the
36
+ # next stop while settings is the default
37
+ # value to use.
38
+ attr_accessor :event # Stop event
39
+ attr_accessor :leave_cmd_loop # Commands set this to signal to leave
40
+ # the command loop (which often continues to
41
+ # run the debugged program).
42
+ attr_accessor :line_no # Last line shown in "list" command
43
+ attr_accessor :next_thread # Thread. If non-nil then in
44
+ # stepping the thread has to be
45
+ # this thread.
46
+ attr_accessor :pass_exception # Pass an exception back
47
+ attr_accessor :prompt # String print before requesting input
48
+ attr_reader :settings # Hash[:symbol] of command
49
+ # processor settings
50
+ attr_reader :step_bp
51
+
52
+ # The following are used in to force stopping at a different line
53
+ # number. FIXME: could generalize to a position object.
54
+ attr_accessor :last_pos # Last position. 6-Tuple: of
55
+ # [location, container, stack_size,
56
+ # current_thread, pc_offset]
57
+
58
+
59
+ unless defined?(EVENT2ICON)
60
+ # Event icons used in printing locations.
61
+ EVENT2ICON = {
62
+ 'brkpt' => 'xx',
63
+ 'tbrkpt' => 'x1',
64
+ 'c-call' => 'C>',
65
+ 'c-return' => '<C',
66
+ 'step-call' => '->',
67
+ 'call' => '->',
68
+ 'class' => '::',
69
+ 'coverage' => '[]',
70
+ 'debugger-call' => ':o',
71
+ 'end' => '-|',
72
+ 'line' => '--',
73
+ 'raise' => '!!',
74
+ 'return' => '<-',
75
+ 'start' => '>>',
76
+ 'start' => '>>',
77
+ 'switch' => 'sw',
78
+ 'trace-var' => '$V',
79
+ 'unknown' => '?!',
80
+ 'vm' => 'VM',
81
+ 'vm-insn' => '..',
82
+ }
83
+ # These events are important enough event that we always want to
84
+ # stop on them.
85
+ UNMASKABLE_EVENTS = Set.new(['end', 'raise', 'unknown'])
86
+ end
87
+
88
+ def initialize(dbgr, settings={})
89
+ @dbgr = dbgr
90
+ @debug_nest = 1
91
+ @hidelevels = {}
92
+ @last_command = nil
93
+ @last_pos = [nil, nil, nil, nil, nil, nil]
94
+ @next_thread = nil
95
+ @user_variables = 0
96
+
97
+
98
+ start_cmds = settings.delete(:start_cmds)
99
+ start_file = settings.delete(:start_file)
100
+
101
+ @settings = settings.merge(DEFAULT_SETTINGS)
102
+ @different_pos = @settings[:different]
103
+
104
+ # FIXME: Rework using a general "set substitute file" command and
105
+ # a global default profile which gets read.
106
+ prelude_file = File.expand_path(File.join(File.dirname(__FILE__),
107
+ %w(.. data prelude.rb)))
108
+
109
+ ## Start with empty thread and frame info.
110
+ frame_teardown
111
+
112
+ # Run initialization routines for each of the "submodule"s.
113
+ # load_cmds has to come first.
114
+ ## %w(load_cmds breakpoint display eventbuf frame running validate
115
+ ## ).each do |submod|
116
+ %w(load_cmds breakpoint frame running validate).each do |submod|
117
+ self.send("#{submod}_initialize")
118
+ end
119
+ hook_initialize(commands)
120
+ end
121
+
122
+ def canonic_container(container)
123
+ [container[0], canonic_file(container[1])]
124
+ end
125
+
126
+ def canonic_file(filename)
127
+ # For now we want resolved filenames
128
+ @settings[:basename] ? File.basename(filename) :
129
+ # Cache this?
130
+ Pathname.new(filename).cleanpath.to_s
131
+ end
132
+
133
+ def compute_prompt
134
+ th = @current_thread
135
+ thread_str =
136
+ if 2 == Thread.list.size
137
+ ''
138
+ elsif th == Thread.main
139
+ '@main'
140
+ else
141
+ "@#{th.current.object_id}"
142
+ end
143
+ "%s#{settings[:prompt]}%s%s: " %
144
+ ['(' * @debug_nest, thread_str, ')' * @debug_nest]
145
+
146
+ end
147
+
148
+ # Check that we meed the criteria that cmd specifies it needs
149
+ def ok_for_running(cmd, name, nargs)
150
+ # TODO check execution_set against execution status.
151
+ # Check we have frame is not null
152
+ min_args = cmd.class.const_get(:MIN_ARGS)
153
+ if nargs < min_args
154
+ errmsg(("Command '%s' needs at least %d argument(s); " +
155
+ "got %d.") % [name, min_args, nargs])
156
+ return false
157
+ end
158
+ max_args = cmd.class.const_get(:MAX_ARGS)
159
+ if max_args and nargs > max_args
160
+ errmsg(("Command '%s' needs at most %d argument(s); " +
161
+ "got %d.") % [name, max_args, nargs])
162
+ return false
163
+ end
164
+ # if cmd.class.const_get(:NEED_RUNNING) && !...
165
+ # errmsg "Command '%s' requires a running program." % name
166
+ # return false
167
+ # end
168
+
169
+ if cmd.class.const_get(:NEED_STACK) && !@frame
170
+ errmsg "Command '%s' requires a running stack frame." % name
171
+ return false
172
+ end
173
+
174
+ return true
175
+ end
176
+
177
+ # Run one debugger command. True is returned if we want to quit.
178
+ def process_command_and_quit?()
179
+ intf = @dbgr.intf
180
+ return true if intf[-1].input.eof? && intf.size == 1
181
+ while !intf[-1].input.eof? || intf.size > 1
182
+ begin
183
+ @current_command = read_command().strip
184
+ if @current_command.empty?
185
+ if @last_command && intf[-1].interactive?
186
+ @current_command = @last_command
187
+ else
188
+ next
189
+ end
190
+ end
191
+ next if @current_command[0..0] == '#' # Skip comment lines
192
+ break
193
+ rescue IOError, Errno::EPIPE
194
+ if @dbgr.intf.size > 1
195
+ @dbgr.intf.pop
196
+ @last_command = nil
197
+ print_location
198
+ else
199
+ msg "That's all folks..."
200
+ ## FIXME: think of something better.
201
+ quit('exit!')
202
+ return true
203
+ end
204
+ end
205
+ end
206
+ leave_cmdloop = run_command(@current_command)
207
+
208
+ # Save it to the history.
209
+ @dbgr.history_io.puts @last_command
210
+ end
211
+
212
+ def after_cmdloop
213
+ @cmdloop_posthooks.run
214
+ end
215
+
216
+ def before_cmdloop
217
+
218
+ frame_setup
219
+
220
+ @unconditional_prehooks.run
221
+ if breakpoint?
222
+ delete_breakpoint(@brkpt) if @brkpt.temp?
223
+ @last_pos = [@frame.vm_location, @stack_size, @current_thread, @event]
224
+ else
225
+ if stepping_skip? # || @stack_size <= @hide_level
226
+ step(@return_to_program, @step_count)
227
+ return true
228
+ elsif @event == 'start'
229
+ step('step', 0)
230
+ return true
231
+ end
232
+ end
233
+
234
+ @prompt = "(#{@settings[:prompt]}): " # compute_prompt
235
+
236
+ @leave_cmd_loop = false
237
+ print_location unless @settings[:traceprint]
238
+ # if 'trace-var' == @event
239
+ # msg "Note: we are stopped *after* the above location."
240
+ # end
241
+
242
+ # @eventbuf.add_mark if @settings[:tracebuffer]
243
+
244
+ @return_to_program = false
245
+ @cmdloop_prehooks.run
246
+ return false
247
+ end
248
+
249
+
250
+ # This is the main entry point.
251
+ def process_commands
252
+ skip_command = before_cmdloop
253
+ while not @leave_cmd_loop do
254
+ begin
255
+ if !skip_command
256
+ break if process_command_and_quit?()
257
+ end
258
+ if @return_to_program
259
+ after_cmdloop
260
+ if @step_count >= 0
261
+ @step_bp = step_over_by(1)
262
+ run_command('disassemble') if settings[:debugstep]
263
+ dbgr.listen('step' == @return_to_program)
264
+ else
265
+ @step_bp = nil
266
+ dbgr.listen
267
+ end
268
+ skip_command = before_cmdloop
269
+ end
270
+ rescue SystemExit
271
+ ## @dbgr.stop
272
+ raise
273
+ rescue Exception => exc
274
+ errmsg("Internal debugger error: #{exc.inspect}")
275
+ exception_dump(exc, @settings[:debugexcept], $!.backtrace)
276
+ end
277
+ end
278
+ after_cmdloop
279
+ end
280
+
281
+ # Run current_command, a String. @last_command is set after the
282
+ # command is run if it is a command.
283
+ def run_command(current_command)
284
+ eval_command =
285
+ if current_command[0..0] == '!'
286
+ current_command[0] = ''
287
+ else
288
+ false
289
+ end
290
+
291
+ unless eval_command
292
+ # Expand macros. FIXME: put in a procedure
293
+ args = current_command.split
294
+ while true do
295
+ macro_cmd_name = args[0]
296
+ return false if args.size == 0
297
+ break unless @macros.member?(macro_cmd_name)
298
+ current_command = @macros[macro_cmd_name].call(*args[1..-1])
299
+ msg current_command if settings[:debugmacro]
300
+ if current_command.is_a?(Array) &&
301
+ current_command.any {|val| !val.is_a?(String)}
302
+ args = current_command
303
+ elsif current_command.is_a?(String)
304
+ args = current_command.split
305
+ else
306
+ errmsg("macro #{macro_cmd_name} should return an Array " +
307
+ "of Strings or a String. Got #{current_command.inspect}")
308
+ return false
309
+ end
310
+ end
311
+
312
+ @cmd_name = args[0]
313
+ run_cmd_name =
314
+ if @aliases.member?(@cmd_name)
315
+ @aliases[@cmd_name]
316
+ else
317
+ @cmd_name
318
+ end
319
+
320
+ if @commands.member?(run_cmd_name)
321
+ cmd = @commands[run_cmd_name]
322
+ if ok_for_running(cmd, run_cmd_name, args.size-1)
323
+ @cmd_argstr = current_command[@cmd_name.size..-1].lstrip
324
+ cmd.run(args)
325
+ @last_command = current_command
326
+ end
327
+ return false
328
+ end
329
+ end
330
+
331
+ # Eval anything that's not a command or has been
332
+ # requested to be eval'd
333
+ if settings[:autoeval] || eval_command
334
+ eval_code(current_command, @settings[:maxstring])
335
+ else
336
+ undefined_command(cmd_name)
337
+ end
338
+ return false
339
+ end
340
+
341
+ # Error message when a command doesn't exist
342
+ def undefined_command(cmd_name)
343
+ errmsg('Undefined command: "%s". Try "help".' % cmd_name)
344
+ end
345
+
346
+ # FIXME: Allow access to both Trepan::CmdProcessor and Trepan
347
+ # for index [] and []=.
348
+ # If there is a Trepan::CmdProcessor setting that would take precidence.
349
+ # def settings
350
+ # @settings.merge(@dbgr.settings) # wrong because this doesn't allow []=
351
+ # end
352
+ end
353
+ end
354
+
355
+ if __FILE__ == $0
356
+ $0 = 'foo' # So we don't get here again
357
+ require_relative '../lib/trepanning'
358
+ dbg = Trepan.new(:nx => true)
359
+ cmdproc = dbg.instance_variable_get('@processor')
360
+ cmdproc.msg('I am main')
361
+ cmdproc.errmsg('Whoa!')
362
+ cmds = cmdproc.commands
363
+ p cmdproc.aliases
364
+ p cmdproc.commands.keys.sort
365
+ cmd_name, cmd_obj = cmds.first
366
+ puts cmd_obj.class.const_get(:HELP)
367
+ puts cmd_obj.class.const_get(:SHORT_HELP)
368
+
369
+ cmdproc.instance_variable_set('@current_thread', Thread.current)
370
+ puts cmdproc.compute_prompt
371
+ Thread.new{ puts cmdproc.compute_prompt }.join
372
+
373
+ x = Thread.new{ Thread.pass; x = 1 }
374
+ puts cmdproc.compute_prompt
375
+ x.join
376
+ cmdproc.debug_nest += 1
377
+ puts cmdproc.compute_prompt
378
+
379
+ # if ARGV.size > 0
380
+ # cmdproc.msg('Enter "q" to quit')
381
+ # cmdproc.process_commands
382
+ # else
383
+ # $input = []
384
+ # class << cmdproc
385
+ # def read_command
386
+ # $input.shift
387
+ # end
388
+ # end
389
+ # $input = ['1+2']
390
+ # cmdproc.process_command_and_quit?
391
+ # $input = ['!s = 5'] # ! means eval line
392
+ # cmdproc.process_command_and_quit?
393
+ # end
394
+ end
data/processor/mock.rb ADDED
@@ -0,0 +1,137 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # Mock setup for commands.
3
+ require 'rubygems'; require 'require_relative'
4
+
5
+ require_relative 'main'
6
+
7
+ # require_relative '../app/core'
8
+ require_relative '../app/default'
9
+ require_relative '../app/frame'
10
+ require_relative '../interface/user' # user interface (includes I/O)
11
+
12
+ module MockDebugger
13
+ class MockDebugger
14
+ attr_accessor :trace_filter # Procs/Methods we ignore.
15
+
16
+ attr_accessor :frame # Actually a "Rubinius::Location object
17
+ attr_accessor :core # access to Debugger::Core instance
18
+ attr_accessor :intf # The way the outside world interfaces with us.
19
+ attr_reader :initial_dir # String. Current directory when program
20
+ # started. Used in restart program.
21
+ attr_accessor :restart_argv # How to restart us, empty or nil.
22
+ # Note restart[0] is typically $0.
23
+ attr_reader :settings # Hash[:symbol] of things you can configure
24
+ attr_accessor :processor
25
+
26
+ # FIXME: move more stuff of here and into Trepan::CmdProcessor
27
+ # These below should go into Trepan::CmdProcessor.
28
+ attr_reader :cmd_argstr, :cmd_name, :vm_locations, :current_frame,
29
+ :debugee_thread
30
+
31
+ def initialize(settings={})
32
+ @before_cmdloop_hooks = []
33
+ @settings = Trepanning::DEFAULT_SETTINGS.merge(settings)
34
+ @intf = [Trepan::UserInterface.new]
35
+ @vm_locations = Rubinius::VM.backtrace(1, true)
36
+ @current_frame = Trepan::Frame.new(self, 0, @vm_locations[0])
37
+ @debugee_thread = Thread.current
38
+ @frames = []
39
+ @restart_argv = Rubinius::OS_STARTUP_DIR
40
+
41
+ ## @core = Trepan::Core.new(self)
42
+ @trace_filter = []
43
+
44
+ # Don't allow user commands in mocks.
45
+ ## @core.processor.settings[:user_cmd_dir] = nil
46
+
47
+ end
48
+
49
+ def frame(num)
50
+ @frames[num] ||= Trepan::Frame.new(self, num, @vm_locations[num])
51
+ end
52
+ end
53
+
54
+ # Common Mock debugger setup
55
+ def setup(name=nil, show_constants=true)
56
+ unless name
57
+ loc = Rubinius::VM.backtrace(1, true)[0]
58
+ name = File.basename(loc.file, '.rb')
59
+ end
60
+
61
+ if ARGV.size > 0 && ARGV[0] == 'debug'
62
+ require_relative '../lib/trepanning'
63
+ dbgr = Trepan.new
64
+ dbgr.debugger
65
+ else
66
+ dbgr = MockDebugger.new
67
+ end
68
+
69
+ cmdproc = Trepan::CmdProcessor.new(dbgr)
70
+ cmdproc.frame = dbgr.frame(0)
71
+ dbgr.processor = cmdproc
72
+
73
+ cmdproc.load_cmds_initialize
74
+ cmds = cmdproc.commands
75
+ cmd = cmds[name]
76
+ cmd.proc.frame_setup
77
+ show_special_class_constants(cmd) if show_constants
78
+
79
+ def cmd.msg(message)
80
+ puts message
81
+ end
82
+ def cmd.msg_nocr(message)
83
+ print message
84
+ end
85
+ def cmd.errmsg(message)
86
+ puts "Error: #{message}"
87
+ end
88
+ def cmd.confirm(prompt, default)
89
+ true
90
+ end
91
+
92
+ return dbgr, cmd
93
+ end
94
+ module_function :setup
95
+
96
+ def sub_setup(sub_class, run=true)
97
+ sub_name = sub_class.const_get('PREFIX')
98
+ dbgr, cmd = setup(sub_name[0], false)
99
+ sub_cmd = sub_class.new(cmd)
100
+ sub_cmd.summary_help(sub_cmd.name)
101
+ puts
102
+ sub_cmd.run([cmd.name]) if run
103
+ return sub_cmd
104
+ end
105
+ module_function :sub_setup
106
+
107
+ def subsub_setup(sub_class, subsub_class, run=true)
108
+ subsub_name = subsub_class.const_get('PREFIX')
109
+ dbgr, cmd = setup(subsub_name[0], false)
110
+ sub_cmd = sub_class.new(dbgr.processor, cmd)
111
+ subsub_cmd = subsub_class.new(cmd.proc, sub_cmd, subsub_name.join(''))
112
+ subsub_cmd.run([subsub_cmd.name]) if run
113
+ return subsub_cmd
114
+ end
115
+ module_function :subsub_setup
116
+
117
+ def show_special_class_constants(cmd)
118
+ puts 'ALIASES: %s' % [cmd.class.const_get('ALIASES').inspect] if
119
+ cmd.class.constants.member?(:ALIASES)
120
+ %w(CATEGORY MIN_ARGS MAX_ARGS
121
+ NAME NEED_STACK SHORT_HELP).each do |name|
122
+ puts '%s: %s' % [name, cmd.class.const_get(name).inspect]
123
+ end
124
+ puts '-' * 30
125
+ puts cmd.class.const_get('HELP')
126
+ puts '=' * 30
127
+ end
128
+ module_function :show_special_class_constants
129
+
130
+ end
131
+
132
+ if __FILE__ == $0
133
+ dbgr = MockDebugger::MockDebugger.new
134
+ p dbgr.settings
135
+ puts '=' * 10
136
+ # p dbgr.core.processor.settings
137
+ end
data/processor/msg.rb ADDED
@@ -0,0 +1,28 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # I/O related command processor methods
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../app/util'
5
+ class Trepan
6
+ include Util
7
+ class CmdProcessor
8
+ def errmsg(message)
9
+ @dbgr.intf[-1].errmsg(safe_rep(message))
10
+ end
11
+
12
+ def msg(message)
13
+ @dbgr.intf[-1].msg(safe_rep(message))
14
+ end
15
+
16
+ def msg_nocr(message)
17
+ @dbgr.intf[-1].msg_nocr(safe_rep(message))
18
+ end
19
+
20
+ def read_command()
21
+ @dbgr.intf[-1].read_command(@prompt)
22
+ end
23
+
24
+ def safe_rep(str)
25
+ Trepan::Util::safe_repr(str, @settings[:maxstring])
26
+ end
27
+ end
28
+ end