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
data/app/complete.rb
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
|
|
3
|
+
module 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/default.rb
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
require 'rubygems'; require 'require_relative'
|
|
3
|
+
module Trepan
|
|
4
|
+
# Default options to Trepan.start
|
|
5
|
+
DEFAULT_START_SETTINGS = {
|
|
6
|
+
:init => true, # Set $0 and save ARGV?
|
|
7
|
+
:post_mortem => false, # post-mortem debugging on uncaught exception?
|
|
8
|
+
:tracing => nil # Debugger.tracing value. true/false resets,
|
|
9
|
+
# nil keeps the prior value
|
|
10
|
+
} unless defined?(DEFAULT_START_SETTINGS)
|
|
11
|
+
|
|
12
|
+
# the port number used for remote debugging
|
|
13
|
+
PORT = 8989 unless defined?(PORT)
|
|
14
|
+
|
|
15
|
+
# What file is used for debugger startup commands.
|
|
16
|
+
unless defined?(CMD_INITFILE_BASE)
|
|
17
|
+
CMD_INITFILE_BASE =
|
|
18
|
+
if RUBY_PLATFORM =~ /mswin/
|
|
19
|
+
# Of course MS Windows has to be different
|
|
20
|
+
HOME_DIR = (ENV['HOME'] ||
|
|
21
|
+
ENV['HOMEDRIVE'].to_s + ENV['HOMEPATH'].to_s).to_s
|
|
22
|
+
'trepan8.ini'
|
|
23
|
+
else
|
|
24
|
+
HOME_DIR = ENV['HOME'].to_s
|
|
25
|
+
'.trepan8rc'
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
CMD_INITFILE = File.join(HOME_DIR, CMD_INITFILE_BASE) unless
|
|
30
|
+
defined?(CMD_INITFILE)
|
|
31
|
+
|
|
32
|
+
# Default settings for a Trepan class object
|
|
33
|
+
DEFAULT_SETTINGS = {
|
|
34
|
+
:cmdproc_opts => {}, # Default Trepan::CmdProcessor settings
|
|
35
|
+
:core_opts => {}, # Default Trepan::Core settings
|
|
36
|
+
:delete_restore => true, # Delete restore profile after reading?
|
|
37
|
+
:initial_dir => nil, # If --cd option was given, we save it here.
|
|
38
|
+
:nx => false, # Don't run user startup file (e.g. .trepanxrc)
|
|
39
|
+
:offset => 0, # skipping back +offset+ frames. This lets you start
|
|
40
|
+
# the debugger straight into callers method.
|
|
41
|
+
|
|
42
|
+
# Default values used only when 'server' or 'client'
|
|
43
|
+
# (out-of-process debugging)
|
|
44
|
+
:port => 1955,
|
|
45
|
+
:host => 'localhost',
|
|
46
|
+
|
|
47
|
+
:restart_argv => [],
|
|
48
|
+
:server => false # Out-of-process debugging?
|
|
49
|
+
} unless defined?(DEFAULT_SETTINGS)
|
|
50
|
+
|
|
51
|
+
# Default settings for Trepan run from the command line.
|
|
52
|
+
DEFAULT_CMDLINE_SETTINGS = {
|
|
53
|
+
:annotate => 0,
|
|
54
|
+
:client => false,
|
|
55
|
+
:control => false,
|
|
56
|
+
:cport => DEFAULT_SETTINGS[:port] + 1,
|
|
57
|
+
:frame_bind => false,
|
|
58
|
+
:host => DEFAULT_SETTINGS[:host],
|
|
59
|
+
:quit => true,
|
|
60
|
+
:rewrite_program => false,
|
|
61
|
+
:stop => true,
|
|
62
|
+
:nx => false,
|
|
63
|
+
:port => DEFAULT_SETTINGS[:port],
|
|
64
|
+
:post_mortem => false,
|
|
65
|
+
:readline => true, # try to use GNU readline?
|
|
66
|
+
:restart_script => nil,
|
|
67
|
+
:script => nil,
|
|
68
|
+
:server => false,
|
|
69
|
+
:tracing => false,
|
|
70
|
+
:verbose_long => false,
|
|
71
|
+
:wait => false,
|
|
72
|
+
:cmdfiles => [], # initialization command files to run
|
|
73
|
+
## :output => nil,
|
|
74
|
+
## Note that at most one of :server or :client can be true.
|
|
75
|
+
} unless defined?(DEFAULT_CMDLINE_SETTINGS)
|
|
76
|
+
|
|
77
|
+
class << self
|
|
78
|
+
attr_accessor :start_sentinal
|
|
79
|
+
# If start_sentinal is set, it is a string to look for in caller()
|
|
80
|
+
# and is used to see if the call stack is truncated. Is also
|
|
81
|
+
# defined in lib/trepanning.rb
|
|
82
|
+
start_sentinal = nil;
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
if __FILE__ == $0
|
|
87
|
+
# Show it:
|
|
88
|
+
require 'pp'
|
|
89
|
+
PP.pp(Trepan::CmdProcessor::DEFAULT_SETTINGS)
|
|
90
|
+
end
|
data/app/display.rb
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
# Classes to support gdb-like display/undisplay.
|
|
4
|
+
|
|
5
|
+
require 'rubygems'; require 'require_relative'
|
|
6
|
+
require_relative 'frame'
|
|
7
|
+
|
|
8
|
+
# return suitable frame signature to key display expressions off of.
|
|
9
|
+
def display_signature(frame)
|
|
10
|
+
return nil unless frame
|
|
11
|
+
frame.object_id
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Manage a list of display expressions.
|
|
15
|
+
class DisplayMgr
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
@next = 0
|
|
19
|
+
@list = []
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def add(frame, arg, fmt=nil)
|
|
23
|
+
return nil unless frame
|
|
24
|
+
begin
|
|
25
|
+
eval(arg, frame.binding)
|
|
26
|
+
rescue
|
|
27
|
+
return nil
|
|
28
|
+
end
|
|
29
|
+
@next += 1
|
|
30
|
+
d = Display.new(frame, arg, fmt, @next)
|
|
31
|
+
@list << d
|
|
32
|
+
d
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# List all display items; return 0 if none
|
|
36
|
+
def all
|
|
37
|
+
s = []
|
|
38
|
+
unless @list.empty?
|
|
39
|
+
s << "Auto-display expressions now in effect:
|
|
40
|
+
Num Enb Expression"
|
|
41
|
+
@list.each do |display|
|
|
42
|
+
s << display.format
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
s
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Delete all display expressions"""
|
|
49
|
+
def clear
|
|
50
|
+
@list = []
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Delete display expression i
|
|
54
|
+
def delete_index(display_number)
|
|
55
|
+
@list.each_with_index do |display, i|
|
|
56
|
+
if display_number == display.number
|
|
57
|
+
@list[i..i] = []
|
|
58
|
+
return true
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# display any items that are active'''
|
|
65
|
+
def display(frame)
|
|
66
|
+
return unless frame
|
|
67
|
+
s = []
|
|
68
|
+
sig = display_signature(frame)
|
|
69
|
+
@list.each do |display|
|
|
70
|
+
if display.enabled # && display.signature == sig
|
|
71
|
+
s << display.to_s(frame)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
return s
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def enable_disable(display_number, b_enable_disable)
|
|
78
|
+
@list.each do |display|
|
|
79
|
+
if display_number == display.number
|
|
80
|
+
display.enabled = b_enable_disable
|
|
81
|
+
return true
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
false
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
class Display
|
|
89
|
+
attr_reader :number
|
|
90
|
+
attr_reader :signature
|
|
91
|
+
attr_accessor :enabled
|
|
92
|
+
|
|
93
|
+
def initialize(frame, arg, fmt, number)
|
|
94
|
+
@signature = display_signature(frame)
|
|
95
|
+
@fmt = fmt
|
|
96
|
+
@arg = arg
|
|
97
|
+
@enabled = true
|
|
98
|
+
@number = number
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def to_s(frame)
|
|
102
|
+
return 'No symbol "' + @arg + '" in current context.' unless frame
|
|
103
|
+
|
|
104
|
+
begin
|
|
105
|
+
val = eval(@arg, frame.binding)
|
|
106
|
+
rescue
|
|
107
|
+
return "No symbol \"#{@arg}\" in current context."
|
|
108
|
+
end
|
|
109
|
+
s = "#{self.format(false)} = #{val}"
|
|
110
|
+
return s
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# format display item
|
|
114
|
+
def format(show_enabled=true)
|
|
115
|
+
what = ''
|
|
116
|
+
what += @enabled ? ' y ' : ' n ' if
|
|
117
|
+
show_enabled
|
|
118
|
+
what += (@fmt + ' ') if @fmt
|
|
119
|
+
what += @arg if @arg
|
|
120
|
+
'%3d: %s' % [@number, what]
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
if __FILE__ == $0
|
|
125
|
+
# Demo it.
|
|
126
|
+
mgr = DisplayMgr.new
|
|
127
|
+
|
|
128
|
+
def print_display(mgr)
|
|
129
|
+
mgr.all.each {|line| puts line}
|
|
130
|
+
puts '=' * 40
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
frame = Rubinius::VM.backtrace(0)[0]
|
|
134
|
+
|
|
135
|
+
x = 1
|
|
136
|
+
mgr.add(frame, 'x > 1')
|
|
137
|
+
print_display(mgr)
|
|
138
|
+
|
|
139
|
+
mgr.enable_disable(1, false)
|
|
140
|
+
print_display(mgr)
|
|
141
|
+
|
|
142
|
+
mgr.enable_disable(1, true)
|
|
143
|
+
print_display(mgr)
|
|
144
|
+
|
|
145
|
+
mgr.clear()
|
|
146
|
+
print_display(mgr)
|
|
147
|
+
|
|
148
|
+
end
|
data/app/eventbuffer.rb
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
module Trace
|
|
3
|
+
|
|
4
|
+
class EventBuffer
|
|
5
|
+
EventStruct = Struct.new(:event, :arg, :frame) unless defined?(EventStruct)
|
|
6
|
+
attr_reader :buf
|
|
7
|
+
attr_accessor :marks # User position mark into buffer. If buffer is limited,
|
|
8
|
+
attr_reader :maxsize # Maximum size of buffer or nil if unlimited.
|
|
9
|
+
attr_reader :size # size of buffer
|
|
10
|
+
# then marks will drop out as they disappear from the buffer
|
|
11
|
+
def initialize(maxsize=nil)
|
|
12
|
+
@maxsize = maxsize
|
|
13
|
+
reset
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def reset
|
|
17
|
+
@buf = []
|
|
18
|
+
@marks = []
|
|
19
|
+
@pos = -1
|
|
20
|
+
@size = 0
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Add a new event dropping off old events if that was declared
|
|
24
|
+
# marks are also dropped if buffer has a limit.
|
|
25
|
+
def append(event, frame, arg)
|
|
26
|
+
item = EventStruct.new(event, arg, frame)
|
|
27
|
+
@pos = self.succ_pos
|
|
28
|
+
@marks.shift if @marks[0] == @pos
|
|
29
|
+
@buf[@pos] = item
|
|
30
|
+
@size += 1 unless @maxsize && @size == @maxsize
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Add mark for the current event buffer position.
|
|
34
|
+
def add_mark
|
|
35
|
+
@marks << @pos
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Like add mark, but do only if the last marked position has
|
|
39
|
+
# changed
|
|
40
|
+
def add_mark_nodup
|
|
41
|
+
@marks << @pos unless @marks[-1] == @pos
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def each(from=nil, to=nil)
|
|
45
|
+
from = self.succ_pos unless from
|
|
46
|
+
to = @pos unless to
|
|
47
|
+
if from <= to
|
|
48
|
+
from.upto(to).each do |pos|
|
|
49
|
+
yield @buf[pos]
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
from.upto(@size-1).each do |pos|
|
|
53
|
+
yield @buf[pos]
|
|
54
|
+
end
|
|
55
|
+
0.upto(@pos).each do |pos|
|
|
56
|
+
yield @buf[pos]
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def each_with_index(from=nil, to=nil)
|
|
62
|
+
from = succ_pos unless from
|
|
63
|
+
to = @pos unless to
|
|
64
|
+
if from <= to
|
|
65
|
+
from.upto(to).each do |pos|
|
|
66
|
+
yield [@buf[pos], pos]
|
|
67
|
+
end
|
|
68
|
+
else
|
|
69
|
+
from.upto(@size-1).each do |pos|
|
|
70
|
+
yield [@buf[pos], pos]
|
|
71
|
+
end
|
|
72
|
+
0.upto(@pos).each do |pos|
|
|
73
|
+
yield [@buf[pos], pos]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def format_entry(item, long_format=true)
|
|
79
|
+
# require 'rbdbgr'; Debugger.debug
|
|
80
|
+
mess = "#{item.event} #{item.frame}"
|
|
81
|
+
# if long_format && item.iseq
|
|
82
|
+
# mess += "\n\t" + "VM offset #{item.pc_offset} of #{item.iseq.name}"
|
|
83
|
+
# end
|
|
84
|
+
mess
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Return the next event buffer position taking into account
|
|
88
|
+
# that we may have a fixed-sized buffer ring.
|
|
89
|
+
def succ_pos(inc=1)
|
|
90
|
+
pos = @pos + inc
|
|
91
|
+
@maxsize ? pos % @maxsize : pos
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Return the next event buffer position taking into account
|
|
95
|
+
# that we may have a fixed-sized buffer ring.
|
|
96
|
+
def pred_pos(dec=1)
|
|
97
|
+
pos = @pos - dec
|
|
98
|
+
@maxsize ? pos % @maxsize : pos
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Return the adjusted zeroth position in @buf.
|
|
102
|
+
def zero_pos
|
|
103
|
+
if !@maxsize || @buf.size < @maxsize
|
|
104
|
+
0
|
|
105
|
+
else
|
|
106
|
+
self.succ_pos
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end # EventBuffer
|
|
111
|
+
end # Trace
|
|
112
|
+
|
|
113
|
+
if __FILE__ == $0
|
|
114
|
+
def event_processor(event, frame, arg=nil)
|
|
115
|
+
begin
|
|
116
|
+
@eventbuf.append(event, frame, arg)
|
|
117
|
+
rescue
|
|
118
|
+
p $!
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
def dump_all
|
|
122
|
+
puts '-' * 40
|
|
123
|
+
@eventbuf.each do |e|
|
|
124
|
+
puts @eventbuf.format_entry(e) if e
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
require 'rubygems'; require 'set_trace'
|
|
129
|
+
@eventbuf = Trace::EventBuffer.new(5)
|
|
130
|
+
p @eventbuf.zero_pos
|
|
131
|
+
dump_all
|
|
132
|
+
|
|
133
|
+
# trace_filter = Trace::Filter.new
|
|
134
|
+
# trace_func = method(:event_processor).to_proc
|
|
135
|
+
# trace_filter << trace_func
|
|
136
|
+
# trace_filter.set_trace_func(trace_func)
|
|
137
|
+
# z=5
|
|
138
|
+
# z.times do |i|
|
|
139
|
+
# x = i
|
|
140
|
+
# y = x+2
|
|
141
|
+
# end
|
|
142
|
+
# trace_filter.set_trace_func(nil)
|
|
143
|
+
# p @eventbuf.buf[@eventbuf.zero_pos]
|
|
144
|
+
# dump_all
|
|
145
|
+
@eventbuf.reset
|
|
146
|
+
dump_all
|
|
147
|
+
end
|