diff --git a/lib/datadog/di/instrumenter.rb b/lib/datadog/di/instrumenter.rb index ad660bb7481..d18d77eab58 100644 --- a/lib/datadog/di/instrumenter.rb +++ b/lib/datadog/di/instrumenter.rb @@ -227,7 +227,7 @@ def hook_line(probe, &block) # However, by adding the :return trace point we lose diagnostics # for lines that contain no executable code (e.g. comments only) # and thus cannot actually be instrumented. - [:line, :return] + [:line, :return, :b_return] else [:line] end @@ -249,7 +249,7 @@ def hook_line(probe, &block) # TODO test this path end rescue => exc - raise if settings.dynamic_instrumentation.propagate_all_exceptions + raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions logger.warn("Unhandled exception in line trace point: #{exc.class}: #{exc}") telemetry&.report(exc, description: "Unhandled exception in line trace point") # TODO test this path diff --git a/spec/datadog/di/integration/instrumentation_integration_test_class.rb b/spec/datadog/di/integration/instrumentation_integration_test_class.rb index 80622cfbaed..00b4d780776 100644 --- a/spec/datadog/di/integration/instrumentation_integration_test_class.rb +++ b/spec/datadog/di/integration/instrumentation_integration_test_class.rb @@ -9,6 +9,14 @@ def test_method # padding a * 2 # line 10 end # line 11 -end # line 12 -# Comment - line 14 + def test_method_with_block + array = [1] + array.each do |value| + value_copy = value + end # line 17 + end + +end # line 20 + +# Comment - line 22 diff --git a/spec/datadog/di/integration/instrumentation_spec.rb b/spec/datadog/di/integration/instrumentation_spec.rb index 9830182f3c5..2006c9ba49a 100644 --- a/spec/datadog/di/integration/instrumentation_spec.rb +++ b/spec/datadog/di/integration/instrumentation_spec.rb @@ -355,10 +355,63 @@ def run_test include_examples 'simple log probe' end + context 'target line is the end line of a block' do + let(:probe) do + Datadog::DI::Probe.new(id: "1234", type: :log, + file: 'instrumentation_integration_test_class.rb', line_no: 17, + capture_snapshot: false,) + end + + it 'invokes probe' do + expect(component.transport).to receive(:send_request).at_least(:once) + probe_manager.add_probe(probe) + component.probe_notifier_worker.flush + expect(probe_manager.installed_probes.length).to eq 1 + expect(component.probe_notifier_worker).to receive(:add_snapshot).once.and_call_original + expect(InstrumentationIntegrationTestClass.new.test_method_with_block).to eq([1]) + end + + describe 'payload' do + let(:payload) do + probe_manager.add_probe(probe) + payload = nil + expect(component.probe_notifier_worker).to receive(:add_snapshot) do |payload_| + payload = payload_ + end + expect(InstrumentationIntegrationTestClass.new.test_method_with_block).to eq([1]) + component.probe_notifier_worker.flush + expect(payload).to be_a(Hash) + payload + end + + let(:snapshot) do + payload.fetch(:"debugger.snapshot") + end + + it 'does not have captures' do + expect(component.transport).to receive(:send_request).at_least(:once) + expect(snapshot.fetch(:captures)).to be nil + end + + let(:stack) do + snapshot.fetch(:stack) + end + + let(:top_stack_frame) do + stack.first + end + + it 'has instrumented location as top stack frame' do + expect(component.transport).to receive(:send_request).at_least(:once) + expect(File.basename(top_stack_frame.fetch(:fileName))).to eq 'instrumentation_integration_test_class.rb' + end + end + end + context 'target line contains a comment (no executable code)' do let(:probe) do Datadog::DI::Probe.new(id: "1234", type: :log, - file: 'instrumentation_integration_test_class.rb', line_no: 14, + file: 'instrumentation_integration_test_class.rb', line_no: 22, capture_snapshot: false,) end