rbx-trepanning 0.0.3-universal-rubinius-1.2 → 0.0.4-universal-rubinius-1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +152 -55
- data/NEWS +7 -0
- data/Rakefile +1 -1
- data/app/breakpoint.rb +3 -2
- data/app/breakpoint.rbc +207 -220
- data/app/brkptmgr.rb +84 -82
- data/app/brkptmgr.rbc +263 -193
- data/app/client.rb +61 -0
- data/app/client.rbc +1225 -0
- data/app/default.rb +17 -7
- data/app/default.rbc +302 -181
- data/app/display.rb +134 -21
- data/app/display.rbc +2176 -566
- data/app/iseq.rb +33 -11
- data/app/iseq.rbc +634 -243
- data/app/llvm.rbc +2576 -0
- data/app/options.rb +51 -20
- data/app/options.rb.orig +154 -0
- data/app/options.rbc +1148 -561
- data/app/rbx-llvm.rb +165 -0
- data/app/util.rb +1 -1
- data/app/util.rbc +38 -32
- data/bin/trepan.orig +0 -0
- data/bin/trepan.rej +11 -0
- data/bin/trepanx +13 -8
- data/bin/trepanx.compiled.rbc +373 -319
- data/interface/base_intf.rb +11 -5
- data/interface/base_intf.rbc +173 -70
- data/interface/client.rb +80 -0
- data/interface/client.rbc +1072 -0
- data/interface/comcodes.rb +18 -0
- data/interface/comcodes.rbc +343 -0
- data/interface/server.rb +143 -0
- data/interface/server.rbc +2213 -0
- data/interface/user.rb +1 -8
- data/interface/user.rbc +68 -165
- data/io/base_io.rb +56 -2
- data/io/base_io.rbc +727 -20
- data/io/tcpclient.rb +123 -0
- data/io/tcpclient.rbc +2327 -0
- data/io/tcpfns.rb +31 -0
- data/io/tcpfns.rbc +652 -0
- data/io/tcpserver.rb +138 -0
- data/io/tcpserver.rbc +2585 -0
- data/lib/trepanning.rb +91 -56
- data/lib/trepanning.rb.orig +433 -0
- data/lib/trepanning.rb.rej +11 -0
- data/lib/trepanning.rbc +1954 -1340
- data/processor/command/backtrace.rb +45 -15
- data/processor/command/base/cmd.rb +10 -6
- data/processor/command/base/subcmd.rb +16 -1
- data/processor/command/complete.rb +47 -0
- data/processor/command/continue.rb +4 -3
- data/processor/command/directory.rb +9 -1
- data/processor/command/disassemble.rb +22 -7
- data/processor/command/display.rb +82 -0
- data/processor/command/eval.rb +3 -1
- data/processor/command/exit.rb +4 -0
- data/processor/command/help.rb +69 -18
- data/processor/command/info_subcmd/breakpoints.rb +6 -8
- data/processor/command/info_subcmd/file.rb +5 -7
- data/processor/command/info_subcmd/method.rb +9 -9
- data/processor/command/info_subcmd/program.rb +3 -4
- data/processor/command/info_subcmd/variables.rb +4 -3
- data/processor/command/list.rb +8 -4
- data/processor/command/nexti.rb +2 -2
- data/processor/command/pr.rb +2 -2
- data/processor/command/ps.rb +2 -2
- data/processor/command/server.rb +72 -0
- data/processor/command/set_subcmd/auto.rb +2 -3
- data/processor/command/set_subcmd/basename.rb +3 -4
- data/processor/command/set_subcmd/debug.rb +2 -3
- data/processor/command/set_subcmd/different.rb +3 -4
- data/processor/command/set_subcmd/hidelevel.rb +6 -7
- data/processor/command/set_subcmd/highlight.rb +33 -0
- data/processor/command/set_subcmd/kernelstep.rb +3 -4
- data/processor/command/set_subcmd/max.rb +2 -4
- data/processor/command/set_subcmd/max_subcmd/string.rb +44 -22
- data/processor/command/set_subcmd/substitute.rb +2 -3
- data/processor/command/set_subcmd/trace.rb +3 -4
- data/processor/command/show_subcmd/alias.rb +3 -4
- data/processor/command/show_subcmd/args.rb +2 -3
- data/processor/command/show_subcmd/auto.rb +1 -2
- data/processor/command/show_subcmd/basename.rb +2 -3
- data/processor/command/show_subcmd/debug.rb +1 -2
- data/processor/command/show_subcmd/different.rb +2 -3
- data/processor/command/show_subcmd/hidelevel.rb +1 -2
- data/processor/command/show_subcmd/highlight.rb +24 -0
- data/processor/command/show_subcmd/kernelstep.rb +3 -6
- data/processor/command/show_subcmd/max.rb +4 -5
- data/processor/command/show_subcmd/trace.rb +9 -11
- data/processor/command/show_subcmd/version.rb +23 -0
- data/processor/command/source.rb +75 -31
- data/processor/command/undisplay.rb +59 -0
- data/processor/default.rb +4 -4
- data/processor/disassemble.rb +18 -5
- data/processor/display.rb +18 -0
- data/processor/location.rb +15 -5
- data/processor/main.rb +27 -13
- data/processor/mock.rb +12 -9
- data/processor/msg.rb +24 -9
- data/processor/stepping.rb +10 -12
- data/sample/list-terminal-colors.rb +139 -0
- data/sample/list-terminal-colors.rbc +2164 -0
- data/sample/rocky-dot-trepanrc.orig +0 -0
- data/sample/rocky-dot-trepanrc.rej +11 -0
- data/sample/rocky-dot-trepanxrc +14 -0
- data/sample/rocky-trepanx-colors.rb +39 -0
- data/test/data/fname-with-blank.right +3 -0
- data/test/data/inline-call.cmd +6 -0
- data/test/data/inline-call.right +13 -0
- data/test/data/quit.right +2 -0
- data/test/example/{gcd1.rb → gcd-server.rb} +4 -6
- data/test/example/gcd.rb +0 -0
- data/test/example/inline-call.rb +23 -0
- data/test/integration/helper.rb +8 -8
- data/test/integration/test-fname-with-blank.rb +5 -1
- data/test/integration/test-inline-call.rb +20 -0
- data/test/integration/test-quit.rb +5 -1
- data/test/unit/cmd-helper.rb +7 -4
- data/test/unit/mock-helper.rb +1 -0
- data/test/unit/test-app-brkpt.rb +4 -5
- data/test/unit/test-app-brkptmgr.rb +2 -2
- data/test/unit/test-app-iseq.rb +29 -14
- data/test/unit/test-app-options.rb +26 -5
- data/test/unit/test-base-subcmd.rb +1 -1
- data/test/unit/test-cmd-source.rb +34 -0
- data/test/unit/test-io-tcp.rb +33 -0
- data/test/unit/test-io-tcpclient.rb +53 -0
- data/test/unit/test-io-tcpfns.rb +17 -0
- data/test/unit/test-io-tcpserver.rb +50 -0
- data/test/unit/test-proc-main.rb +6 -2
- metadata +53 -10
- data/test/example/gcd-xx.rb +0 -18
@@ -4,32 +4,63 @@ require_relative './base/cmd'
|
|
4
4
|
class Trepan::Command::BacktraceCommand < Trepan::Command
|
5
5
|
ALIASES = %w(bt where)
|
6
6
|
CATEGORY = 'stack'
|
7
|
+
MAX_ARGS = 2 # Need at most this many
|
7
8
|
NAME = File.basename(__FILE__, '.rb')
|
8
9
|
HELP = <<-HELP
|
9
|
-
|
10
|
+
#{NAME} [full] [COUNT]
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
Print a backtrace of all stack frames, or innermost COUNT frames. Use
|
13
|
+
of the 'full' qualifier also prints the values of the local variables.
|
14
|
+
|
15
|
+
Passing "full" will also show the values of all locals variables in
|
16
|
+
each frame.
|
17
|
+
|
18
|
+
Normally outer frames which constitute debugger overhead are hidden
|
19
|
+
from view. However if a count is given and it runs into those hidden
|
20
|
+
frames, they will be shown.
|
21
|
+
|
22
|
+
Examples:
|
23
|
+
|
24
|
+
#{NAME}
|
25
|
+
#{NAME} full # show
|
26
|
+
#{NAME} 2
|
27
|
+
#{NAME} 3 full
|
28
|
+
#{NAME} full 3 # same as above
|
29
|
+
#{NAME} 1000 # probably will show any outer hidden frames
|
30
|
+
|
31
|
+
See also 'set hidelevel'.
|
13
32
|
HELP
|
14
33
|
NEED_STACK = true
|
15
34
|
SHORT_HELP = 'Show the current call stack'
|
16
35
|
|
17
36
|
def run(args)
|
18
|
-
|
19
|
-
verbose =
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
else
|
25
|
-
proc.stack_size
|
37
|
+
verbose_ary, count_ary = args[1..-1].partition {|item| item =~ /full/i}
|
38
|
+
verbose = !verbose_ary.empty?
|
39
|
+
|
40
|
+
if count_ary.size > 1
|
41
|
+
errmsg "Expecting only at most one parameter other than 'full'"
|
42
|
+
return
|
26
43
|
end
|
27
44
|
|
28
|
-
|
45
|
+
if 1 == count_ary.size
|
46
|
+
begin
|
47
|
+
count = Integer(count_ary[0])
|
48
|
+
rescue
|
49
|
+
errmsg "Expecting count to be an integer; got #{count_ary[0]}"
|
50
|
+
return
|
51
|
+
end
|
52
|
+
elsif 0 == count_ary.size
|
53
|
+
count = proc.stack_size
|
54
|
+
else
|
55
|
+
errmsg "Wrong number of parameters. Expecting at most 2."
|
56
|
+
return
|
57
|
+
end
|
29
58
|
|
30
59
|
@proc.dbgr.each_frame(@proc.top_frame) do |frame|
|
31
|
-
|
32
|
-
|
60
|
+
if count and frame.number >= count
|
61
|
+
msg "(More stack frames follow...)" if count != proc.stack_size
|
62
|
+
return
|
63
|
+
end
|
33
64
|
|
34
65
|
prefix = (frame == @proc.frame) ? '-->' : ' '
|
35
66
|
msg "%s #%d %s" % [prefix, frame.number,
|
@@ -43,4 +74,3 @@ in each frame.
|
|
43
74
|
end
|
44
75
|
end
|
45
76
|
end
|
46
|
-
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
3
3
|
# Base class of all commands. Code common to all commands is here.
|
4
4
|
# Note: don't end classname with Command (capital C) since main
|
5
5
|
# will think this a command name like QuitCommand
|
@@ -47,21 +47,21 @@ class Trepan
|
|
47
47
|
@proc.confirm(message, default)
|
48
48
|
end
|
49
49
|
|
50
|
-
def errmsg(message)
|
51
|
-
@proc.errmsg(message)
|
50
|
+
def errmsg(message, opts={})
|
51
|
+
@proc.errmsg(message, opts)
|
52
52
|
end
|
53
53
|
|
54
54
|
def obj_const(obj, name)
|
55
55
|
obj.class.const_get(name)
|
56
56
|
end
|
57
57
|
|
58
|
-
def msg(message)
|
59
|
-
@proc.msg(message)
|
58
|
+
def msg(message, opts={})
|
59
|
+
@proc.msg(message, opts)
|
60
60
|
end
|
61
61
|
|
62
62
|
# Convenience short-hand for @dbgr.intf[-1].msg_nocr
|
63
63
|
def msg_nocr(msg)
|
64
|
-
@proc.msg_nocr(msg)
|
64
|
+
@proc.msg_nocr(msg, opts={})
|
65
65
|
end
|
66
66
|
|
67
67
|
def my_const(name)
|
@@ -87,6 +87,10 @@ class Trepan
|
|
87
87
|
raise RuntimeError, 'You need to define this method elsewhere'
|
88
88
|
end
|
89
89
|
|
90
|
+
def section(message, opts={})
|
91
|
+
@proc.section(message, opts)
|
92
|
+
end
|
93
|
+
|
90
94
|
def settings
|
91
95
|
@proc.settings
|
92
96
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
3
3
|
# A base class for debugger subcommands.
|
4
4
|
#
|
5
5
|
# Note: don't end classname with Command (capital C) since main
|
@@ -194,6 +194,18 @@ class Trepan
|
|
194
194
|
|
195
195
|
end
|
196
196
|
|
197
|
+
module Trepanning
|
198
|
+
module Subcommand
|
199
|
+
module_function
|
200
|
+
def set_name_prefix(__file__, klass)
|
201
|
+
dirname = File.basename(File.dirname(File.expand_path(__file__)))
|
202
|
+
name = File.basename(__file__, '.rb')
|
203
|
+
klass.const_set('NAME', name)
|
204
|
+
klass.const_set('PREFIX', %W(#{dirname[0...-'_subcmd'.size]} #{name}))
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
197
209
|
if __FILE__ == $0
|
198
210
|
# Demo it.
|
199
211
|
require_relative '../../mock'
|
@@ -210,4 +222,7 @@ if __FILE__ == $0
|
|
210
222
|
# p subcmd.settings
|
211
223
|
# p subcmd.show_onoff(subcmd.settings[:autoeval])
|
212
224
|
# subcmd.run_set_int('', 'Just a test')
|
225
|
+
class Trepan::Subcommand::Foo < Trepan::Subcommand
|
226
|
+
Trepanning::Subcommand.set_name_prefix(__FILE__, self)
|
227
|
+
end
|
213
228
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
require 'rubygems'; require 'require_relative'
|
3
|
+
require_relative 'base/cmd'
|
4
|
+
class Trepan::Command::CompleteCommand < Trepan::Command
|
5
|
+
|
6
|
+
unless defined?(HELP)
|
7
|
+
HELP =
|
8
|
+
"complete COMMAND-PREFIX
|
9
|
+
|
10
|
+
List the completions for the rest of the line as a command.
|
11
|
+
|
12
|
+
NOTE: For now we just handle completion of the first token.
|
13
|
+
"
|
14
|
+
CATEGORY = 'support'
|
15
|
+
NAME = File.basename(__FILE__, '.rb')
|
16
|
+
NEED_STACK = false
|
17
|
+
SHORT_HELP = 'List the completions for the rest of the line as a command'
|
18
|
+
end
|
19
|
+
|
20
|
+
# This method runs the command
|
21
|
+
def run(args) # :nodoc
|
22
|
+
if args.size == 2
|
23
|
+
cmd_matches = @proc.commands.keys.select do |cmd|
|
24
|
+
cmd.start_with?(args[1])
|
25
|
+
end
|
26
|
+
alias_matches = @proc.aliases.keys.select do |cmd|
|
27
|
+
cmd.start_with?(args[1]) && !cmd_matches.member?(@proc.aliases[cmd])
|
28
|
+
end
|
29
|
+
(cmd_matches+alias_matches).sort.each do |match|
|
30
|
+
msg match
|
31
|
+
end
|
32
|
+
else # FIXME: handle more complex completions
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
if __FILE__ == $0
|
38
|
+
# Demo it.
|
39
|
+
require_relative '../mock'
|
40
|
+
dbgr, cmd = MockDebugger::setup
|
41
|
+
%w(d b bt).each do |prefix|
|
42
|
+
cmd.run [cmd.name, prefix]
|
43
|
+
puts '=' * 40
|
44
|
+
end
|
45
|
+
cmd.run %w(#{cmd.name} fdafsasfda)
|
46
|
+
puts '=' * 40
|
47
|
+
end
|
@@ -5,20 +5,21 @@ require_relative '../stepping'
|
|
5
5
|
class Trepan::Command::ContinueCommand < Trepan::Command
|
6
6
|
NAME = File.basename(__FILE__, '.rb')
|
7
7
|
HELP = <<-HELP
|
8
|
-
#{NAME} [breakpoint
|
8
|
+
#{NAME} [breakpoint-position]
|
9
9
|
|
10
10
|
Leave the debugger loop and continue execution. Subsequent entry to
|
11
11
|
the debugger however may occur via breakpoints or explicit calls, or
|
12
12
|
exceptions.
|
13
13
|
|
14
|
-
If a parameter is given, a
|
14
|
+
If a parameter is given, a one-time breakpoint is set at that position
|
15
15
|
before continuing.
|
16
16
|
|
17
17
|
Examples:
|
18
18
|
#{NAME}
|
19
19
|
#{NAME} 10 # continue to line 10
|
20
|
+
#{NAME} Array#map # beginning of next Array#map call
|
20
21
|
|
21
|
-
See also 'step', 'next', and 'nexti' commands.
|
22
|
+
See also 'step', 'next', 'finish', and 'nexti' commands.
|
22
23
|
HELP
|
23
24
|
ALIASES = %w(c cont)
|
24
25
|
CATEGORY = 'running'
|
@@ -9,6 +9,8 @@ class Trepan::Command::DirectoryCommand < Trepan::Command
|
|
9
9
|
MAX_ARGS = 1 # Need at most this many
|
10
10
|
NAME = File.basename(__FILE__, '.rb')
|
11
11
|
HELP = <<-HELP
|
12
|
+
#{NAME} [DIR]
|
13
|
+
|
12
14
|
Add directory DIR to beginning of search path for source files.
|
13
15
|
DIR can also be $cwd for the current working directory, or $cdir for the
|
14
16
|
directory in which the debugged file start.
|
@@ -16,7 +18,12 @@ With no argument, reset the search path to $cdir:$cwd, the default.
|
|
16
18
|
|
17
19
|
This command may be useful for debugging into Rubinius methods such as
|
18
20
|
kernel/common/module.rb if have the source code somewhere.
|
21
|
+
|
22
|
+
Examples:
|
23
|
+
#{NAME} ~/.rvm/src/rbx-head # Adds an rvm-like directory to path
|
24
|
+
#{NAME} # reset to $cdir:$cwd
|
19
25
|
HELP
|
26
|
+
|
20
27
|
SHORT_HELP =
|
21
28
|
'Add directory DIR to beginning of search path for source files'
|
22
29
|
end
|
@@ -24,7 +31,8 @@ kernel/common/module.rb if have the source code somewhere.
|
|
24
31
|
# This method runs the command
|
25
32
|
def run(args) # :nodoc
|
26
33
|
if args.size > 1
|
27
|
-
|
34
|
+
path = File.expand_path(args[1])
|
35
|
+
settings[:directory] = "#{path}:#{settings[:directory]}"
|
28
36
|
msg "Source directories searched: #{settings[:directory]}"
|
29
37
|
else
|
30
38
|
if confirm('Reintialize source path to empty?', false)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
1
3
|
require 'rubygems'; require 'require_relative'
|
2
4
|
require_relative './base/cmd'
|
3
5
|
require_relative '../../app/iseq'
|
@@ -32,6 +34,8 @@ Examples:
|
|
32
34
|
lines = cm.lines
|
33
35
|
next_line_ip = 0
|
34
36
|
next_i = 1
|
37
|
+
prefixes = []
|
38
|
+
disasm = ''
|
35
39
|
cm.decode.each do |insn|
|
36
40
|
show_line =
|
37
41
|
if insn.ip >= next_line_ip
|
@@ -43,8 +47,8 @@ Examples:
|
|
43
47
|
false
|
44
48
|
end
|
45
49
|
|
46
|
-
|
47
|
-
str =
|
50
|
+
prefixes << Trepan::ISeq::disasm_prefix(insn.ip, frame_ip, cm)
|
51
|
+
str = insn.to_s
|
48
52
|
if show_line
|
49
53
|
str +=
|
50
54
|
if insn.instance_variable_get('@comment')
|
@@ -56,7 +60,20 @@ Examples:
|
|
56
60
|
end
|
57
61
|
str += "# line: #{line_no}"
|
58
62
|
end
|
59
|
-
|
63
|
+
disasm += "#{str}\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
# FIXME DRY with ../disassemble.rb
|
67
|
+
if settings[:highlight]
|
68
|
+
require_relative '../../app/rbx-llvm'
|
69
|
+
@llvm_highlighter = CodeRay::Duo[:llvm, :term]
|
70
|
+
# llvm_scanner = CodeRay.scanner :llvm
|
71
|
+
# p llvm_scanner.tokenize(disasm)
|
72
|
+
disasm = @llvm_highlighter.encode(disasm)
|
73
|
+
end
|
74
|
+
|
75
|
+
disasm.split("\n").each_with_index do |inst, i|
|
76
|
+
msg ("#{prefixes[i]} #{inst}", :unlimited => true)
|
60
77
|
end
|
61
78
|
end
|
62
79
|
|
@@ -65,14 +82,12 @@ Examples:
|
|
65
82
|
if 1 == args.size
|
66
83
|
@proc.show_bytecode
|
67
84
|
elsif 'all' == args[1]
|
68
|
-
|
69
|
-
msg "Bytecode for #{@proc.frame.vm_location.describe}"
|
85
|
+
section "Bytecode for #{@proc.frame.vm_location.describe}"
|
70
86
|
disassemble_method(current_method)
|
71
87
|
else
|
72
88
|
cm = @proc.parse_method(args[1])
|
73
89
|
if cm
|
74
|
-
|
75
|
-
msg "Bytecode for method #{args[1]}"
|
90
|
+
section "Bytecode for method #{args[1]}"
|
76
91
|
disassemble_method(cm.executable)
|
77
92
|
else
|
78
93
|
errmsg "Method #{args[1]} not found"
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
3
|
+
require 'rubygems'; require 'require_relative'
|
4
|
+
require_relative 'base/cmd'
|
5
|
+
|
6
|
+
class Trepan::Command::DisplayCommand < Trepan::Command
|
7
|
+
|
8
|
+
unless defined?(HELP)
|
9
|
+
NAME = File.basename(__FILE__, '.rb')
|
10
|
+
HELP = <<-HELP
|
11
|
+
#{name} [format] EXP
|
12
|
+
|
13
|
+
Print value of expression EXP each time the program stops. FMT may be
|
14
|
+
used before EXP and may be one of 'c' for char, 'x' for hex, 'o' for
|
15
|
+
octal, 'f' for float or 's' for string.
|
16
|
+
|
17
|
+
For now, display expressions are only evaluated when in the same
|
18
|
+
instruction sequence as the frame that was in effect when the display
|
19
|
+
expression was set. This is a departure from gdb and we may allow for
|
20
|
+
more flexibility in the future to specify whether this should be the
|
21
|
+
case or not.
|
22
|
+
|
23
|
+
With no argument, evaluate and display all currently requested
|
24
|
+
auto-display expressions. Use "undisplay" to cancel display
|
25
|
+
requests previously made.
|
26
|
+
HELP
|
27
|
+
|
28
|
+
CATEGORY = 'data'
|
29
|
+
NEED_STACK = false
|
30
|
+
SHORT_HELP = 'Display expressions when entering debugger'
|
31
|
+
end
|
32
|
+
|
33
|
+
def run(args)
|
34
|
+
|
35
|
+
if args.size == 1
|
36
|
+
# Display anything active
|
37
|
+
@proc.run_eval_display
|
38
|
+
else
|
39
|
+
if %w(/c /x /o /f /s).member?(args[1])
|
40
|
+
if 2 == args.size
|
41
|
+
errmsg("Expecting an expression after the format")
|
42
|
+
return
|
43
|
+
end
|
44
|
+
format = args[1]
|
45
|
+
expr = args[2..-1].join(' ')
|
46
|
+
else
|
47
|
+
format = nil
|
48
|
+
expr = args[1..-1].join(' ')
|
49
|
+
end
|
50
|
+
|
51
|
+
dp = @proc.displays.add(@proc.frame, expr, format)
|
52
|
+
unless dp
|
53
|
+
errmsg('Error evaluating "%s" in the current frame' % expr)
|
54
|
+
return
|
55
|
+
end
|
56
|
+
msg(dp.to_s(@proc.frame))
|
57
|
+
@proc.cmdloop_prehooks.insert_if_new(5, *@proc.display_hook)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if __FILE__ == $0
|
63
|
+
# Demo it.
|
64
|
+
require_relative '../mock'
|
65
|
+
dbgr, cmd = MockDebugger::setup
|
66
|
+
|
67
|
+
def run_cmd(cmd, args)
|
68
|
+
cmd.run(args)
|
69
|
+
puts '==' * 10
|
70
|
+
end
|
71
|
+
|
72
|
+
# run_cmd(cmd, [cmd.name])
|
73
|
+
# run_cmd(cmd, [cmd.name, '/x', '10'])
|
74
|
+
# run_cmd(cmd, [cmd.name, 'd'])
|
75
|
+
# run_cmd(cmd, [cmd.name])
|
76
|
+
e = 5
|
77
|
+
vm_locations = Rubinius::VM.backtrace(0, true)
|
78
|
+
cmd.proc.instance_variable_set('@frame ',
|
79
|
+
Trepan::Frame.new(self, 0, vm_locations[0]))
|
80
|
+
|
81
|
+
run_cmd(cmd, [cmd.name, 'e'])
|
82
|
+
end
|
data/processor/command/eval.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
1
3
|
require 'rubygems'; require 'require_relative'
|
2
4
|
require_relative './base/cmd'
|
3
5
|
|
@@ -16,7 +18,7 @@ next to the inspect output of the value.
|
|
16
18
|
NEED_STACK = true
|
17
19
|
SHORT_HELP = 'Run code in the current context'
|
18
20
|
def run(args)
|
19
|
-
@proc.debug_eval(@proc.cmd_argstr,
|
21
|
+
@proc.debug_eval(@proc.cmd_argstr, settings[:maxstring])
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
data/processor/command/exit.rb
CHANGED
@@ -44,6 +44,10 @@ See also "kill".'
|
|
44
44
|
return
|
45
45
|
end
|
46
46
|
exitrc = (args.size > 1) ? exitrc = Integer(args[1]) rescue 0 : 0
|
47
|
+
|
48
|
+
# FIXME: funnel to sort of more general finalize routine
|
49
|
+
@proc.dbgr.intf[-1].close
|
50
|
+
|
47
51
|
# No graceful way to stop threads...
|
48
52
|
# A little harsh, but for now let's go with this.
|
49
53
|
exit! exitrc
|
data/processor/command/help.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
1
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require 'rubygems'; require 'require_relative'
|
3
3
|
require_relative 'base/cmd'
|
4
4
|
class Trepan::Command::HelpCommand < Trepan::Command
|
5
5
|
|
6
6
|
unless defined?(HELP)
|
7
|
-
|
8
|
-
|
7
|
+
NAME = File.basename(__FILE__, '.rb')
|
8
|
+
HELP = <<-HELP
|
9
|
+
#{NAME} [command [subcommand]|expression]
|
9
10
|
|
10
11
|
Without argument, print the list of available debugger commands.
|
11
12
|
|
@@ -22,8 +23,7 @@ subcommand. For example 'help info line' give help about the
|
|
22
23
|
info line command.
|
23
24
|
|
24
25
|
See also 'examine' and 'whatis'.
|
25
|
-
|
26
|
-
|
26
|
+
HELP
|
27
27
|
|
28
28
|
ALIASES = %w(?)
|
29
29
|
CATEGORIES = {
|
@@ -36,20 +36,21 @@ See also 'examine' and 'whatis'.
|
|
36
36
|
'stack' => 'Examining the call stack'
|
37
37
|
}
|
38
38
|
CATEGORY = 'support'
|
39
|
-
NAME = File.basename(__FILE__, '.rb')
|
40
39
|
NEED_STACK = false
|
41
40
|
SHORT_HELP = 'Print commands or give help for command(s)'
|
42
41
|
end
|
43
42
|
|
44
43
|
# List the command categories and a short description of each.
|
45
44
|
def list_categories
|
46
|
-
|
45
|
+
section 'Classes of commands:'
|
47
46
|
CATEGORIES.keys.sort.each do |cat|
|
48
47
|
msg("%-13s -- %s" % [cat, CATEGORIES[cat]])
|
49
48
|
end
|
50
49
|
final_msg = '
|
51
50
|
Type "help" followed by a class name for a list of commands in that class.
|
51
|
+
Type "help syntax" for information on debugger command syntax.
|
52
52
|
Type "help *" for the list of all commands.
|
53
|
+
Type "help all" for the list of all commands.
|
53
54
|
Type "help REGEXP" for the list of commands matching /^#{REGEXP}/
|
54
55
|
Type "help CLASS *" for the list of all commands in class CLASS.
|
55
56
|
Type "help" followed by command name for full documentation.
|
@@ -62,8 +63,14 @@ Type "help" followed by command name for full documentation.
|
|
62
63
|
if args.size > 1
|
63
64
|
cmd_name = args[1]
|
64
65
|
if cmd_name == '*'
|
65
|
-
|
66
|
+
section 'All command names:'
|
66
67
|
msg columnize_commands(@proc.commands.keys.sort)
|
68
|
+
elsif cmd_name =~ /^syntax$/i
|
69
|
+
show_command_syntax
|
70
|
+
elsif cmd_name =~ /^all$/i
|
71
|
+
CATEGORIES.sort.each do |category|
|
72
|
+
show_category(category[0], [])
|
73
|
+
end
|
67
74
|
elsif CATEGORIES.member?(cmd_name)
|
68
75
|
show_category(args[1], args[2..-1])
|
69
76
|
elsif @proc.commands.member?(cmd_name) or @proc.aliases.member?(cmd_name)
|
@@ -84,42 +91,87 @@ Type "help" followed by command name for full documentation.
|
|
84
91
|
msg "Aliases: #{cmd_obj.class.const_get(:ALIASES).join(', ')}"
|
85
92
|
end
|
86
93
|
end
|
87
|
-
else
|
94
|
+
else
|
88
95
|
matches = @proc.commands.keys.grep(/^#{cmd_name}/).sort rescue []
|
89
96
|
if matches.empty?
|
90
97
|
errmsg("No commands found matching /^#{cmd_name}/. Try \"help\".")
|
91
98
|
else
|
92
|
-
|
99
|
+
section "Command names matching /^#{cmd_name}/:"
|
93
100
|
msg columnize_commands(matches.sort)
|
94
101
|
end
|
95
102
|
end
|
96
103
|
else
|
97
104
|
list_categories
|
98
105
|
end
|
99
|
-
return false # Don't break out of cmd loop
|
100
106
|
end
|
101
107
|
|
102
108
|
# Show short help for all commands in `category'.
|
103
109
|
def show_category(category, args)
|
104
110
|
|
105
111
|
if args.size == 1 && args[0] == '*'
|
106
|
-
|
112
|
+
section "Commands in class %s:" % category
|
107
113
|
|
108
114
|
cmds = @proc.commands.keys.select do |cmd_name|
|
109
115
|
category == @proc.commands[cmd_name].category
|
110
116
|
end.sort
|
111
|
-
|
112
117
|
width = settings[:maxwidth]
|
113
118
|
return columnize_commands(cmds)
|
114
119
|
end
|
115
120
|
|
116
|
-
msg(
|
117
|
-
|
121
|
+
msg('')
|
122
|
+
section "Command class: %s" % category
|
123
|
+
msg('')
|
118
124
|
@proc.commands.keys.sort.each do |name|
|
119
125
|
next if category != @proc.commands[name].category
|
120
126
|
msg("%-13s -- %s" % [name, @proc.commands[name].short_help])
|
121
127
|
end
|
122
128
|
end
|
129
|
+
|
130
|
+
def show_command_syntax
|
131
|
+
section "Debugger command syntax"
|
132
|
+
msg <<-EOS
|
133
|
+
Command command syntax is very simple-minded.
|
134
|
+
|
135
|
+
If a line starts with #, the command is ignored.
|
136
|
+
If a line starts with !, the line is eval'd.
|
137
|
+
|
138
|
+
If the command you want eval'd uses the Ruby ! initally, add that
|
139
|
+
after the first !.
|
140
|
+
|
141
|
+
Commands are split at whereever ;; appears. This process disregards
|
142
|
+
any quotes or other symbols that have meaning in Ruby. The strings
|
143
|
+
after the leading command string are put back on a command queue.
|
144
|
+
|
145
|
+
Within a single command, tokens are then white-space split. Again,
|
146
|
+
this process disregards quotes or symbols that have meaning in Ruby.
|
147
|
+
|
148
|
+
The first token is then looked up in the debugger command table and
|
149
|
+
then the debugger alias table. If a match is found the command name
|
150
|
+
and arguments are dispatched to the command object that process the
|
151
|
+
command.
|
152
|
+
|
153
|
+
If the command is not found and "auto eval" is set on, then the
|
154
|
+
command is eval'd in the context that the program is currently stopped
|
155
|
+
at. If "auto eval" is not set on, then we display an error message
|
156
|
+
that the entered string is "undefined".
|
157
|
+
|
158
|
+
If you want irb-like command-processing, it's possible to go into an
|
159
|
+
irb shell with the "irb" command. It is also possible to arrange going
|
160
|
+
into an irb shell every time you enter the debugger.
|
161
|
+
|
162
|
+
Examples:
|
163
|
+
|
164
|
+
# This line does nothing. It is a comment
|
165
|
+
s # by default, this is an alias for the "step" command
|
166
|
+
!s # shows the value of variable step.
|
167
|
+
!!s # Evaluates !s (or "not s"). The first ! is indicates evaluate.
|
168
|
+
info program;; list # Runs two commands "info program" and "list"
|
169
|
+
pr "hi ;;-)" # Syntax error since ;; splits the line and " is not closed.
|
170
|
+
!puts "hi ;;-)" # One way to do the above.
|
171
|
+
|
172
|
+
See also "alias", "irb", "set auto eval", and "set auto irb".
|
173
|
+
EOS
|
174
|
+
end
|
123
175
|
end
|
124
176
|
|
125
177
|
if __FILE__ == $0
|
@@ -129,16 +181,15 @@ if __FILE__ == $0
|
|
129
181
|
|
130
182
|
cmd.run %W(#{cmd.name} help)
|
131
183
|
puts '=' * 40
|
132
|
-
cmd.run %
|
184
|
+
cmd.run %W(#{cmd.name} *)
|
133
185
|
puts '=' * 40
|
134
|
-
cmd.run %
|
186
|
+
cmd.run %W(#{cmd.name} fdafsasfda)
|
135
187
|
puts '=' * 40
|
136
188
|
cmd.run [cmd.name]
|
137
189
|
puts '=' * 40
|
138
190
|
cmd.run %W(#{cmd.name} support)
|
139
191
|
puts '=' * 40
|
140
192
|
cmd.run %W(#{cmd.name} support *)
|
141
|
-
|
142
193
|
puts '=' * 40
|
143
194
|
cmd.run %W(#{cmd.name} s.*)
|
144
195
|
puts '=' * 40
|
@@ -1,9 +1,12 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
1
3
|
require 'rubygems'; require 'require_relative'
|
2
4
|
require_relative '../base/subcmd'
|
3
5
|
|
4
6
|
class Trepan::Subcommand::InfoBreakpoints < Trepan::Subcommand
|
7
|
+
Trepanning::Subcommand.set_name_prefix(__FILE__, self)
|
5
8
|
HELP = <<-EOH
|
6
|
-
|
9
|
+
#{PREFIX.join(' ')} [num1 ...] [verbose]
|
7
10
|
|
8
11
|
Show status of user-settable breakpoints. If no breakpoint numbers are
|
9
12
|
given, the show all breakpoints. Otherwise only those breakpoints
|
@@ -18,15 +21,9 @@ The "enb" column indicates whether the breakpoint is enabled.
|
|
18
21
|
The "Where" column indicates where the breakpoint is located.
|
19
22
|
EOH
|
20
23
|
MIN_ABBREV = 'br'.size
|
21
|
-
NAME = File.basename(__FILE__, '.rb')
|
22
|
-
PREFIX = %w(info breakpoints)
|
23
24
|
SHORT_HELP = 'Status of user-settable breakpoints'
|
24
25
|
|
25
26
|
def run(args)
|
26
|
-
# FIXME: Originally was
|
27
|
-
# section "Breakpoints"
|
28
|
-
# Add section?
|
29
|
-
|
30
27
|
show_all =
|
31
28
|
if args.size > 2
|
32
29
|
opts = {
|
@@ -46,10 +43,11 @@ EOH
|
|
46
43
|
msg('No breakpoints.')
|
47
44
|
else
|
48
45
|
# There's at least one
|
46
|
+
section "Num Breakpoint"
|
49
47
|
bpmgr.list.each do |bp|
|
50
48
|
msg "%3d: %s" % [bp.id, bp.describe]
|
51
49
|
end
|
52
|
-
|
50
|
+
section 'Deferred breakpoints...'
|
53
51
|
@proc.dbgr.deferred_breakpoints.each_with_index do |bp, i|
|
54
52
|
if bp
|
55
53
|
msg "%3d: %s" % [i+1, bp.describe]
|