trepanning 0.1.0 → 0.1.1
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 +4 -0
- data/ChangeLog +1279 -235
- data/Makefile +13 -0
- data/NEWS +30 -0
- data/Rakefile +50 -14
- data/app/.gitignore +1 -0
- data/app/breakpoint.rb +7 -2
- data/app/brkptmgr.rb +12 -0
- data/app/cmd_parse.citrus +167 -0
- data/app/cmd_parse.kpeg +221 -0
- data/app/cmd_parse.rb +201 -0
- data/app/cmd_parser.rb +1914 -0
- data/app/complete.rb +79 -0
- data/app/condition.rb +1 -1
- data/app/core.rb +7 -11
- data/app/default.rb +1 -1
- data/app/disassemble.rb +3 -2
- data/app/file.rb +12 -36
- data/app/frame.rb +3 -2
- data/app/irb.rb +9 -5
- data/app/iseq.rb +46 -0
- data/app/options.rb +6 -30
- data/app/run.rb +5 -2
- data/app/util.rb +1 -2
- data/app/yarv.rb +11 -1
- data/bin/.gitignore +1 -0
- data/bin/trepan +6 -6
- data/data/.gitignore +1 -0
- data/interface/.gitignore +1 -0
- data/interface/base_intf.rb +9 -5
- data/interface/comcodes.rb +10 -8
- data/interface/user.rb +76 -17
- data/io/.gitignore +1 -0
- data/io/input.rb +39 -15
- data/io/tcpclient.rb +7 -1
- data/io/tcpfns.rb +5 -3
- data/io/tcpserver.rb +13 -10
- data/lib/.gitignore +1 -0
- data/lib/trepanning.rb +50 -13
- data/processor/.gitignore +1 -0
- data/processor/Makefile +7 -0
- data/processor/breakpoint.rb +7 -2
- data/processor/command/.gitignore +1 -0
- data/processor/command/Makefile +7 -0
- data/processor/command/alias.rb +2 -2
- data/processor/command/backtrace.rb +4 -0
- data/processor/command/base/cmd.rb +45 -2
- data/processor/command/base/subcmd.rb +4 -2
- data/processor/command/base/submgr.rb +23 -19
- data/processor/command/base/subsubcmd.rb +23 -1
- data/processor/command/base/subsubmgr.rb +13 -0
- data/processor/command/break.rb +34 -29
- data/processor/command/complete.rb +37 -0
- data/processor/command/condition.rb +2 -0
- data/processor/command/continue.rb +15 -18
- data/processor/command/disassemble.rb +5 -0
- data/processor/command/down.rb +1 -1
- data/processor/command/eval.rb +70 -0
- data/processor/command/exit.rb +4 -1
- data/processor/command/finish.rb +6 -4
- data/processor/command/frame.rb +6 -3
- data/processor/command/help.rb +97 -54
- data/processor/command/help/.gitignore +1 -0
- data/processor/command/help/README +10 -0
- data/processor/command/help/command.txt +48 -0
- data/processor/command/help/filename.txt +40 -0
- data/processor/command/help/location.txt +37 -0
- data/processor/command/info_subcmd/.gitignore +1 -0
- data/processor/command/info_subcmd/breakpoints.rb +9 -9
- data/processor/command/info_subcmd/{file.rb → files.rb} +92 -27
- data/processor/command/info_subcmd/frame.rb +41 -15
- data/processor/command/info_subcmd/iseq.rb +39 -17
- data/processor/command/info_subcmd/program.rb +2 -8
- data/processor/command/info_subcmd/registers.rb +12 -10
- data/processor/command/info_subcmd/registers_subcmd/.gitignore +1 -0
- data/processor/command/info_subcmd/ruby.rb +60 -0
- data/processor/command/irb.rb +26 -3
- data/processor/command/kill.rb +21 -10
- data/processor/command/list.rb +1 -1
- data/processor/command/macro.rb +37 -23
- data/processor/command/pr.rb +1 -1
- data/processor/command/reload.rb +4 -0
- data/processor/command/reload_subcmd/.gitignore +1 -0
- data/processor/command/restart.rb +9 -9
- data/processor/command/save.rb +29 -36
- data/processor/command/set_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/auto_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/confirm.rb +23 -0
- data/processor/command/set_subcmd/debug_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/different.rb +2 -0
- data/processor/command/set_subcmd/events.rb +2 -0
- data/processor/command/set_subcmd/max.rb +9 -12
- data/processor/command/set_subcmd/max_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/substitute_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/trace.rb +7 -13
- data/processor/command/set_subcmd/trace_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/trace_subcmd/buffer.rb +12 -27
- data/processor/command/set_subcmd/trace_subcmd/print.rb +10 -8
- data/processor/command/set_subcmd/trace_subcmd/var.rb +6 -10
- data/processor/command/show.rb +12 -1
- data/processor/command/show_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/alias.rb +11 -15
- data/processor/command/show_subcmd/auto_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/basename.rb +1 -9
- data/processor/command/show_subcmd/confirm.rb +25 -0
- data/processor/command/show_subcmd/debug_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/macro.rb +32 -14
- data/processor/command/show_subcmd/max_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/trace_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/trace_subcmd/buffer.rb +11 -31
- data/processor/command/show_subcmd/trace_subcmd/print.rb +4 -20
- data/processor/command/source.rb +7 -1
- data/processor/command/up.rb +7 -4
- data/processor/default.rb +3 -1
- data/processor/eval.rb +13 -0
- data/processor/eventbuf.rb +3 -2
- data/processor/frame.rb +19 -0
- data/processor/help.rb +20 -0
- data/processor/load_cmds.rb +143 -24
- data/processor/location.rb +61 -10
- data/processor/main.rb +30 -11
- data/processor/mock.rb +5 -3
- data/processor/msg.rb +17 -0
- data/processor/running.rb +1 -1
- data/processor/subcmd.rb +3 -2
- data/processor/validate.rb +173 -185
- data/sample/.gitignore +1 -0
- data/sample/list-terminal-colors.rb +139 -0
- data/sample/rocky-dot-trepanrc +14 -0
- data/sample/rocky-trepan-colors.rb +47 -0
- data/test/Makefile +7 -0
- data/test/data/.gitignore +1 -0
- data/test/data/debugger-stop.cmd +3 -0
- data/test/data/debugger-stop.right +5 -0
- data/test/data/fname-with-blank.right +0 -3
- data/test/data/quit.right +0 -1
- data/test/data/quit2.cmd +6 -0
- data/test/data/quit2.right +3 -0
- data/test/data/testing.cmd +1 -0
- data/test/example/.gitignore +1 -0
- data/test/example/debugger-stop.rb +14 -0
- data/test/functional/.gitignore +2 -0
- data/test/functional/fn_helper.rb +7 -9
- data/test/functional/test-break-long.rb +7 -7
- data/test/functional/test-break.rb +7 -7
- data/test/functional/test-condition.rb +4 -4
- data/test/functional/test-delete.rb +6 -5
- data/test/functional/test-eval.rb +115 -0
- data/test/functional/test-raise.rb +1 -1
- data/test/functional/test-return.rb +1 -1
- data/test/integration/.gitignore +2 -0
- data/test/integration/helper.rb +6 -3
- data/test/integration/test-debugger-stop.rb +22 -0
- data/test/integration/test-quit.rb +8 -0
- data/test/unit/.gitignore +1 -0
- data/test/unit/Makefile +7 -0
- data/test/unit/test-app-brkpt.rb +0 -1
- data/test/unit/test-app-cmd_parse.rb +107 -0
- data/test/unit/test-app-cmd_parser.rb +22 -0
- data/test/unit/test-app-complete.rb +38 -0
- data/test/unit/test-app-condition.rb +20 -0
- data/test/unit/test-app-iseq.rb +31 -0
- data/test/unit/test-app-options.rb +9 -1
- data/test/unit/test-app-util.rb +0 -1
- data/test/unit/test-base-cmd.rb +46 -0
- data/test/unit/test-base-subcmd.rb +11 -2
- data/test/unit/test-base-submgr.rb +23 -0
- data/test/unit/test-base-subsubcmd.rb +20 -0
- data/test/unit/test-cmd-break.rb +22 -23
- data/test/unit/test-cmd-help.rb +4 -0
- data/test/unit/test-completion.rb +43 -0
- data/test/unit/test-io-tcpclient.rb +3 -2
- data/test/unit/test-proc-load_cmds.rb +10 -1
- data/test/unit/test-proc-location.rb +39 -0
- data/test/unit/test-proc-main.rb +1 -1
- data/test/unit/test-proc-validate.rb +47 -31
- data/trepanning.gemspec +45 -0
- metadata +247 -179
- data/app/core.rb-consider +0 -198
- data/test/functional/tmp/b3.rb +0 -5
- data/test/functional/tmp/immediate-bug1.rb +0 -9
data/app/complete.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
|
3
|
+
class Trepan
|
4
|
+
|
5
|
+
# Command completion methods
|
6
|
+
module Complete
|
7
|
+
|
8
|
+
module_function
|
9
|
+
|
10
|
+
# Return an Array of String found from Array of String
|
11
|
+
# +complete_ary+ which start out with String +prefix+.
|
12
|
+
def complete_token(complete_ary, prefix)
|
13
|
+
complete_ary.select { |cmd| cmd.to_s.start_with?(prefix) }.sort
|
14
|
+
end
|
15
|
+
|
16
|
+
def complete_token_with_next(complete_hash, prefix, cmd_prefix='')
|
17
|
+
result = []
|
18
|
+
complete_hash.each do |cmd_name, cmd_obj|
|
19
|
+
result << [cmd_name.to_s[cmd_prefix.size..-1], cmd_obj] if
|
20
|
+
cmd_name.to_s.start_with?(cmd_prefix + prefix)
|
21
|
+
end
|
22
|
+
result.sort{|a, b| a[0] <=> b[0]}
|
23
|
+
end
|
24
|
+
|
25
|
+
# Find all starting matches in Hash +aliases+ that start with +prefix+,
|
26
|
+
# but filter out any matches already in +expanded+.
|
27
|
+
def complete_token_filtered(aliases, prefix, expanded)
|
28
|
+
complete_ary = aliases.keys
|
29
|
+
complete_ary.select { |cmd|
|
30
|
+
cmd.to_s.start_with?(prefix) && ! expanded.member?(aliases[cmd])}.sort
|
31
|
+
end
|
32
|
+
|
33
|
+
# Find all starting matches in Hash +aliases+ that start with +prefix+,
|
34
|
+
# but filter out any matches already in +expanded+.
|
35
|
+
def complete_token_filtered_with_next(aliases, prefix, expanded,
|
36
|
+
commands)
|
37
|
+
complete_ary = aliases.keys
|
38
|
+
expanded_ary = expanded.keys
|
39
|
+
result = []
|
40
|
+
complete_ary.each do |cmd|
|
41
|
+
if cmd.to_s.start_with?(prefix) &&
|
42
|
+
!expanded_ary.member?(aliases[cmd])
|
43
|
+
result << [cmd, commands[aliases[cmd]]]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
# Find the next token in str string from start_pos, we return
|
50
|
+
# the token and the next blank position after the token or
|
51
|
+
# str.size if this is the last token. Tokens are delimited by
|
52
|
+
# white space.
|
53
|
+
def next_token(str, start_pos)
|
54
|
+
look_at = str[start_pos..-1]
|
55
|
+
next_nonblank_pos = start_pos + (look_at =~ /\S/ || 0)
|
56
|
+
next_blank_pos =
|
57
|
+
if next_match = str[next_nonblank_pos..-1] =~ /\s/
|
58
|
+
next_nonblank_pos + next_match
|
59
|
+
else
|
60
|
+
str.size
|
61
|
+
end
|
62
|
+
return [next_blank_pos, str[next_nonblank_pos...next_blank_pos]]
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
if __FILE__ == $0
|
69
|
+
include Trepan::Complete
|
70
|
+
hash = {'ab' => 1, 'aac' => 2, 'aa' => 3, 'b' => 4}
|
71
|
+
p complete_token(hash.keys, 'a')
|
72
|
+
p complete_token_with_next(hash, 'a')
|
73
|
+
## 0 1
|
74
|
+
## 0123456789012345678
|
75
|
+
x = ' now is the time'
|
76
|
+
[0, 2, 5, 8, 9, 13, 19].each do |pos|
|
77
|
+
p next_token(x, pos)
|
78
|
+
end
|
79
|
+
end
|
data/app/condition.rb
CHANGED
data/app/core.rb
CHANGED
@@ -42,7 +42,8 @@ class Trepan
|
|
42
42
|
STEPPING_EVENT_MASK =
|
43
43
|
LINE_EVENT_MASK | CLASS_EVENT_MASK | CALL_EVENT_MASK |
|
44
44
|
RETURN_EVENT_MASK | C_CALL_EVENT_MASK | C_RETURN_EVENT_MASK |
|
45
|
-
INSN_EVENT_MASK | BRKPT_EVENT_MASK
|
45
|
+
INSN_EVENT_MASK | BRKPT_EVENT_MASK | YIELD_EVENT_MASK |
|
46
|
+
LEAVE_EVENT_MASK | SEND_EVENT_MASK
|
46
47
|
|
47
48
|
ASYNC_EVENT_MASK =
|
48
49
|
RAISE_EVENT_MASK | VM_EVENT_MASK | SWITCH_EVENT_MASK
|
@@ -54,17 +55,12 @@ class Trepan
|
|
54
55
|
:step_count => 0, # Stop at next event
|
55
56
|
:async_events => ASYNC_EVENT_MASK,
|
56
57
|
|
57
|
-
#
|
58
|
-
#
|
59
|
-
# up ThreadFrame pointers and information. When this is fixed we can do the below.
|
60
|
-
# Until then we need to at least remove C calls and returns and possibly other
|
61
|
-
# events as well.
|
62
|
-
# :step_events =>
|
63
|
-
# (DEFAULT_EVENT_MASK | INSN_EVENT_MASK)
|
64
|
-
|
58
|
+
# Not sure what the "right" set really is. The below is just
|
59
|
+
# a guess. Use "set events" or customize in ~/.trepanrc
|
65
60
|
:step_events =>
|
66
|
-
(DEFAULT_EVENT_MASK | INSN_EVENT_MASK) &
|
67
|
-
|
61
|
+
# (DEFAULT_EVENT_MASK | INSN_EVENT_MASK) &
|
62
|
+
(DEFAULT_EVENT_MASK ) &
|
63
|
+
~(C_CALL_EVENT_MASK | C_RETURN_EVENT_MASK | SEND_EVENT_MASK)
|
68
64
|
}
|
69
65
|
|
70
66
|
end
|
data/app/default.rb
CHANGED
@@ -20,7 +20,6 @@ class Trepan
|
|
20
20
|
|
21
21
|
:restart_argv => RubyVM::OS_ARGV,
|
22
22
|
# Command run when "restart" is given.
|
23
|
-
:restore_profile => nil, # Profile used to set/restore debugger state
|
24
23
|
:server => false, # Out-of-process debugging?
|
25
24
|
} unless defined?(DEFAULT_SETTINGS)
|
26
25
|
|
@@ -33,6 +32,7 @@ class Trepan
|
|
33
32
|
:port => DEFAULT_SETTINGS[:port],
|
34
33
|
:host => DEFAULT_SETTINGS[:host],
|
35
34
|
:server => false, # Out-of-process debugging?
|
35
|
+
:readline => true, # Try to use GNU Readline?
|
36
36
|
# Note that at most one of :server or :client can be true.
|
37
37
|
} unless defined?(DEFAULT_CMDLINE_SETTINGS)
|
38
38
|
|
data/app/disassemble.rb
CHANGED
@@ -6,12 +6,13 @@
|
|
6
6
|
|
7
7
|
class Trepan
|
8
8
|
module Disassemble
|
9
|
+
# FIXME: turn final optional params into a hash.
|
9
10
|
def mark_disassembly(disassembly_str, iseq_equal, pc_offset,
|
10
11
|
brkpt_offsets=[], max_width=80, highlight=nil)
|
11
12
|
|
12
13
|
if highlight
|
13
14
|
require_relative '../app/yarv'
|
14
|
-
highlighter
|
15
|
+
@highlighter ||= CodeRay::Duo[:yarv, :term]
|
15
16
|
end
|
16
17
|
|
17
18
|
dis_array = disassembly_str.split(/\n/)
|
@@ -44,7 +45,7 @@ class Trepan
|
|
44
45
|
line_padding = ' ' * (line_padding.size - shrink_amount)
|
45
46
|
end
|
46
47
|
if highlight && prefix != ''
|
47
|
-
prefix + highlighter.encode(line_begin + line_padding + line_end)
|
48
|
+
prefix + @highlighter.encode(line_begin + line_padding + line_end)
|
48
49
|
else
|
49
50
|
prefix + line_begin + line_padding + line_end
|
50
51
|
end
|
data/app/file.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
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
|
# Things related to file/module status
|
4
4
|
require 'thread_frame'
|
5
|
+
require_relative 'iseq'
|
5
6
|
|
6
7
|
SCRIPT_ISEQS__ = {} unless
|
7
8
|
defined?(SCRIPT_ISEQS__) && SCRIPT_ISEQS__.is_a?(Hash)
|
@@ -45,11 +46,6 @@ module Trepanning
|
|
45
46
|
return [scripts, rejected]
|
46
47
|
end
|
47
48
|
|
48
|
-
def find_scripts(filename)
|
49
|
-
filename_pat = file_match_pat(filename)
|
50
|
-
return SCRIPT_ISEQS__.keys.grep(/#{filename_pat}/)
|
51
|
-
end
|
52
|
-
|
53
49
|
def find_iseqs(iseqs_hash, name)
|
54
50
|
iseq_name, filename = name.split(/@/)
|
55
51
|
return [] unless iseqs_hash.member?(iseq_name)
|
@@ -66,42 +62,19 @@ module Trepanning
|
|
66
62
|
def find_iseqs_with_lineno(filename, lineno)
|
67
63
|
files = find_scripts(filename)
|
68
64
|
files.each do |file|
|
69
|
-
|
70
|
-
|
71
|
-
|
65
|
+
SCRIPT_ISEQS__[file].each do |iseq|
|
66
|
+
found_iseq = find_iseq_with_line_from_iseq(iseq, lineno, true)
|
67
|
+
return found_iseq if found_iseq
|
72
68
|
end
|
73
|
-
return found if found
|
74
69
|
end
|
75
70
|
return nil
|
76
71
|
end
|
77
72
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
# Make sure it works for C:\foo\bar.rb:12
|
82
|
-
def parse_position(errmsg, arg)
|
83
|
-
colon = arg.rindex(':')
|
84
|
-
if colon
|
85
|
-
# FIXME: Handle double colons, e.g. File::open
|
86
|
-
filename = arg[0..colon-1].rstrip
|
87
|
-
m, f = lookupmodule(filename)
|
88
|
-
if not f
|
89
|
-
errmsg.call("'%s' not found using sys.path" % filename)
|
90
|
-
return nil, nil, nil
|
91
|
-
else
|
92
|
-
filename = f
|
93
|
-
arg = arg[colon+1..-1].lstrip
|
94
|
-
end
|
95
|
-
begin
|
96
|
-
lineno = Integer(arg)
|
97
|
-
rescue
|
98
|
-
errmsg.call("Bad line number: %s", arg)
|
99
|
-
return nil, filename, nil
|
100
|
-
end
|
101
|
-
return nil, filename, lineno
|
102
|
-
end
|
103
|
-
return nil, nil, nil
|
73
|
+
def find_scripts(filename)
|
74
|
+
filename_pat = file_match_pat(filename)
|
75
|
+
return SCRIPT_ISEQS__.keys.grep(/#{filename_pat}/)
|
104
76
|
end
|
77
|
+
|
105
78
|
end
|
106
79
|
# Demo it
|
107
80
|
if __FILE__ == $0
|
@@ -131,5 +104,8 @@ if __FILE__ == $0
|
|
131
104
|
p rejected.keys
|
132
105
|
puts '-' * 20
|
133
106
|
p SCRIPT_ISEQS__.keys
|
107
|
+
# require_relative '../lib/trepanning'; debugger
|
108
|
+
p find_iseqs_with_lineno(__FILE__, __LINE__)
|
109
|
+
p find_iseqs(ISEQS__, 'find_scripts')
|
134
110
|
end
|
135
111
|
end
|
data/app/frame.rb
CHANGED
data/app/irb.rb
CHANGED
@@ -44,7 +44,11 @@ module IRB # :nodoc:
|
|
44
44
|
opts.join(' ')
|
45
45
|
end
|
46
46
|
dbg_cmdproc = conf.workspace.instance_variable_get('@dbg_cmdproc')
|
47
|
-
dbg_cmdproc
|
47
|
+
if dbg_cmdproc
|
48
|
+
dbg_cmdproc.run_command($trepan_command)
|
49
|
+
else
|
50
|
+
puts "Something's wrong with debugger setup of irb"
|
51
|
+
end
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
@@ -69,7 +73,7 @@ module IRB # :nodoc:
|
|
69
73
|
def self.start_session(binding, dbg_cmdproc, conf={})
|
70
74
|
unless @__initialized
|
71
75
|
|
72
|
-
# Set to run the standard
|
76
|
+
# Set to run the standard trepan IRB profile
|
73
77
|
irbrc = File.expand_path(File.join(File.dirname(__FILE__),
|
74
78
|
%w(.. data irbrc)))
|
75
79
|
ENV['IRBRC'] = irbrc
|
@@ -80,8 +84,8 @@ module IRB # :nodoc:
|
|
80
84
|
ARGV.replace(args)
|
81
85
|
|
82
86
|
# If the user has a IRB profile, run that now.
|
83
|
-
if ENV['
|
84
|
-
ENV['IRBRC'] = ENV['
|
87
|
+
if ENV['TREPAN_IRB']
|
88
|
+
ENV['IRBRC'] = ENV['TREPAN_IRB']
|
85
89
|
@CONF[:RC_NAME_GENERATOR]=nil
|
86
90
|
IRB.run_config
|
87
91
|
end
|
@@ -90,7 +94,7 @@ module IRB # :nodoc:
|
|
90
94
|
end
|
91
95
|
|
92
96
|
workspace = WorkSpace.new(binding)
|
93
|
-
workspace.instance_variable_set('@dbg_cmdproc', dbg_cmdproc)
|
97
|
+
# workspace.instance_variable_set('@dbg_cmdproc', dbg_cmdproc)
|
94
98
|
|
95
99
|
irb = Irb.new(workspace)
|
96
100
|
|
data/app/iseq.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
3
|
+
# Things related to RubyVM::InstructionSequence's
|
4
|
+
|
5
|
+
module Trepanning
|
6
|
+
# Returns a RubyVM::Instruction for the specified line. We search the
|
7
|
+
# current instruction sequence +iseq+ and then up the parent scope. If we hit
|
8
|
+
# the top and we can't find +line+ that way, then we
|
9
|
+
# reverse the search from the top and search down. This will add
|
10
|
+
# all siblings of ancestors of +meth+.
|
11
|
+
# Similar to rbx-trepanning method "find_method_with_line".
|
12
|
+
def find_iseq_with_line_from_iseq(iseq, lineno, go_up=true)
|
13
|
+
find_iseq_with_line_from_iseq2(iseq, lineno, go_up, {})
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_iseq_with_line_from_iseq2(iseq, lineno, go_up, seen)
|
17
|
+
return iseq if iseq.offsetlines.values.flatten.uniq.member?(lineno)
|
18
|
+
seen[iseq] = true
|
19
|
+
prev_iseq = iseq
|
20
|
+
while prev_iseq = prev_iseq.parent
|
21
|
+
iseq = prev_iseq
|
22
|
+
return iseq if iseq.offsetlines.values.flatten.uniq.member?(lineno)
|
23
|
+
end if go_up
|
24
|
+
# At top and not found so now go down..
|
25
|
+
iseq.child_iseqs.each do |child_iseq|
|
26
|
+
next if seen[child_iseq] # we tried before
|
27
|
+
# puts "#{child_iseq.name}, #{child_iseq}"
|
28
|
+
result = find_iseq_with_line_from_iseq2(child_iseq, lineno, false, seen)
|
29
|
+
return result if result
|
30
|
+
end
|
31
|
+
return nil
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
# Demo it
|
36
|
+
# if __FILE__ == $0
|
37
|
+
# require 'thread_frame'
|
38
|
+
# include Trepanning
|
39
|
+
# if !(ARGV.size == 1 && ARGV[0] == 'noload')
|
40
|
+
# ISEQS__ = {}
|
41
|
+
# SCRIPT_ISEQS__ = {}
|
42
|
+
# ARGV[0..-1] = ['noload']
|
43
|
+
# load(__FILE__)
|
44
|
+
# else
|
45
|
+
# end
|
46
|
+
# end
|
data/app/options.rb
CHANGED
@@ -3,33 +3,12 @@
|
|
3
3
|
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
4
4
|
#=== Summary
|
5
5
|
# Parses command-line options.
|
6
|
-
#=== Options
|
7
|
-
#
|
8
|
-
#<tt>--cd=DIR</tt>
|
9
|
-
# Change current directory to DIR.
|
10
|
-
#
|
11
|
-
#<tt>--command</tt> <i>file</i>::
|
12
|
-
# Run debugger command file <i>file</i>
|
13
|
-
#
|
14
|
-
#<tt>--nx</tt>::
|
15
|
-
# Don’t execute commands found in any initialization
|
16
|
-
# files, e.g. <tt>.rdebugrc</tt>.
|
17
|
-
#
|
18
|
-
#<tt>--restore=PROFILE</tt>::
|
19
|
-
# Debugger command file which restores debugger settings,
|
20
|
-
# resumably saved before a 'restart' debugger command.
|
21
|
-
#
|
22
|
-
#<tt>--version</tt>::
|
23
|
-
# Show the version number.
|
24
|
-
#
|
25
|
-
#<tt>--help</tt>::
|
26
|
-
# Show invocation help and exit.
|
27
6
|
|
28
7
|
require 'optparse'
|
29
8
|
class Trepan
|
30
9
|
require_relative 'default'
|
31
10
|
|
32
|
-
Trepan::VERSION = '0.1.
|
11
|
+
Trepan::VERSION = '0.1.1'
|
33
12
|
Trepan::PROGRAM = 'trepan'
|
34
13
|
|
35
14
|
def self.show_version
|
@@ -102,13 +81,6 @@ EOB
|
|
102
81
|
|num|
|
103
82
|
options[:port] = num
|
104
83
|
end
|
105
|
-
opts.on("--restore PROFILE", String,
|
106
|
-
"Restore debugger state using PROFILE") do |profile|
|
107
|
-
if File.readable?(profile)
|
108
|
-
options[:restore_profile] = profile
|
109
|
-
stderr.puts "Debugger command file #{profile} is not readable. --restore option ignored."
|
110
|
-
end
|
111
|
-
end
|
112
84
|
opts.on('--server',
|
113
85
|
"Set up for out-of-process debugging") do
|
114
86
|
if options[:client]
|
@@ -118,9 +90,13 @@ EOB
|
|
118
90
|
end
|
119
91
|
end
|
120
92
|
opts.on('--[no-]highlight',
|
121
|
-
"
|
93
|
+
"Use [no] syntax highlight output") do |v|
|
122
94
|
options[:highlight] = ((v) ? :term : nil)
|
123
95
|
end
|
96
|
+
opts.on('--[no-]readline',
|
97
|
+
"Try [not] GNU Readline") do |v|
|
98
|
+
options[:readline] = v
|
99
|
+
end
|
124
100
|
opts.on_tail("-?", "--help", "Show this message") do
|
125
101
|
options[:help] = true
|
126
102
|
stdout.puts opts
|
data/app/run.rb
CHANGED
@@ -9,7 +9,7 @@ module Trepanning
|
|
9
9
|
# The caller must ensure that ARGV is set up to remove any debugger
|
10
10
|
# arguments or things that the debugged program isn't supposed to
|
11
11
|
# see. FIXME: Should we make ARGV an explicit parameter?
|
12
|
-
def debug_program(dbgr, ruby_path, program_to_debug)
|
12
|
+
def debug_program(dbgr, ruby_path, program_to_debug, start_opts={})
|
13
13
|
|
14
14
|
# Make sure Ruby script syntax checks okay.
|
15
15
|
# Otherwise we get a load message that looks like trepanning has
|
@@ -37,7 +37,10 @@ module Trepanning
|
|
37
37
|
dbgr.debugger(:hide_stack=>true) do
|
38
38
|
dbgr.core.processor.hidelevels[Thread.current] =
|
39
39
|
RubyVM::ThreadFrame.current.stack_size + 1
|
40
|
-
|
40
|
+
begin
|
41
|
+
Kernel::load program_to_debug
|
42
|
+
rescue Interrupt
|
43
|
+
end
|
41
44
|
end
|
42
45
|
|
43
46
|
# The dance we have to undo to restore $0 and undo the mess created
|
data/app/util.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
class Trepan
|
4
4
|
module Util
|
5
5
|
|
6
|
+
module_function
|
6
7
|
def safe_repr(str, max, elipsis='... ')
|
7
8
|
if str.is_a?(String) && str.size > max && !str.index("\n")
|
8
9
|
"%s%s%s" % [ str[0...max/2], elipsis, str[str.size-max/2..str.size]]
|
@@ -10,8 +11,6 @@ class Trepan
|
|
10
11
|
str
|
11
12
|
end
|
12
13
|
end
|
13
|
-
module_function :safe_repr
|
14
|
-
|
15
14
|
end
|
16
15
|
end
|
17
16
|
|