backtracer 0.1.0 → 0.2.0
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/README +87 -16
- data/VERSION +1 -1
- data/examples/crash.rb +3 -2
- data/lib/backtracer_tracer.rb +2 -0
- data/lib/backtracer_tracer_args.rb +3 -0
- data/lib/core_backtracer.rb +11 -8
- data/lib/tracerr.rb +168 -0
- metadata +7 -4
- /data/lib/{backtracer_all.rb → backtracer_locals.rb} +0 -0
data/README
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
-
ruby_backtracer:
|
1
|
+
ruby_backtracer: output higher quality backtraces if an unhandled exception occurs. Originally inspired by the frustration of seeling ...24 levels... a few too many times.
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
There are several options available (the more verbose ones rely on ruby-debug, which slows things down a bit).
|
4
|
+
|
5
|
+
ex:
|
6
|
+
a script used to output:
|
5
7
|
examples>ruby crash.rb
|
6
8
|
crash.rb:2:in `go2': unhandled exception
|
7
9
|
from crash.rb:6:in `go'
|
8
10
|
from crash.rb:9
|
9
11
|
|
10
|
-
now outputs:
|
11
|
-
examples>ruby -
|
12
|
+
Using backtracer, it now outputs:
|
13
|
+
examples>ruby -rbacktracer_locals crash.rb
|
12
14
|
|
13
15
|
unhandled exception: crash.rb:2: raise
|
14
16
|
locals: {"a"=>"3", "b"=>55}
|
@@ -17,23 +19,92 @@ unhandled exception: crash.rb:2: raise
|
|
17
19
|
locals: {"a"=>"3", "b"=>55}
|
18
20
|
crash.rb:5 go(a=>3)
|
19
21
|
locals: {"a"=>"3"}
|
22
|
+
or
|
23
|
+
examples>ruby -rbacktracer crash.rb
|
24
|
+
====
|
25
|
+
crash.rb:2:in `go2'
|
26
|
+
raise
|
27
|
+
crash.rb:7:in `go'
|
28
|
+
go2(a, 55)
|
29
|
+
crash.rb:10
|
30
|
+
go '3'
|
31
|
+
====
|
32
|
+
crash.rb:2:in `go2': unhandled exception
|
33
|
+
from crash.rb:7:in `go'
|
34
|
+
from crash.rb:10
|
35
|
+
|
36
|
+
|
37
|
+
All the options are backtracer, backtracer_locals, backtracer_simple, backtracer_tracer
|
38
|
+
|
39
|
+
|
40
|
+
== Installation ==
|
41
|
+
|
42
|
+
== 1.9 ==
|
43
|
+
|
44
|
+
$ gem install ruby-debug19
|
45
|
+
$ gem sources add http://gemcutter.org # if necessary
|
46
|
+
$ gem install backtracer
|
47
|
+
|
48
|
+
run as above
|
49
|
+
$ ruby -rbacktracer script_name
|
50
|
+
|
51
|
+
== 1.8.x ==
|
52
|
+
|
53
|
+
$ gem install ruby-debug
|
54
|
+
$ gem sources add http://gemcutter.org # if necessary
|
55
|
+
$ sudo gem install faster_rubygems # necessary to be able to load gems from the command line -- installs the file rubygemsf into your site_ruby
|
56
|
+
$ gem install backtracer
|
57
|
+
|
58
|
+
now run them like
|
59
|
+
$ ruby -rubygemsf -rbacktracer script_name
|
60
|
+
|
61
|
+
the rubygemsf is necessary because for some reason running
|
62
|
+
$ ruby -rubygems -rbacktracer script_name
|
63
|
+
|
64
|
+
fails [probably a bug in ruby]
|
65
|
+
|
66
|
+
== Descriptions ==
|
67
|
+
|
68
|
+
Try these out if desired:
|
69
|
+
create a file like:
|
70
|
+
|
71
|
+
def go(a)
|
72
|
+
raise
|
73
|
+
end
|
74
|
+
go(3)
|
75
|
+
|
76
|
+
then run ruby against it like
|
77
|
+
|
78
|
+
ruby -rbacktracer name
|
79
|
+
outputs full backtrace with code of each line [a la Python]
|
80
|
+
ruby -rbacktracer_locals name
|
81
|
+
outputs full backtrace with local variables and parameters
|
82
|
+
ruby -rbacktracer_simple name
|
83
|
+
outputs backtrace without the ...24 levels... [yea!]
|
84
|
+
ruby -backtracer_tracer name
|
85
|
+
same as backtracer_locals except it shows traces of calls as they're made
|
86
|
+
|
87
|
+
|
88
|
+
or in 1.8.x
|
89
|
+
ruby -rubygemsf -rbacktracer name
|
90
|
+
etc.
|
20
91
|
|
21
|
-
Now wasn't that prettier?
|
22
92
|
|
23
|
-
|
93
|
+
== Other ==
|
24
94
|
|
25
|
-
|
26
|
-
|
27
|
-
line in the middle (also no speed slowdown, and no local variables displayed).
|
95
|
+
Note that you can [if desired] load these within a script iself
|
96
|
+
require 'backtracer'
|
28
97
|
|
29
|
-
|
98
|
+
and it will output a backtrace if one exists at exit time.
|
30
99
|
|
31
|
-
|
100
|
+
You can also add it to your RUBYOPT variable if you always want it to run [backtracer_simple and backtracer don't cause any slowdown].
|
101
|
+
$ export RUBYOPT=-rbacktracer
|
32
102
|
|
33
|
-
|
103
|
+
if desired.
|
34
104
|
|
35
|
-
|
105
|
+
== Related projects ==
|
106
|
+
unroller, http://eigenclass.org/hiki/method+arguments+via+introspection, liveconsole, ruby-debug
|
36
107
|
|
37
|
-
|
108
|
+
Comments welcome to rdp on github.
|
38
109
|
|
39
|
-
|
110
|
+
http://github.com/rdp/backtracer
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/examples/crash.rb
CHANGED
data/lib/core_backtracer.rb
CHANGED
@@ -90,12 +90,14 @@ class Tracer
|
|
90
90
|
|
91
91
|
unless list = SCRIPT_LINES__[file]
|
92
92
|
begin
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
93
|
+
raise 'might be a .so file' if file =~ /\.so$/
|
94
|
+
f = open(file)
|
95
|
+
begin
|
96
|
+
SCRIPT_LINES__[file] = list = f.readlines
|
97
|
+
ensure
|
98
|
+
f.close
|
99
|
+
end
|
100
|
+
|
99
101
|
rescue
|
100
102
|
SCRIPT_LINES__[file] = list = []
|
101
103
|
end
|
@@ -143,7 +145,7 @@ class Tracer
|
|
143
145
|
|
144
146
|
saved_crit = Thread.critical
|
145
147
|
Thread.critical = true
|
146
|
-
# TODO only do the backtrace if last command was 'raise'
|
148
|
+
# TODO only do the backtrace if last command was 'raise'
|
147
149
|
if type == 'R'
|
148
150
|
Thread.current['backtrace'][@@depths[thread_no] - 1] = [[file, line], [], binding]
|
149
151
|
Thread.current['backtrace'] = Thread.current['backtrace'][0..@@depths[thread_no]] # clear old stuffs
|
@@ -163,7 +165,8 @@ class Tracer
|
|
163
165
|
else
|
164
166
|
print "WEIRD--please report err spot 1, how to reproduce"
|
165
167
|
end
|
166
|
-
|
168
|
+
|
169
|
+
print 'args were ', collected.inspect, "\n" if $VERBOSE # we still collect them for the end backtrace if !$VERBOSE
|
167
170
|
|
168
171
|
Thread.current['backtrace'][@@depths[thread_no] - 1] = [[@@last_file, @@last_line], collected, previous_frame_binding]
|
169
172
|
end
|
data/lib/tracerr.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
#
|
2
|
+
# tracer.rb -
|
3
|
+
# $Release Version: 0.2$
|
4
|
+
# $Revision: 1.8 $
|
5
|
+
# $Date: 1998/05/19 03:42:49 $
|
6
|
+
# by Keiju ISHITSUKA(Nippon Rational Inc.)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
#
|
14
|
+
# tracer main class
|
15
|
+
#
|
16
|
+
class Tracer
|
17
|
+
@RCS_ID='-$Id: tracer.rb,v 1.8 1998/05/19 03:42:49 keiju Exp keiju $-'
|
18
|
+
|
19
|
+
@stdout = STDOUT
|
20
|
+
@verbose = false
|
21
|
+
class << self
|
22
|
+
attr :verbose, true
|
23
|
+
alias verbose? verbose
|
24
|
+
attr :stdout, true
|
25
|
+
end
|
26
|
+
|
27
|
+
EVENT_SYMBOL = {
|
28
|
+
"line" => "-",
|
29
|
+
"call" => ">",
|
30
|
+
"return" => "<",
|
31
|
+
"class" => "C",
|
32
|
+
"end" => "E",
|
33
|
+
"c-call" => ">",
|
34
|
+
"c-return" => "<",
|
35
|
+
}
|
36
|
+
|
37
|
+
def initialize
|
38
|
+
@threads = Hash.new
|
39
|
+
if defined? Thread.main
|
40
|
+
@threads[Thread.main.object_id] = 0
|
41
|
+
else
|
42
|
+
@threads[Thread.current.object_id] = 0
|
43
|
+
end
|
44
|
+
|
45
|
+
@get_line_procs = {}
|
46
|
+
|
47
|
+
@filters = []
|
48
|
+
end
|
49
|
+
|
50
|
+
def stdout
|
51
|
+
Tracer.stdout
|
52
|
+
end
|
53
|
+
|
54
|
+
def on
|
55
|
+
if block_given?
|
56
|
+
on
|
57
|
+
begin
|
58
|
+
yield
|
59
|
+
ensure
|
60
|
+
off
|
61
|
+
end
|
62
|
+
else
|
63
|
+
set_trace_func method(:trace_func).to_proc
|
64
|
+
stdout.print "Trace on\n" if Tracer.verbose?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def off
|
69
|
+
set_trace_func nil
|
70
|
+
stdout.print "Trace off\n" if Tracer.verbose?
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_filter(p = proc)
|
74
|
+
@filters.push p
|
75
|
+
end
|
76
|
+
|
77
|
+
def set_get_line_procs(file, p = proc)
|
78
|
+
@get_line_procs[file] = p
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_line(file, line)
|
82
|
+
if p = @get_line_procs[file]
|
83
|
+
return p.call(line)
|
84
|
+
end
|
85
|
+
|
86
|
+
unless list = SCRIPT_LINES__[file]
|
87
|
+
begin
|
88
|
+
raise 'binary file' if file =~ /\.so$/
|
89
|
+
f = open(file)
|
90
|
+
begin
|
91
|
+
SCRIPT_LINES__[file] = list = f.readlines
|
92
|
+
ensure
|
93
|
+
f.close
|
94
|
+
end
|
95
|
+
rescue
|
96
|
+
SCRIPT_LINES__[file] = list = []
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
if l = list[line - 1]
|
101
|
+
l
|
102
|
+
else
|
103
|
+
"-\n"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def get_thread_no
|
108
|
+
if no = @threads[Thread.current.object_id]
|
109
|
+
no
|
110
|
+
else
|
111
|
+
@threads[Thread.current.object_id] = @threads.size
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def trace_func(event, file, line, id, binding, klass, *)
|
116
|
+
return if file == __FILE__
|
117
|
+
|
118
|
+
for p in @filters
|
119
|
+
return unless p.call event, file, line, id, binding, klass
|
120
|
+
end
|
121
|
+
|
122
|
+
saved_crit = Thread.critical
|
123
|
+
Thread.critical = true
|
124
|
+
stdout.printf("#%d:%s:%d:%s:%s: %s",
|
125
|
+
get_thread_no,
|
126
|
+
file,
|
127
|
+
line,
|
128
|
+
klass || '',
|
129
|
+
EVENT_SYMBOL[event],
|
130
|
+
get_line(file, line))
|
131
|
+
Thread.critical = saved_crit
|
132
|
+
end
|
133
|
+
|
134
|
+
Single = new
|
135
|
+
def Tracer.on
|
136
|
+
if block_given?
|
137
|
+
Single.on{yield}
|
138
|
+
else
|
139
|
+
Single.on
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def Tracer.off
|
144
|
+
Single.off
|
145
|
+
end
|
146
|
+
|
147
|
+
def Tracer.set_get_line_procs(file_name, p = proc)
|
148
|
+
Single.set_get_line_procs(file_name, p)
|
149
|
+
end
|
150
|
+
|
151
|
+
def Tracer.add_filter(p = proc)
|
152
|
+
Single.add_filter(p)
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
|
158
|
+
|
159
|
+
if $0 == __FILE__
|
160
|
+
# direct call
|
161
|
+
|
162
|
+
$0 = ARGV[0]
|
163
|
+
ARGV.shift
|
164
|
+
Tracer.on
|
165
|
+
require $0
|
166
|
+
elsif caller(0).size == 1
|
167
|
+
Tracer.on
|
168
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backtracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors: []
|
7
7
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-03 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -32,9 +32,12 @@ files:
|
|
32
32
|
- examples/run_all_styles_of_backtracer.rb
|
33
33
|
- examples/run_large_style_output.rb
|
34
34
|
- lib/backtracer.rb
|
35
|
-
- lib/
|
35
|
+
- lib/backtracer_locals.rb
|
36
36
|
- lib/backtracer_simple.rb
|
37
|
+
- lib/backtracer_tracer.rb
|
38
|
+
- lib/backtracer_tracer_args.rb
|
37
39
|
- lib/core_backtracer.rb
|
40
|
+
- lib/tracerr.rb
|
38
41
|
has_rdoc: true
|
39
42
|
homepage:
|
40
43
|
licenses: []
|
@@ -59,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
59
62
|
requirements: []
|
60
63
|
|
61
64
|
rubyforge_project:
|
62
|
-
rubygems_version: 1.3.
|
65
|
+
rubygems_version: 1.3.4
|
63
66
|
signing_key:
|
64
67
|
specification_version: 3
|
65
68
|
summary: Quality backtraces for ruby
|
File without changes
|