trace_tree 0.2.8 → 0.2.9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e6a33c823c7c9a9edef43b4a0a9a6131cb5088cf
4
- data.tar.gz: 8fc50067cb0975e582b1450f0f5b4056aae86b1b
3
+ metadata.gz: 2acc2e68551caee98c0c8b0245646acea04bce6d
4
+ data.tar.gz: f7b038d0a709e7dc15f9225179177b1948168a54
5
5
  SHA512:
6
- metadata.gz: 0ed48c6ec0f6b579f8e823c0d03bfb34c511b9f9c86d508f624ad313830313c24ffd9dbae30a52c4b0410453763a0d93224fbe47616d781d51c63f25bb2ffc3d
7
- data.tar.gz: d54d68166144f9bbcc60498fe189ffbdb27d47516ddce71cf8ed5fd2bc77ac8ecb06153c9aa6f95f02b6204b9658a59c5fde30f4c5b025c829467f642cce0944
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
 
@@ -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
- attrs = Interfaces.each_with_object({}) do |attr, hash|
31
- hash[attr] = point.send attr
32
- end
33
- attrs.merge!({return_value: point.return_value}) if point.event =~ /return/
34
- attrs.merge!({thread: point.thread}) if point.respond_to? :thread
35
- attrs
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
- [point.event, point.defined_class, point.method_id] == event_class_method
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
- @current = BindingOfCallers::Revealed.new trace_point.binding.of_caller(3) unless thread?
61
- @thread = thread? ? trace_point.self : current.send(:eval, 'Thread.current')
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
- c_call? ? method_id : current.frame_env
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 |concreate_point_path|
166
- load concreate_point_path
167
- #puts "---->#{concreate_point_path}"
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
@@ -1,3 +1,3 @@
1
1
  class TraceTree
2
- VERSION = "0.2.8"
2
+ VERSION = "0.2.9"
3
3
  end
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
- enhance_point **opt
35
- @build_command = opt[:html] ? :tree_html_full : :tree_graph
36
- @ignore = opt[:ignore] || {}
37
- here = bi.eval('self')
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(*Events) do |point|
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
- here.instance_eval &to_do
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 opt
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 Terminal::Table.from_hashes trace_points_array.map(&:to_h)
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 wanted? trace_point
84
- @ignore.any? do |attr, pattern|
85
- pattern =~ trace_point.send(attr)
86
- end ? false : true
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.8
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-06-10 00:00:00.000000000 Z
11
+ date: 2017-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler