rb8-trepanning 0.1.3
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.
- data/.gitignore +3 -0
- data/CHANGES +34 -0
- data/ChangeLog +875 -0
- data/README.textile +59 -0
- data/Rakefile +215 -0
- data/app/.gitignore +1 -0
- data/app/cmd_parse.kpeg +241 -0
- data/app/cmd_parse.rb +212 -0
- data/app/cmd_parser.rb +1948 -0
- data/app/complete.rb +79 -0
- data/app/default.rb +90 -0
- data/app/display.rb +148 -0
- data/app/eventbuffer.rb +147 -0
- data/app/frame.rb +166 -0
- data/app/irb.rb +114 -0
- data/app/options.rb +200 -0
- data/app/run.rb +74 -0
- data/app/util.rb +65 -0
- data/bin/.gitignore +1 -0
- data/bin/trepan8 +115 -0
- data/data/.gitignore +1 -0
- data/data/irbrc +41 -0
- data/interface/.gitignore +1 -0
- data/interface/base_intf.rb +109 -0
- data/interface/client.rb +82 -0
- data/interface/comcodes.rb +20 -0
- data/interface/script.rb +110 -0
- data/interface/server.rb +147 -0
- data/interface/user.rb +165 -0
- data/io/base_io.rb +148 -0
- data/io/input.rb +158 -0
- data/io/null_output.rb +46 -0
- data/io/string_array.rb +156 -0
- data/io/tcpclient.rb +129 -0
- data/io/tcpfns.rb +33 -0
- data/io/tcpserver.rb +141 -0
- data/lib/debugger.rb +8 -0
- data/lib/trepanning.rb +283 -0
- data/processor/.gitignore +1 -0
- data/processor/command-ruby-debug/breakpoints.rb +155 -0
- data/processor/command-ruby-debug/catchpoint.rb +55 -0
- data/processor/command-ruby-debug/condition.rb +49 -0
- data/processor/command-ruby-debug/control.rb +31 -0
- data/processor/command-ruby-debug/display.rb +120 -0
- data/processor/command-ruby-debug/enable.rb +202 -0
- data/processor/command-ruby-debug/frame.rb +199 -0
- data/processor/command-ruby-debug/help.rb +63 -0
- data/processor/command-ruby-debug/info.rb +359 -0
- data/processor/command-ruby-debug/method.rb +84 -0
- data/processor/command-ruby-debug/reload.rb +40 -0
- data/processor/command-ruby-debug/save.rb +90 -0
- data/processor/command-ruby-debug/set.rb +237 -0
- data/processor/command-ruby-debug/show.rb +251 -0
- data/processor/command-ruby-debug/source.rb +36 -0
- data/processor/command-ruby-debug/threads.rb +189 -0
- data/processor/command-ruby-debug/trace.rb +57 -0
- data/processor/command-ruby-debug/variables.rb +199 -0
- data/processor/command.rb +270 -0
- data/processor/command/.gitignore +1 -0
- data/processor/command/alias.rb +54 -0
- data/processor/command/backtrace.rb +123 -0
- data/processor/command/base/cmd.rb +177 -0
- data/processor/command/base/subcmd.rb +230 -0
- data/processor/command/base/submgr.rb +188 -0
- data/processor/command/base/subsubcmd.rb +128 -0
- data/processor/command/base/subsubmgr.rb +199 -0
- data/processor/command/break.rb +114 -0
- data/processor/command/catch.rb +71 -0
- data/processor/command/complete.rb +39 -0
- data/processor/command/continue.rb +57 -0
- data/processor/command/directory.rb +50 -0
- data/processor/command/disable.rb +85 -0
- data/processor/command/display.rb +78 -0
- data/processor/command/down.rb +54 -0
- data/processor/command/edit.rb +79 -0
- data/processor/command/enable.rb +48 -0
- data/processor/command/eval.rb +90 -0
- data/processor/command/exit.rb +66 -0
- data/processor/command/finish.rb +59 -0
- data/processor/command/frame.rb +97 -0
- data/processor/command/help.rb +230 -0
- data/processor/command/help/.gitignore +1 -0
- data/processor/command/help/README +10 -0
- data/processor/command/help/command.txt +58 -0
- data/processor/command/help/examples.txt +16 -0
- data/processor/command/help/filename.txt +40 -0
- data/processor/command/help/location.txt +37 -0
- data/processor/command/help/suffixes.txt +17 -0
- data/processor/command/info.rb +28 -0
- data/processor/command/info_subcmd/.gitignore +1 -0
- data/processor/command/info_subcmd/args.rb +39 -0
- data/processor/command/info_subcmd/breakpoints.rb +80 -0
- data/processor/command/info_subcmd/catch.rb +36 -0
- data/processor/command/info_subcmd/files.rb +39 -0
- data/processor/command/info_subcmd/globals.rb +64 -0
- data/processor/command/info_subcmd/line.rb +30 -0
- data/processor/command/info_subcmd/locals.rb +69 -0
- data/processor/command/info_subcmd/macro.rb +62 -0
- data/processor/command/info_subcmd/program.rb +51 -0
- data/processor/command/info_subcmd/ruby.rb +57 -0
- data/processor/command/info_subcmd/source.rb +74 -0
- data/processor/command/info_subcmd/stack.rb +25 -0
- data/processor/command/info_subcmd/threads.rb +75 -0
- data/processor/command/kill.rb +78 -0
- data/processor/command/list.rb +117 -0
- data/processor/command/macro.rb +68 -0
- data/processor/command/next.rb +79 -0
- data/processor/command/parsetree.rb +56 -0
- data/processor/command/pp.rb +40 -0
- data/processor/command/pr.rb +37 -0
- data/processor/command/ps.rb +40 -0
- data/processor/command/restart.rb +86 -0
- data/processor/command/save.rb +58 -0
- data/processor/command/set.rb +47 -0
- data/processor/command/set_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/abbrev.rb +25 -0
- data/processor/command/set_subcmd/auto.rb +27 -0
- data/processor/command/set_subcmd/auto_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/auto_subcmd/eval.rb +53 -0
- data/processor/command/set_subcmd/auto_subcmd/irb.rb +33 -0
- data/processor/command/set_subcmd/auto_subcmd/list.rb +33 -0
- data/processor/command/set_subcmd/basename.rb +25 -0
- data/processor/command/set_subcmd/callstyle.rb +46 -0
- data/processor/command/set_subcmd/confirm.rb +24 -0
- data/processor/command/set_subcmd/debug.rb +47 -0
- data/processor/command/set_subcmd/different.rb +61 -0
- data/processor/command/set_subcmd/highlight.rb +43 -0
- data/processor/command/set_subcmd/max.rb +26 -0
- data/processor/command/set_subcmd/max_subcmd/list.rb +49 -0
- data/processor/command/set_subcmd/max_subcmd/stack.rb +50 -0
- data/processor/command/set_subcmd/max_subcmd/string.rb +76 -0
- data/processor/command/set_subcmd/max_subcmd/width.rb +49 -0
- data/processor/command/set_subcmd/reload.rb +42 -0
- data/processor/command/set_subcmd/timer.rb +58 -0
- data/processor/command/set_subcmd/trace.rb +37 -0
- data/processor/command/set_subcmd/trace_subcmd/buffer.rb +42 -0
- data/processor/command/set_subcmd/trace_subcmd/print.rb +41 -0
- data/processor/command/shell.rb +139 -0
- data/processor/command/show.rb +39 -0
- data/processor/command/show_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/abbrev.rb +20 -0
- data/processor/command/show_subcmd/alias.rb +46 -0
- data/processor/command/show_subcmd/args.rb +34 -0
- data/processor/command/show_subcmd/auto.rb +28 -0
- data/processor/command/show_subcmd/auto_subcmd/eval.rb +27 -0
- data/processor/command/show_subcmd/auto_subcmd/irb.rb +23 -0
- data/processor/command/show_subcmd/auto_subcmd/list.rb +22 -0
- data/processor/command/show_subcmd/basename.rb +20 -0
- data/processor/command/show_subcmd/callstyle.rb +22 -0
- data/processor/command/show_subcmd/confirm.rb +18 -0
- data/processor/command/show_subcmd/debug.rb +26 -0
- data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +21 -0
- data/processor/command/show_subcmd/debug_subcmd/skip.rb +22 -0
- data/processor/command/show_subcmd/debug_subcmd/step.rb +22 -0
- data/processor/command/show_subcmd/different.rb +26 -0
- data/processor/command/show_subcmd/directories.rb +22 -0
- data/processor/command/show_subcmd/highlight.rb +24 -0
- data/processor/command/show_subcmd/max.rb +27 -0
- data/processor/command/show_subcmd/max_subcmd/list.rb +38 -0
- data/processor/command/show_subcmd/max_subcmd/stack.rb +36 -0
- data/processor/command/show_subcmd/max_subcmd/string.rb +42 -0
- data/processor/command/show_subcmd/max_subcmd/width.rb +37 -0
- data/processor/command/show_subcmd/reload.rb +18 -0
- data/processor/command/show_subcmd/timer.rb +18 -0
- data/processor/command/show_subcmd/trace.rb +29 -0
- data/processor/command/show_subcmd/trace_subcmd/buffer.rb +65 -0
- data/processor/command/show_subcmd/trace_subcmd/print.rb +23 -0
- data/processor/command/show_subcmd/version.rb +23 -0
- data/processor/command/source.rb +134 -0
- data/processor/command/step.rb +81 -0
- data/processor/command/tbreak.rb +19 -0
- data/processor/command/unalias.rb +44 -0
- data/processor/command/undisplay.rb +59 -0
- data/processor/command/up.rb +72 -0
- data/processor/default.rb +56 -0
- data/processor/display.rb +17 -0
- data/processor/eval.rb +113 -0
- data/processor/eventbuf.rb +105 -0
- data/processor/frame.rb +172 -0
- data/processor/help.rb +92 -0
- data/processor/helper.rb +76 -0
- data/processor/hook.rb +134 -0
- data/processor/load_cmds.rb +258 -0
- data/processor/location.rb +174 -0
- data/processor/main.rb +455 -0
- data/processor/mock.rb +136 -0
- data/processor/msg.rb +61 -0
- data/processor/processor.rb +674 -0
- data/processor/running.rb +168 -0
- data/processor/stepping.rb +18 -0
- data/processor/subcmd.rb +161 -0
- data/processor/validate.rb +355 -0
- data/processor/virtual.rb +34 -0
- data/test/data/.gitignore +1 -0
- data/test/data/break_bad.cmd +19 -0
- data/test/data/break_bad.right +29 -0
- data/test/data/break_loop_bug.cmd +5 -0
- data/test/data/break_loop_bug.right +15 -0
- data/test/data/dollar-0.right +2 -0
- data/test/data/dollar-0a.right +2 -0
- data/test/data/dollar-0b.right +2 -0
- data/test/data/edit.cmd +14 -0
- data/test/data/edit.right +24 -0
- data/test/data/file-with-space.cmd +6 -0
- data/test/data/file-with-space.right +4 -0
- data/test/data/printvar.cmd +17 -0
- data/test/data/printvar.right +31 -0
- data/test/data/raise.cmd +11 -0
- data/test/data/raise.right +19 -0
- data/test/data/source.cmd +5 -0
- data/test/data/source.right +18 -0
- data/test/data/stepping-1.9.right +50 -0
- data/test/data/stepping.cmd +21 -0
- data/test/data/stepping.right +48 -0
- data/test/data/trepan8-save.1 +6 -0
- data/test/example/bp_loop_issue.rb +3 -0
- data/test/example/break-bug.rb +7 -0
- data/test/example/brkpt-class-bug.rb +8 -0
- data/test/example/classes.rb +11 -0
- data/test/example/dollar-0.rb +5 -0
- data/test/example/except-bug1.rb +4 -0
- data/test/example/except-bug2.rb +7 -0
- data/test/example/file with space.rb +1 -0
- data/test/example/gcd.rb +18 -0
- data/test/example/info-var-bug.rb +47 -0
- data/test/example/info-var-bug2.rb +2 -0
- data/test/example/null.rb +1 -0
- data/test/example/pm-bug.rb +3 -0
- data/test/example/pm.rb +11 -0
- data/test/example/raise.rb +3 -0
- data/test/integration/.gitignore +4 -0
- data/test/integration/config.yaml +8 -0
- data/test/integration/helper.rb +154 -0
- data/test/integration/test-break_bad.rb +26 -0
- data/test/integration/test-dollar-0.rb +31 -0
- data/test/integration/test-edit.rb +17 -0
- data/test/integration/test-file-with-space.rb +26 -0
- data/test/integration/test-printvar.rb +17 -0
- data/test/integration/test-raise.rb +21 -0
- data/test/integration/test-source.rb +16 -0
- data/test/integration/test-stepping.rb +24 -0
- data/test/unit/.gitignore +1 -0
- data/test/unit/cmd-helper.rb +52 -0
- data/test/unit/mock-helper.rb +12 -0
- data/test/unit/test-app-cmd_parse.rb +97 -0
- data/test/unit/test-app-cmd_parser.rb +23 -0
- data/test/unit/test-app-complete.rb +39 -0
- data/test/unit/test-app-frame.rb +32 -0
- data/test/unit/test-app-options.rb +92 -0
- data/test/unit/test-app-run.rb +14 -0
- data/test/unit/test-app-util.rb +44 -0
- data/test/unit/test-base-cmd.rb +45 -0
- data/test/unit/test-base-subcmd.rb +57 -0
- data/test/unit/test-base-submgr.rb +23 -0
- data/test/unit/test-base-subsubcmd.rb +17 -0
- data/test/unit/test-cmd-alias.rb +48 -0
- data/test/unit/test-cmd-exit.rb +27 -0
- data/test/unit/test-cmd-help.rb +104 -0
- data/test/unit/test-cmd-kill.rb +46 -0
- data/test/unit/test-cmd-source.rb +34 -0
- data/test/unit/test-completion.rb +42 -0
- data/test/unit/test-intf-user.rb +46 -0
- data/test/unit/test-io-input.rb +27 -0
- data/test/unit/test-io-tcp.rb +33 -0
- data/test/unit/test-io-tcpclient.rb +54 -0
- data/test/unit/test-io-tcpfns.rb +17 -0
- data/test/unit/test-io-tcpserver.rb +50 -0
- data/test/unit/test-proc-eval.rb +36 -0
- data/test/unit/test-proc-hook.rb +30 -0
- data/test/unit/test-proc-load_cmds.rb +50 -0
- data/test/unit/test-proc-location.rb +79 -0
- data/test/unit/test-subcmd-help.rb +44 -0
- data/trepan8.gemspec +52 -0
- metadata +391 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Trepan
|
|
2
|
+
class TraceCommand < OldCommand # :nodoc:
|
|
3
|
+
def regexp
|
|
4
|
+
/^\s* tr(?:ace)? (?: \s+ (\S+)) # on |off | var(iable)
|
|
5
|
+
(?: \s+ (\S+))? # (all | variable-name)?
|
|
6
|
+
(?: \s+ (\S+))? \s* # (stop | nostop)?
|
|
7
|
+
$/ix
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def execute
|
|
11
|
+
if @match[1] =~ /on|off/
|
|
12
|
+
onoff = 'on' == @match[1]
|
|
13
|
+
if @match[2]
|
|
14
|
+
Debugger.current_context.tracing = onoff
|
|
15
|
+
print "Tracing %s all threads.\n" % (onoff ? 'on' : 'off')
|
|
16
|
+
else
|
|
17
|
+
Debugger.tracing = onoff
|
|
18
|
+
print "Tracing %s on current thread.\n" % (onoff ? 'on' : 'off')
|
|
19
|
+
end
|
|
20
|
+
elsif @match[1] =~ /var(?:iable)?/
|
|
21
|
+
varname=@match[2]
|
|
22
|
+
if debug_eval("defined?(#{varname})")
|
|
23
|
+
if @match[3] && @match[3] !~ /(:?no)?stop/
|
|
24
|
+
errmsg("expecting 'stop' or 'nostop'; got %s\n" % @match[3])
|
|
25
|
+
else
|
|
26
|
+
dbg_cmd = if @match[3] && (@match[3] !~ /nostop/)
|
|
27
|
+
'debugger' else '' end
|
|
28
|
+
end
|
|
29
|
+
eval("
|
|
30
|
+
trace_var(:#{varname}) do |val|
|
|
31
|
+
print \"traced variable #{varname} has value \#{val}\n\"
|
|
32
|
+
#{dbg_cmd}
|
|
33
|
+
end")
|
|
34
|
+
else
|
|
35
|
+
errmsg "#{varname} is not a global variable.\n"
|
|
36
|
+
end
|
|
37
|
+
else
|
|
38
|
+
errmsg("expecting 'on', 'off', 'var' or 'variable'; got: %s\n" %
|
|
39
|
+
@match[1])
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class << self
|
|
44
|
+
def help_command
|
|
45
|
+
'trace'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def help(cmd)
|
|
49
|
+
%{
|
|
50
|
+
tr[ace] (on|off)\tset trace mode of current thread
|
|
51
|
+
tr[ace] (on|off) all\tset trace mode of all threads
|
|
52
|
+
tr[ace] var(iable) VARNAME [stop|nostop]\tset trace variable on VARNAME
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
module Trepan
|
|
2
|
+
module VarFunctions # :nodoc:
|
|
3
|
+
def var_list(ary, b = get_binding)
|
|
4
|
+
ary.sort!
|
|
5
|
+
for v in ary
|
|
6
|
+
begin
|
|
7
|
+
s = debug_eval(v, b).inspect
|
|
8
|
+
rescue
|
|
9
|
+
begin
|
|
10
|
+
s = debug_eval(v, b).to_s
|
|
11
|
+
rescue
|
|
12
|
+
s = "*Error in evaluation*"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
if s.size > self.class.settings[:width]
|
|
16
|
+
s[self.class.settings[:width]-3 .. -1] = "..."
|
|
17
|
+
end
|
|
18
|
+
print "%s = %s\n", v, s
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
def var_class_self
|
|
22
|
+
obj = debug_eval('self')
|
|
23
|
+
var_list(obj.class.class_variables, get_binding)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Implements the debugger 'var class' command.
|
|
28
|
+
class VarClassVarCommand < OldCommand
|
|
29
|
+
def regexp
|
|
30
|
+
/^\s*v(?:ar)?\s+cl(?:ass)?/
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def execute
|
|
34
|
+
unless @state.context
|
|
35
|
+
errmsg "can't get class variables here.\n"
|
|
36
|
+
return
|
|
37
|
+
end
|
|
38
|
+
var_class_self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class << self
|
|
42
|
+
def help_command
|
|
43
|
+
'var'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def help(cmd)
|
|
47
|
+
%{
|
|
48
|
+
v[ar] cl[ass] \t\t\tshow class variables of self
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class VarConstantCommand < OldCommand # :nodoc:
|
|
55
|
+
def regexp
|
|
56
|
+
/^\s*v(?:ar)?\s+co(?:nst(?:ant)?)?\s+/
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def execute
|
|
60
|
+
obj = debug_eval(@match.post_match)
|
|
61
|
+
if obj.kind_of? Module
|
|
62
|
+
constants = debug_eval("#{@match.post_match}.constants")
|
|
63
|
+
constants.sort!
|
|
64
|
+
for c in constants
|
|
65
|
+
next if c =~ /SCRIPT/
|
|
66
|
+
value = obj.const_get(c) rescue "ERROR: #{$!}"
|
|
67
|
+
print " %s => %p\n", c, value
|
|
68
|
+
end
|
|
69
|
+
else
|
|
70
|
+
print "Should be Class/Module: %s\n", @match.post_match
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
class << self
|
|
75
|
+
def help_command
|
|
76
|
+
'var'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def help(cmd)
|
|
80
|
+
%{
|
|
81
|
+
v[ar] c[onst] <object>\t\tshow constants of object
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
class VarGlobalCommand < OldCommand # :nodoc:
|
|
88
|
+
def regexp
|
|
89
|
+
/^\s*v(?:ar)?\s+g(?:lobal)?\s*$/
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def execute
|
|
93
|
+
var_list(global_variables)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
class << self
|
|
97
|
+
def help_command
|
|
98
|
+
'var'
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def help(cmd)
|
|
102
|
+
%{
|
|
103
|
+
v[ar] g[lobal]\t\t\tshow global variables
|
|
104
|
+
}
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
class VarInstanceCommand < OldCommand # :nodoc:
|
|
110
|
+
def regexp
|
|
111
|
+
/^\s*v(?:ar)?\s+ins(?:tance)?\s*/
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def execute
|
|
115
|
+
obj = debug_eval(@match.post_match.empty? ? 'self' : @match.post_match)
|
|
116
|
+
var_list(obj.instance_variables, obj.instance_eval{binding()})
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
class << self
|
|
120
|
+
def help_command
|
|
121
|
+
'var'
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def help(cmd)
|
|
125
|
+
%{
|
|
126
|
+
v[ar] i[nstance] <object>\tshow instance variables of object
|
|
127
|
+
}
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Implements the debugger 'var local' command.
|
|
133
|
+
class VarLocalCommand < OldCommand
|
|
134
|
+
def regexp
|
|
135
|
+
/^\s*v(?:ar)?\s+l(?:ocal)?\s*$/
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def execute
|
|
139
|
+
locals = @state.context.frame_locals(@state.frame_pos)
|
|
140
|
+
_self = @state.context.frame_self(@state.frame_pos)
|
|
141
|
+
locals.keys.sort.each do |name|
|
|
142
|
+
print " %s => %p\n", name, locals[name]
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
class << self
|
|
147
|
+
def help_command
|
|
148
|
+
'var'
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def help(cmd)
|
|
152
|
+
%{
|
|
153
|
+
v[ar] l[ocal]\t\t\tshow local variables
|
|
154
|
+
}
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Implements the debugger 'var inherit' command.
|
|
160
|
+
begin
|
|
161
|
+
require 'classtree'
|
|
162
|
+
have_classtree = true
|
|
163
|
+
rescue LoadError
|
|
164
|
+
have_classtree = false
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
class VarInheritCommand < OldCommand
|
|
168
|
+
def regexp
|
|
169
|
+
/^\s*v(?:ar)?\s+ct\s*/
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def execute
|
|
173
|
+
unless @state.context
|
|
174
|
+
errmsg "can't get object inheritance.\n"
|
|
175
|
+
return
|
|
176
|
+
end
|
|
177
|
+
puts @match.post_match
|
|
178
|
+
obj = debug_eval("#{@match.post_match}.classtree")
|
|
179
|
+
if obj
|
|
180
|
+
print obj
|
|
181
|
+
else
|
|
182
|
+
errmsg "Trouble getting object #{@match.post_match}\n"
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
class << self
|
|
187
|
+
def help_command
|
|
188
|
+
'var'
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def help(cmd)
|
|
192
|
+
%{
|
|
193
|
+
v[ar] ct\t\t\tshow class heirarchy of object
|
|
194
|
+
}
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end if have_classtree
|
|
198
|
+
|
|
199
|
+
end
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'columnize'
|
|
3
|
+
require 'require_relative'
|
|
4
|
+
require_relative './helper'
|
|
5
|
+
|
|
6
|
+
module Trepan
|
|
7
|
+
RUBY_DEBUG_DIR = File.expand_path(File.dirname(__FILE__)) unless
|
|
8
|
+
defined?(RUBY_DEBUG_DIR)
|
|
9
|
+
|
|
10
|
+
# A Trepan::Command object is is the base class for commands that
|
|
11
|
+
# implement a single debugger command. Individual debugger commands
|
|
12
|
+
# will be a subclass of this. The singleton class object is the
|
|
13
|
+
# command manager for all commands.
|
|
14
|
+
#
|
|
15
|
+
# Each debugger command is expected to implement the following methods:
|
|
16
|
+
# _regexp_:: A regular expression which input strings are matched
|
|
17
|
+
# against. If we have a match, run this command.
|
|
18
|
+
# It is the ruby-debug programmer's responsibility
|
|
19
|
+
# to make sure that these regular expressions match disjoint
|
|
20
|
+
# sets of strings. Otherwise one is arbitrarily used.
|
|
21
|
+
# _execute_:: Ruby code that implements the command.
|
|
22
|
+
# _help_:: Should return a String containing descriptive help for
|
|
23
|
+
# the commmand. Used by the 'help' command Trepan::HelpCommand
|
|
24
|
+
# _help_command_:: The name of the command listed via help.
|
|
25
|
+
#
|
|
26
|
+
# _help_ and _help_command_ methods are singleton methods, not
|
|
27
|
+
# instance methods like _regexp_ and _execute_.
|
|
28
|
+
class OldCommand
|
|
29
|
+
SubcmdStruct=Struct.new(:name, :min, :short_help, :long_help) unless
|
|
30
|
+
defined?(SubcmdStruct)
|
|
31
|
+
|
|
32
|
+
include Columnize
|
|
33
|
+
|
|
34
|
+
# Find _param_ in _subcmds_. The _param_ id downcased and can be
|
|
35
|
+
# abbreviated to the minimum length listed in the subcommands
|
|
36
|
+
def find(subcmds, param)
|
|
37
|
+
param.downcase!
|
|
38
|
+
for try_subcmd in subcmds do
|
|
39
|
+
if (param.size >= try_subcmd.min) and
|
|
40
|
+
(try_subcmd.name[0..param.size-1] == param)
|
|
41
|
+
return try_subcmd
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
return nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
class << self
|
|
48
|
+
# An Array containing Trepan::Command classes that implment each
|
|
49
|
+
# of the debugger commands.
|
|
50
|
+
def commands
|
|
51
|
+
@commands ||= []
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
DEF_OPTIONS = {
|
|
55
|
+
:allow_in_control => false,
|
|
56
|
+
:allow_in_post_mortem => true,
|
|
57
|
+
:event => true,
|
|
58
|
+
:always_run => 0,
|
|
59
|
+
:unknown => false,
|
|
60
|
+
:need_context => false,
|
|
61
|
+
} unless defined?(DEF_OPTIONS)
|
|
62
|
+
|
|
63
|
+
def inherited(klass)
|
|
64
|
+
DEF_OPTIONS.each do |o, v|
|
|
65
|
+
klass.options[o] = v if klass.options[o].nil?
|
|
66
|
+
end
|
|
67
|
+
commands << klass
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Read in and "include" all the subclasses of the
|
|
71
|
+
# Trepan::Command class. For example
|
|
72
|
+
# Trepan::QuitCommand is one of them. The list of Ruby
|
|
73
|
+
# files to read are all the files that end .rb in directory
|
|
74
|
+
# Trepan::RUBY_DEBUG_DIR
|
|
75
|
+
def load_commands
|
|
76
|
+
Dir[File.join(%W(#{Trepan.const_get(:RUBY_DEBUG_DIR)}
|
|
77
|
+
command-ruby-debug *))].each do
|
|
78
|
+
|file|
|
|
79
|
+
require file if file =~ /\.rb$/
|
|
80
|
+
end
|
|
81
|
+
Trepan.constants.grep(/Functions$/).map { |name| Trepan.const_get(name) }.each do |mod|
|
|
82
|
+
include mod
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def method_missing(meth, *args, &block)
|
|
87
|
+
if meth.to_s =~ /^(.+?)=$/
|
|
88
|
+
@options[$1.intern] = args.first
|
|
89
|
+
else
|
|
90
|
+
if @options.has_key?(meth)
|
|
91
|
+
@options[meth]
|
|
92
|
+
else
|
|
93
|
+
super
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def options
|
|
99
|
+
@options ||= {}
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def settings_map
|
|
103
|
+
@@settings_map ||= {}
|
|
104
|
+
end
|
|
105
|
+
private :settings_map
|
|
106
|
+
|
|
107
|
+
# Returns a Hash of Debugger settings, @settings. If doesn't exist
|
|
108
|
+
# we create a @settings hash with [] setter and getter and return that.
|
|
109
|
+
def settings
|
|
110
|
+
unless true and defined? @settings and @settings
|
|
111
|
+
@settings = Object.new
|
|
112
|
+
map = settings_map
|
|
113
|
+
c = class << @settings; self end
|
|
114
|
+
if c.respond_to?(:funcall)
|
|
115
|
+
c.funcall(:define_method, :[]) do |name|
|
|
116
|
+
raise "No such setting #{name}" unless map.has_key?(name)
|
|
117
|
+
map[name][:getter].call
|
|
118
|
+
end
|
|
119
|
+
else
|
|
120
|
+
c.send(:define_method, :[]) do |name|
|
|
121
|
+
raise "No such setting #{name}" unless map.has_key?(name)
|
|
122
|
+
map[name][:getter].call
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
c = class << @settings; self end
|
|
126
|
+
if c.respond_to?(:funcall)
|
|
127
|
+
c.funcall(:define_method, :[]=) do |name, value|
|
|
128
|
+
raise "No such setting #{name}" unless map.has_key?(name)
|
|
129
|
+
map[name][:setter].call(value)
|
|
130
|
+
end
|
|
131
|
+
else
|
|
132
|
+
c.send(:define_method, :[]=) do |name, value|
|
|
133
|
+
raise "No such setting #{name}" unless map.has_key?(name)
|
|
134
|
+
map[name][:setter].call(value)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
@settings
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def register_setting_var(name, default)
|
|
142
|
+
var_name = "@@#{name}"
|
|
143
|
+
class_variable_set(var_name, default)
|
|
144
|
+
register_setting_get(name) { class_variable_get(var_name) }
|
|
145
|
+
register_setting_set(name) { |value| class_variable_set(var_name, value) }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def register_setting_get(name, &block)
|
|
149
|
+
settings_map[name] ||= {}
|
|
150
|
+
settings_map[name][:getter] = block
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def register_setting_set(name, &block)
|
|
154
|
+
settings_map[name] ||= {}
|
|
155
|
+
settings_map[name][:setter] = block
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
register_setting_var(:basename, false) # use basename in showing files?
|
|
160
|
+
register_setting_var(:callstyle, :last)
|
|
161
|
+
register_setting_var(:debuggertesting, false)
|
|
162
|
+
register_setting_var(:force_stepping, false)
|
|
163
|
+
register_setting_var(:full_path, true)
|
|
164
|
+
register_setting_var(:listsize, 10) # number of lines in list command
|
|
165
|
+
register_setting_var(:stack_trace_on_error, false)
|
|
166
|
+
register_setting_var(:tracing_plus, false) # different linetrace lines?
|
|
167
|
+
|
|
168
|
+
# width of line output. Use COLUMNS value if it exists and is
|
|
169
|
+
# not too rediculously large.
|
|
170
|
+
width = ENV['COLUMNS'].to_i
|
|
171
|
+
width = 80 unless width > 10
|
|
172
|
+
register_setting_var(:width, width)
|
|
173
|
+
|
|
174
|
+
if not defined? Trepan::ARGV
|
|
175
|
+
Trepan::ARGV = ARGV.clone
|
|
176
|
+
end
|
|
177
|
+
register_setting_var(:argv, Trepan::ARGV)
|
|
178
|
+
|
|
179
|
+
def initialize(state)
|
|
180
|
+
@state = state
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def match(input)
|
|
184
|
+
@match = regexp.match(input)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
protected
|
|
188
|
+
|
|
189
|
+
# FIXME: use delegate?
|
|
190
|
+
def errmsg(*args)
|
|
191
|
+
@state.errmsg(*args)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def print(*args)
|
|
195
|
+
@state.print(*args)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Called when we are about to do a dangerous operation. _msg_
|
|
199
|
+
# contains a prompt message. Return _true_ if confirmed or _false_
|
|
200
|
+
# if not confirmed.
|
|
201
|
+
def confirm(msg)
|
|
202
|
+
@state.confirm(msg) == 'y'
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# debug_eval like Kernel.eval or Object.instance_eval but using
|
|
206
|
+
# the bindings for the debugged program. If there is a
|
|
207
|
+
# syntax-error like exception in running eval, print an
|
|
208
|
+
# appropriate message and throw :debug_error
|
|
209
|
+
def debug_eval(str, b = get_binding)
|
|
210
|
+
begin
|
|
211
|
+
val = eval(str, b)
|
|
212
|
+
rescue StandardError, ScriptError => e
|
|
213
|
+
if OldCommand.settings[:stack_trace_on_error]
|
|
214
|
+
at = eval("caller(1)", b)
|
|
215
|
+
print "%s:%s\n", at.shift, e.to_s.sub(/\(eval\):1:(in `.*?':)?/, '')
|
|
216
|
+
for i in at
|
|
217
|
+
print "\tfrom %s\n", i
|
|
218
|
+
end
|
|
219
|
+
else
|
|
220
|
+
print "#{e.class} Exception: #{e.message}\n"
|
|
221
|
+
end
|
|
222
|
+
throw :debug_error
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# debug_eval like Kernel.eval or Object.instance_eval but using
|
|
227
|
+
# the bindings for the debugged program. If there is a syntax
|
|
228
|
+
# error kind of exception in running eval, no warning is given and
|
|
229
|
+
# nil is returned.
|
|
230
|
+
def debug_silent_eval(str)
|
|
231
|
+
begin
|
|
232
|
+
eval(str, get_binding)
|
|
233
|
+
rescue StandardError, ScriptError
|
|
234
|
+
nil
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Return a binding object for the debugged program.
|
|
239
|
+
def get_binding
|
|
240
|
+
@state.context.frame_binding(@state.frame_pos)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def line_at(file, line)
|
|
244
|
+
Debugger.line_at(file, line)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def get_context(thnum)
|
|
248
|
+
Debugger.contexts.find{|c| c.thnum == thnum}
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
OldCommand.load_commands
|
|
253
|
+
|
|
254
|
+
# Returns setting object.
|
|
255
|
+
# Use Debugger.settings[] and Debugger.settings[]= methods to query and set
|
|
256
|
+
# debugger settings. These settings are available:
|
|
257
|
+
#
|
|
258
|
+
# - :autolist - automatically calls 'list' command on breakpoint
|
|
259
|
+
# - :autoeval - evaluates input in the current binding if it's not recognized as a debugger command
|
|
260
|
+
# - :autoirb - automatically calls 'irb' command on breakpoint
|
|
261
|
+
# - :stack_trace_on_error - shows full stack trace if eval command results with an exception
|
|
262
|
+
# - :frame_full_path - displays full paths when showing frame stack
|
|
263
|
+
# - :frame_class_names - displays method's class name when showing frame stack
|
|
264
|
+
# - :reload_source_on_change - makes 'list' command to always display up-to-date source code
|
|
265
|
+
# - :force_stepping - stepping command asways move to the new line
|
|
266
|
+
#
|
|
267
|
+
def self.settings
|
|
268
|
+
OldCommand.settings
|
|
269
|
+
end
|
|
270
|
+
end
|