Skip to content

Commit 4feb07b

Browse files
watsonBridgeAR
authored andcommitted
fix(debugger): reuse loaded tracer for trace context in devtools client (#9765)
The devtools worker evaluates an expression on every paused call frame to read the active trace and span IDs. That expression used global.require('dd-trace'), which re-resolves and re-requires the tracer module on each hit. Use globalThis._ddtrace instead, matching the singleton instance installed by bootstrap when the application first loads dd-trace. This avoids duplicate module resolution, works when the bare 'dd-trace' specifier is not resolvable from the paused frame (e.g. sirun benchmarks that load the tracer by path), and removes per-hit require overhead from the hot pause path.
1 parent ca8d4ec commit 4feb07b

2 files changed

Lines changed: 6 additions & 15 deletions

File tree

benchmark/sirun/debugger/start-devtools-client.js

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,16 @@
22

33
const assert = require('node:assert/strict')
44
const fs = require('node:fs')
5-
const Module = require('node:module')
65

76
// Point the tracer at this variant's per-core agent (port matches `agent.js`)
87
// before `getConfig()` reads the URL. Set it unconditionally so a globally
98
// inherited `DD_TRACE_AGENT_URL` can't redirect us back to a shared port that
109
// another parallel variant owns.
1110
process.env.DD_TRACE_AGENT_URL = `http://127.0.0.1:${8080 + Number(process.env.CPU_AFFINITY || 0)}`
1211

13-
// The trace-context expression the devtools client evaluates on the paused frame
14-
// for every hit does `global.require('dd-trace')`. This bench loads the tracer by
15-
// relative path, so the bare specifier would otherwise throw MODULE_NOT_FOUND on
16-
// every hit and skew the measurement. Resolve it to this checkout's entry point.
17-
const ddTraceEntry = require.resolve('../../..')
18-
const originalResolveFilename = Module._resolveFilename
19-
Module._resolveFilename = function (request, ...rest) {
20-
return originalResolveFilename.call(this, request === 'dd-trace' ? ddTraceEntry : request, ...rest)
21-
}
12+
// Production initializes the tracer before starting Dynamic Instrumentation. This benchmark imports the debugger
13+
// internals directly, so initialize the tracer explicitly before the paused-frame expression reads global._ddtrace.
14+
require('../../..')
2215

2316
// The global snapshot cap (MAX_SNAPSHOTS_PER_SECOND_GLOBALLY) is read in the
2417
// devtools worker thread at module load, with no config or env path to override
@@ -27,9 +20,6 @@ Module._resolveFilename = function (request, ...rest) {
2720
// No-op unless the variant opts in via the env var.
2821
patchGlobalSnapshotCap(process.env.MAX_SNAPSHOTS_PER_SECOND_GLOBALLY)
2922

30-
// Entry point normally primes this; bench imports src directly.
31-
globalThis[Symbol.for('dd-trace')] ??= { beforeExitHandlers: new Set() }
32-
3323
const getConfig = require('../../../packages/dd-trace/src/config')
3424
const { start } = require('../../../packages/dd-trace/src/debugger')
3525
const { generateProbeConfig } = require('../../../packages/dd-trace/test/debugger/devtools_client/utils')

packages/dd-trace/src/debugger/devtools_client/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ require('./remote_config')
2323

2424
/** @typedef {import('node:inspector').Debugger.EvaluateOnCallFrameReturnType} EvaluateOnCallFrameResult */
2525

26-
// Expression to run on a call frame of the paused thread to get its active trace and span id.
2726
const templateExpressionSetupCode = `
2827
const $dd_inspect = global.require('node:util').inspect;
2928
const $dd_segmentInspectOptions = {
@@ -34,8 +33,10 @@ const templateExpressionSetupCode = `
3433
breakLength: Infinity
3534
};
3635
`
36+
37+
// Expression to run on a call frame of the paused thread to get its active trace and span id.
3738
const getDDTagsExpression = `(() => {
38-
const context = global.require('dd-trace').scope().active()?.context();
39+
const context = globalThis._ddtrace.scope().active()?.context();
3940
return { trace_id: context?.toTraceId(), span_id: context?.toSpanId() }
4041
})()`
4142

0 commit comments

Comments
 (0)