appmap 0.84.0 → 0.87.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc5d48a877bd0953d1d374fcabfa23bf584ac81bd4f303d4f759fb531a778b22
4
- data.tar.gz: 6fe7282152760a910275176ea36987747671e4d06d3983b41ac04edfc217d22c
3
+ metadata.gz: 340b56e93b02e0d530da30ead22c7fe26d067aeac1be6b4188a38819d51c1c82
4
+ data.tar.gz: 0bbae1f5fea6e1040973c15307aa3ef10b0b2e14d86755dc11dbb13e03ddfa8a
5
5
  SHA512:
6
- metadata.gz: 3385416af1ca8318f5e08fe8edc242be03e7e40b8c15a5a68e6ec0678915cd3ca37a3948bf2651db20f2d56dc3b9ba93dda777a5d21ebcd134de252c78d5af91
7
- data.tar.gz: 67ee12c6708a5e29e86462d086b0509db2d4c0b05643182b9ea5209d4acfe792d52532bb3314a48911c07e7d1891a2a32868a55feb13455172e7571c1b7a3570
6
+ metadata.gz: f41681a8af1625ce7003f8c02cd312a2b4ae1cffb6f47a8825930eb5c3e721ed95fde409cda5b02c6cf82e08614570fb4835f186861909d896bfa033e500e837
7
+ data.tar.gz: ffc6aac108fd752f599b0af3b0f25b859c3c591789169129e46184f5a8499253f27303acbdbe7985e2154a0ca90a8ed673b5000bed0d3f6f9aa9ca8bbd26c189
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ # [0.87.0](https://github.com/applandinc/appmap-ruby/compare/v0.86.0...v0.87.0) (2022-08-19)
2
+
3
+
4
+ ### Features
5
+
6
+ * Improve performance of initial hooking ([901e262](https://github.com/applandinc/appmap-ruby/commit/901e26237027920ede6b0f9d4bc3d175c861b23a))
7
+
8
+ # [0.86.0](https://github.com/applandinc/appmap-ruby/compare/v0.85.0...v0.86.0) (2022-08-10)
9
+
10
+
11
+ ### Features
12
+
13
+ * Don't record rspec test when appmap: false ([09c4a24](https://github.com/applandinc/appmap-ruby/commit/09c4a249c7446c6aebcc1d462d3d7b35817334fc))
14
+
15
+ # [0.85.0](https://github.com/applandinc/appmap-ruby/compare/v0.84.0...v0.85.0) (2022-08-08)
16
+
17
+
18
+ ### Features
19
+
20
+ * Tune method parameters ([4a7b575](https://github.com/applandinc/appmap-ruby/commit/4a7b575e6f9684adaac4b592adc1ad2c832e900d))
21
+
1
22
  # [0.84.0](https://github.com/applandinc/appmap-ruby/compare/v0.83.6...v0.84.0) (2022-08-04)
2
23
 
3
24
 
@@ -11,7 +11,9 @@
11
11
  require_name: active_support/security_utils
12
12
  force: true
13
13
  - method: ActiveSupport.run_load_hooks
14
- label: deserialize.safe
14
+ labels:
15
+ - deserialize.safe
16
+ - lang.eval.safe
15
17
  require_name: active_support/lazy_load_hooks
16
18
  force: true
17
19
  - method: ActiveSupport::MessageEncryptor#encrypt_and_sign
@@ -2,6 +2,7 @@
2
2
  - Marshal#load
3
3
  - Marshal#restore
4
4
  require_name: ruby
5
+ handler_class: AppMap::Handler::MarshalLoadHandler
5
6
  label: deserialize.unsafe
6
7
  - method: Marshal#dump
7
8
  require_name: ruby
@@ -29,3 +30,6 @@
29
30
  - Process#spawn
30
31
  require_name: ruby
31
32
  label: system.exec
33
+ - methods:
34
+ - ERB#result
35
+ require_name: ruby
data/lib/appmap/event.rb CHANGED
@@ -193,7 +193,7 @@ module AppMap
193
193
 
194
194
  public
195
195
 
196
- def build_from_invocation(defined_class, method, receiver, arguments, event: MethodCall.new)
196
+ def build_from_invocation(defined_class, method, receiver, arguments, parameters: method.parameters, event: MethodCall.new)
197
197
  event ||= MethodCall.new
198
198
  defined_class ||= 'Class'
199
199
 
@@ -208,10 +208,10 @@ module AppMap
208
208
 
209
209
  # Check if the method has key parameters. If there are any they'll always be last.
210
210
  # If yes, then extract it from arguments.
211
- has_key = [[:dummy], *method.parameters].last.first.to_s.start_with?('key') && arguments[-1].is_a?(Hash)
211
+ has_key = [[:dummy], *parameters].last.first.to_s.start_with?('key') && arguments[-1].is_a?(Hash)
212
212
  kwargs = has_key && arguments[-1].dup || {}
213
213
 
214
- event.parameters = method.parameters.map.with_index do |method_param, idx|
214
+ event.parameters = parameters.map.with_index do |method_param, idx|
215
215
  param_type, param_name = method_param
216
216
  param_name ||= 'arg'
217
217
  value = case param_type
@@ -23,6 +23,21 @@ module AppMap
23
23
  # To avoid this, we explicitly substitute the correct execution
24
24
  # context, up several stack frames.
25
25
  class EvalHandler < FunctionHandler
26
+ # Kernel#eval reports the method parameters as :rest, instead of what you might expect from
27
+ # the documented signature: eval(string [, binding [, filename [,lineno]]])
28
+ # In the C code, it's defined as rb_f_eval(int argc, const VALUE *argv, VALUE self),
29
+ # so maybe that's why the parameters are reported as :rest.
30
+ #
31
+ # In any case, reporting the parameters as :rest means that the code string, binding, etc
32
+ # are reported in the AppMap as members of an Array, without individual object ids or types.
33
+ #
34
+ # To make eval easier to analyze, fake the hook_method parameters to better match
35
+ # the documentation.
36
+ PARAMETERS= [
37
+ [ :req, :string ],
38
+ [ :rest ],
39
+ ]
40
+
26
41
  # The depth of the frame we need to pluck out:
27
42
  # 1. Hook::Method#do_call
28
43
  # 2. Hook::Method#trace_call
@@ -31,6 +46,10 @@ module AppMap
31
46
  # 5. the (intended) frame of the original eval that we hooked
32
47
  # Note it needs to be adjusted if this call sequence changes.
33
48
  FRAME_DEPTH = 5
49
+
50
+ def handle_call(receiver, args)
51
+ AppMap::Event::MethodCall.build_from_invocation(defined_class, hook_method, receiver, args, parameters: PARAMETERS)
52
+ end
34
53
 
35
54
  def do_call(receiver, src = nil, context = nil, *rest)
36
55
  context ||= AppMap.caller_binding FRAME_DEPTH
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'appmap/handler/function_handler'
4
+
5
+ module AppMap
6
+ module Handler
7
+ class MarshalLoadHandler < FunctionHandler
8
+ PARAMETERS= [
9
+ [ :req, :source ],
10
+ [ :rest ],
11
+ ]
12
+
13
+ def handle_call(receiver, args)
14
+ AppMap::Event::MethodCall.build_from_invocation(defined_class, hook_method, receiver, args, parameters: PARAMETERS)
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/appmap/hook.rb CHANGED
@@ -183,12 +183,6 @@ module AppMap
183
183
 
184
184
  hook = lambda do |hook_cls|
185
185
  lambda do |method_id|
186
- # Don't try and trace the AppMap methods or there will be
187
- # a stack overflow in the defined hook method.
188
- next if %w[Marshal AppMap ActiveSupport].member?((hook_cls&.name || '').split('::')[0])
189
-
190
- next if method_id == :call
191
-
192
186
  method = \
193
187
  begin
194
188
  hook_cls.instance_method(method_id)
@@ -197,6 +191,16 @@ module AppMap
197
191
  next
198
192
  end
199
193
 
194
+ package = config.lookup_package(hook_cls, method)
195
+ # doing this check first returned early in 98.7% of cases in sample_app_6th_ed
196
+ next unless package
197
+
198
+ # Don't try and trace the AppMap methods or there will be
199
+ # a stack overflow in the defined hook method.
200
+ next if %w[Marshal AppMap ActiveSupport].member?((hook_cls&.name || '').split('::')[0])
201
+
202
+ next if method_id == :call
203
+
200
204
  next if self.class.already_hooked?(method)
201
205
 
202
206
  warn "AppMap: Examining #{hook_cls} #{method.name}" if LOG
@@ -206,9 +210,6 @@ module AppMap
206
210
  # TODO: Figure out how to tell the difference?
207
211
  next unless disasm
208
212
 
209
- package = config.lookup_package(hook_cls, method)
210
- next unless package
211
-
212
213
  package.handler_class.new(package, hook_cls, method).activate
213
214
  end
214
215
  end
data/lib/appmap/rspec.rb CHANGED
@@ -157,14 +157,20 @@ module AppMap
157
157
  AppMap.info 'Configuring AppMap recorder for RSpec' if first_recording?
158
158
  @recording_count += 1
159
159
 
160
- @recordings_by_example[example.object_id] = Recording.new(example)
160
+ recording = if example.metadata[:appmap] != false
161
+ Recording.new(example)
162
+ else
163
+ :false
164
+ end
165
+
166
+ @recordings_by_example[example.object_id] = recording
161
167
  end
162
168
 
163
169
  def end_spec(example, exception:)
164
170
  recording = @recordings_by_example.delete(example.object_id)
165
171
  return warn "No recording found for #{example}" unless recording
166
172
 
167
- recording.finish exception
173
+ recording.finish exception unless recording == :false
168
174
  end
169
175
 
170
176
  def config
@@ -3,7 +3,7 @@
3
3
  module AppMap
4
4
  URL = 'https://github.com/applandinc/appmap-ruby'
5
5
 
6
- VERSION = '0.84.0'
6
+ VERSION = '0.87.0'
7
7
 
8
8
  APPMAP_FORMAT_VERSION = '1.7.0'
9
9
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.84.0
4
+ version: 0.87.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Gilpin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-04 00:00:00.000000000 Z
11
+ date: 2022-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: method_source
@@ -396,6 +396,7 @@ files:
396
396
  - lib/appmap/handler.rb
397
397
  - lib/appmap/handler/eval_handler.rb
398
398
  - lib/appmap/handler/function_handler.rb
399
+ - lib/appmap/handler/marshal_load_handler.rb
399
400
  - lib/appmap/handler/net_http_handler.rb
400
401
  - lib/appmap/handler/open_ssl_handler.rb
401
402
  - lib/appmap/handler/rails/render_handler.rb