Skip to content

Commit 25823ff

Browse files
committed
fix: Apply special case hook handling to Kernel and instance_eval
1 parent ede2236 commit 25823ff

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

lib/appmap/hook.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ def hook_builtins
116116
end
117117

118118
methods = []
119+
# irb(main):001:0> Kernel.public_instance_method(:system)
120+
# (irb):1:in `public_instance_method': method `system' for module `Kernel' is private (NameError)
121+
if base_cls == Kernel
122+
methods << [ base_cls, base_cls.instance_method(method_name) ] rescue nil
123+
end
119124
methods << [ base_cls, base_cls.public_instance_method(method_name) ] rescue nil
120125
methods << [ base_cls, base_cls.protected_instance_method(method_name) ] rescue nil
121126
if base_cls.respond_to?(:singleton_class)

lib/appmap/hook/method.rb

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ def activate
102102

103103
enabled = true if AppMap.tracing.enabled? && !reentrant && !disabled_by_shallow_flag.call
104104

105-
return call_instance_method.call unless enabled
105+
enabled = false if %i[instance_eval instance_exec].member?(hook_method.name) && args.empty?
106+
107+
return call_instance_method.call(self, args, &block) unless enabled
106108

107109
call_event, start_time = with_disabled_hook.call do
108110
before_hook.call(self, defined_class, args)
@@ -125,11 +127,17 @@ def activate
125127
hook_method_parameters = hook_method.parameters.dup.freeze
126128
SIGNATURES[[ hook_class, hook_method.name ]] = hook_method_parameters
127129

128-
hook_class.ancestors.find { |cls| cls.method_defined?(hook_method.name, false) }.tap do |cls|
129-
if cls
130-
cls.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
131-
else
132-
warn "#{hook_method.name} not found on #{hook_class}"
130+
# irb(main):001:0> Kernel.public_instance_method(:system)
131+
# (irb):1:in `public_instance_method': method `system' for module `Kernel' is private (NameError)
132+
if hook_class == Kernel
133+
hook_class.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
134+
else
135+
hook_class.ancestors.find { |cls| cls.method_defined?(hook_method.name, false) }.tap do |cls|
136+
if cls
137+
cls.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
138+
else
139+
warn "#{hook_method.name} not found on #{hook_class}"
140+
end
133141
end
134142
end
135143
end

0 commit comments

Comments
 (0)