Skip to content

Commit be529bd

Browse files
committed
fix: Correct the method-hooking logic to capture some missing model methods
With classes enhanced by ActiveRecord, the logic to determine which code blocks to hook was missing some of the methods.
1 parent 1afe158 commit be529bd

File tree

1 file changed

+15
-30
lines changed

1 file changed

+15
-30
lines changed

lib/appmap/hook.rb

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def qualify_method_name(method)
3636

3737
def initialize(config)
3838
@config = config
39-
@trace_locations = []
39+
@trace_enabled = []
4040
# Paths that are known to be non-tracing
4141
@notrace_paths = Set.new
4242
end
@@ -47,10 +47,8 @@ def enable(&block)
4747

4848
hook_builtins
4949

50-
@trace_begin = TracePoint.new(:class, &method(:trace_class))
5150
@trace_end = TracePoint.new(:end, &method(:trace_end))
52-
53-
@trace_begin.enable(&block)
51+
@trace_end.enable(&block)
5452
end
5553

5654
# hook_builtins builds hooks for code that is built in to the Ruby standard library.
@@ -96,29 +94,22 @@ def hook_builtins
9694

9795
protected
9896

99-
def trace_class(trace_point)
100-
path = trace_point.path
101-
102-
return if @notrace_paths.member?(path)
103-
104-
if config.path_enabled?(path)
105-
location = trace_location(trace_point)
106-
warn "Entering hook-enabled location #{location}" if Hook::LOG || Hook::LOG_HOOK
107-
@trace_locations << location
108-
unless @trace_end.enabled?
109-
warn "Enabling hooking" if Hook::LOG || Hook::LOG_HOOK
110-
@trace_end.enable
111-
end
112-
else
113-
@notrace_paths << path
114-
end
115-
end
116-
11797
def trace_location(trace_point)
11898
[ trace_point.path, trace_point.lineno ].join(':')
11999
end
120100

121101
def trace_end(trace_point)
102+
location = trace_location(trace_point)
103+
warn "Class or module ends at location #{trace_location(trace_point)}" if Hook::LOG || Hook::LOG_HOOK
104+
105+
path = trace_point.path
106+
enabled = !@notrace_paths.member?(path) && config.path_enabled?(path)
107+
if !enabled
108+
warn "Not hooking - path is not enabled" if Hook::LOG || Hook::LOG_HOOK
109+
@notrace_paths << path
110+
return
111+
end
112+
122113
cls = trace_point.self
123114

124115
instance_methods = cls.public_instance_methods(false) - OBJECT_INSTANCE_METHODS
@@ -151,7 +142,8 @@ def trace_end(trace_point)
151142
warn "AppMap: Examining #{hook_cls} #{method.name}" if LOG
152143

153144
disasm = RubyVM::InstructionSequence.disasm(method)
154-
# Skip methods that have no instruction sequence, as they are obviously trivial.
145+
# Skip methods that have no instruction sequence, as they are either have no body or they are or native.
146+
# TODO: Figure out how to tell the difference?
155147
next unless disasm
156148

157149
package = config.lookup_package(hook_cls, method)
@@ -170,13 +162,6 @@ def trace_end(trace_point)
170162
# uninitialized constant Faraday::Connection
171163
warn "NameError in #{__FILE__}: #{$!.message}"
172164
end
173-
174-
location = @trace_locations.pop
175-
warn "Leaving hook-enabled location #{location}" if Hook::LOG || Hook::LOG_HOOK
176-
if @trace_locations.empty?
177-
warn "Disabling hooking" if Hook::LOG || Hook::LOG_HOOK
178-
@trace_end.disable
179-
end
180165
end
181166
end
182167
end

0 commit comments

Comments
 (0)