trace_tree 0.2.8 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/lib/trace_tree/point.rb +82 -14
- data/lib/trace_tree/version.rb +1 -1
- data/lib/trace_tree.rb +40 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2acc2e68551caee98c0c8b0245646acea04bce6d
|
4
|
+
data.tar.gz: f7b038d0a709e7dc15f9225179177b1948168a54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8c8e186db907601748d81fcd7c325c35084cb9cd504599337fc95fc0d81d59a2c5dc5cf5a4d4171ecf16b3e4660ace8e1c44f51c71a7e97a330917622f6066c
|
7
|
+
data.tar.gz: 9e650c794990c69ce8154fcaca17bef4c4c3684295eaa49c84218df412b2a5d1768de8fef6e5c78319f879dc366f45e24f66f99c29a8b3fd406ca684ab37e25a
|
data/README.md
CHANGED
@@ -45,7 +45,10 @@ end
|
|
45
45
|
* `:gem => true` by default. Replace the gem paths in source_location with $GemPathN, can make the lines shorter. To see what are replaced, inspect `TraceTree::GemPaths`.
|
46
46
|
* `:html => nil` by default. Set it true to generate a html in which a tree constructed with `<ul>`, `<li>`. (No need to set `color`).
|
47
47
|
* `:tmp => nil` by default. Set it true or a string or an array of string to specify a tmp file under the default tmp dir of your system. (No need to provide `file` argument. It makes parent directories as needed)
|
48
|
+
* `:htmp => nil` by default. It is combination of `:html` and `:tmp`.
|
49
|
+
* `:in => //, :out => nil` by default. Give them regexp(s) to include/exclude methods defined in files match that regexp(s). Notice thread-calls and methods defined by `define_method` are always included. Also, once you set any of these two options, the code to trace should not be in same line with `binding.trace_tree() do`.
|
48
50
|
* `:timer => nil` by default. Set it true if you want to know how much time spent in tracing and drawing tree. Notice the `file` should be appendable, otherwise the time will overwrite the tree.
|
51
|
+
* `:debug =>` by default. Give it somthing like what for `:tmp` to output a whole list of TracePoints in file for debug.
|
49
52
|
|
50
53
|
### Example
|
51
54
|
|
data/lib/trace_tree/point.rb
CHANGED
@@ -7,7 +7,7 @@ class TraceTree
|
|
7
7
|
include TreeGraphable
|
8
8
|
include TreeHtmlable
|
9
9
|
|
10
|
-
attr_reader :current, :thread
|
10
|
+
attr_reader :current, :thread, :frame_env
|
11
11
|
attr_accessor :terminal
|
12
12
|
|
13
13
|
Interfaces = [:event, :defined_class, :method_id, :path, :lineno]
|
@@ -27,16 +27,21 @@ class TraceTree
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def hashify point
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
h = {}
|
31
|
+
h[:event] = point.event
|
32
|
+
h[:defined_class] = point.defined_class
|
33
|
+
h[:method_id] = point.method_id
|
34
|
+
h[:frame_env] = point.frame_env unless point.thread?
|
35
|
+
h[:path] = point.path
|
36
|
+
h[:lineno] = point.lineno
|
37
|
+
h[:thread] = point.thread
|
38
|
+
h[:return_value] = point.return_value if point.event =~ /return/
|
39
|
+
h
|
36
40
|
end
|
37
41
|
|
38
42
|
def class_of? point
|
39
|
-
|
43
|
+
e, c, m = event_class_method
|
44
|
+
point.method_id == m && point.event == e && point.defined_class == c
|
40
45
|
end
|
41
46
|
|
42
47
|
def initialize_clone proto
|
@@ -46,6 +51,19 @@ class TraceTree
|
|
46
51
|
end
|
47
52
|
|
48
53
|
attr_reader :proto
|
54
|
+
|
55
|
+
def cache_event_class_method!
|
56
|
+
bases.each do |base|
|
57
|
+
base.class_eval <<-EOM
|
58
|
+
class << self
|
59
|
+
alias_method :_event_class_method, :event_class_method
|
60
|
+
def self.event_class_method
|
61
|
+
@ecm ||= _event_class_method.freeze
|
62
|
+
end
|
63
|
+
end
|
64
|
+
EOM
|
65
|
+
end
|
66
|
+
end
|
49
67
|
end
|
50
68
|
|
51
69
|
def method_missing method_id, *args, &blk
|
@@ -56,17 +74,33 @@ class TraceTree
|
|
56
74
|
Interfaces.each do |i|
|
57
75
|
instance_variable_set "@#{i}", trace_point.send(i)
|
58
76
|
end
|
77
|
+
|
59
78
|
@return_value = trace_point.return_value if x_return?
|
60
|
-
|
61
|
-
|
79
|
+
|
80
|
+
if thread?
|
81
|
+
@thread = trace_point.self
|
82
|
+
else
|
83
|
+
there = trace_point.binding.of_caller(3)
|
84
|
+
@current = BindingOfCallers::Revealed.new there
|
85
|
+
@frame_env = current.frame_env.to_sym
|
86
|
+
@thread = current.send(:eval, 'Thread.current')
|
87
|
+
end
|
62
88
|
rescue => e
|
63
89
|
puts e
|
64
90
|
end
|
65
91
|
|
92
|
+
def b_call?
|
93
|
+
event == :b_call
|
94
|
+
end
|
95
|
+
|
66
96
|
def c_call?
|
67
97
|
event == :c_call
|
68
98
|
end
|
69
99
|
|
100
|
+
def class?
|
101
|
+
event == :class
|
102
|
+
end
|
103
|
+
|
70
104
|
def x_return?
|
71
105
|
event =~ /return/
|
72
106
|
end
|
@@ -75,6 +109,13 @@ class TraceTree
|
|
75
109
|
event =~ /thread/
|
76
110
|
end
|
77
111
|
|
112
|
+
def end_of_trace?
|
113
|
+
MainFile == path && (
|
114
|
+
(:c_return == event && :instance_eval == method_id) ||
|
115
|
+
(:c_call == event && :disable == method_id)
|
116
|
+
)
|
117
|
+
end
|
118
|
+
|
78
119
|
def return_value
|
79
120
|
raise RuntimeError.new('RuntimeError: not supported by this event') unless x_return?
|
80
121
|
@return_value
|
@@ -127,7 +168,9 @@ class TraceTree
|
|
127
168
|
end
|
128
169
|
|
129
170
|
def method_name
|
130
|
-
|
171
|
+
return method_id if c_call?
|
172
|
+
return frame_env if b_call? || class?
|
173
|
+
(method_id == frame_env) ? method_id : "#{method_id} -> #{frame_env}"
|
131
174
|
end
|
132
175
|
|
133
176
|
def call_symbol
|
@@ -162,7 +205,32 @@ class TraceTree
|
|
162
205
|
end
|
163
206
|
end
|
164
207
|
|
165
|
-
Dir.glob(File.expand_path('../point/*', __FILE__)).each do |
|
166
|
-
load
|
167
|
-
#puts "---->#{
|
208
|
+
Dir.glob(File.expand_path('../point/*', __FILE__)).each do |concrete_point_path|
|
209
|
+
load concrete_point_path
|
210
|
+
#puts "---->#{concrete_point_path}"
|
211
|
+
end
|
212
|
+
|
213
|
+
class TraceTree
|
214
|
+
class Point
|
215
|
+
|
216
|
+
cache_event_class_method!
|
217
|
+
|
218
|
+
NativeThreadCall = [CcallClassthreadNew,
|
219
|
+
CreturnClassthreadNew,
|
220
|
+
CcallThreadInitialize,
|
221
|
+
CreturnThreadInitialize,
|
222
|
+
Threadbegin,
|
223
|
+
Threadend]
|
224
|
+
|
225
|
+
def thread_relative?
|
226
|
+
NativeThreadCall.any?{ |k| k.class_of? self } ||
|
227
|
+
Thread == defined_class
|
228
|
+
end
|
229
|
+
|
230
|
+
def method_defined_by_define_method?
|
231
|
+
(event == :call || event == :return) &&
|
232
|
+
method_id != frame_env
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
168
236
|
end
|
data/lib/trace_tree/version.rb
CHANGED
data/lib/trace_tree.rb
CHANGED
@@ -16,6 +16,8 @@ end
|
|
16
16
|
|
17
17
|
class TraceTree
|
18
18
|
|
19
|
+
MainFile = __FILE__
|
20
|
+
|
19
21
|
Events = [:b_call, :b_return,
|
20
22
|
:c_call, :c_return,
|
21
23
|
:call, :return,
|
@@ -31,19 +33,18 @@ class TraceTree
|
|
31
33
|
def generate *log, **opt, &to_do
|
32
34
|
@opt = opt
|
33
35
|
@log = dump_location *log
|
34
|
-
|
35
|
-
|
36
|
-
@
|
37
|
-
|
36
|
+
@debug = TmpFile.new opt[:debug] if opt[:debug]
|
37
|
+
enhance_point
|
38
|
+
@build_command = (opt[:html] || opt[:htmp]) ? :tree_html_full : :tree_graph
|
39
|
+
make_filter
|
40
|
+
@__file__, @__line__, there = bi.eval('[__FILE__, __LINE__, self]')
|
38
41
|
|
39
42
|
#start_trace
|
40
43
|
timer[:trace]
|
41
|
-
@tp = TracePoint.new
|
42
|
-
trace_points << point_loader.create(point) if wanted? point
|
43
|
-
end
|
44
|
+
@tp = TracePoint.new *Events, &@deal
|
44
45
|
@tp.enable
|
45
46
|
|
46
|
-
|
47
|
+
there.instance_eval &to_do
|
47
48
|
ensure
|
48
49
|
#stop_trace
|
49
50
|
return unless @tp
|
@@ -58,10 +59,11 @@ class TraceTree
|
|
58
59
|
|
59
60
|
def dump_location *log
|
60
61
|
return TmpFile.new opt[:tmp] if opt[:tmp]
|
62
|
+
return TmpFile.new(opt[:htmp] + '.html') if opt[:htmp]
|
61
63
|
log.empty? ? STDOUT : log[0]
|
62
64
|
end
|
63
65
|
|
64
|
-
def enhance_point
|
66
|
+
def enhance_point
|
65
67
|
enhancement = []
|
66
68
|
enhancement << TraceTree::Color unless opt[:color] == false
|
67
69
|
enhancement << TraceTree::ShortGemPath unless opt[:gem] == false
|
@@ -72,18 +74,40 @@ class TraceTree
|
|
72
74
|
timer[:tree]
|
73
75
|
tree = sort(trace_points_array).send build_command
|
74
76
|
timer[:tree]
|
77
|
+
@debug.puts table_of_points if defined? @debug
|
75
78
|
log.puts tree
|
76
79
|
log.puts timer.to_s if opt[:timer]
|
77
80
|
rescue => e
|
78
81
|
log.puts timer.to_s
|
79
82
|
log.puts e
|
80
|
-
log.puts
|
83
|
+
log.puts table_of_points
|
84
|
+
end
|
85
|
+
|
86
|
+
def table_of_points
|
87
|
+
Terminal::Table.from_hashes trace_points_array.map(&:to_h)
|
81
88
|
end
|
82
89
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
end
|
90
|
+
def make_filter
|
91
|
+
if !opt.key?(:in) && !opt.key?(:out)
|
92
|
+
return @deal = -> point { trace_points << point_loader.create(point) }
|
93
|
+
end
|
94
|
+
@in, @out = Array(opt[:in] || //), Array(opt[:out])
|
95
|
+
@deal = -> point do
|
96
|
+
po = point_loader.create(point)
|
97
|
+
trace_points << po if wanted? po
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def wanted? point
|
102
|
+
return false if point.end_of_trace?
|
103
|
+
return true if native?(point) || point.thread_relative? || point.method_defined_by_define_method?
|
104
|
+
@in.any?{ |pattern| pattern =~ point.path } &&
|
105
|
+
@out.all?{ |pattern| pattern !~ point.path }
|
106
|
+
end
|
107
|
+
|
108
|
+
def native? point
|
109
|
+
MainFile == point.path ||
|
110
|
+
(:b_call == point.event && @__file__ == point.path && @__line__ == point.lineno)
|
87
111
|
end
|
88
112
|
|
89
113
|
def sort trace_points
|
@@ -111,6 +135,8 @@ class TraceTree
|
|
111
135
|
point.thread_begin = began_threads[thread]
|
112
136
|
end
|
113
137
|
|
138
|
+
#binding.pry
|
139
|
+
|
114
140
|
stacks[trace_points.first.thread][0].
|
115
141
|
callees[0].
|
116
142
|
callees[0]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trace_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ken
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|