Skip to content

Commit 9ff794c

Browse files
authored
perf: improve algorithm for getting callsites in AppSec (#6044)
Use the `Error.captureStackTrace` API when triggering `Error.prepareStackTrace` in order to be able to provide a constructor function. This is used to reduce the number of unnecessary frames being generated.
1 parent 2ada98a commit 9ff794c

File tree

5 files changed

+23
-23
lines changed

5 files changed

+23
-23
lines changed

packages/dd-trace/src/appsec/iast/vulnerability-reporter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ function isDuplicatedVulnerability (vulnerability) {
114114
}
115115

116116
function getVulnerabilityCallSiteFrames () {
117-
return getCallsiteFrames(stackTraceMaxDepth)
117+
return getCallsiteFrames(stackTraceMaxDepth, getVulnerabilityCallSiteFrames)
118118
}
119119

120120
function replaceCallSiteFromSourceMap (callsite) {

packages/dd-trace/src/appsec/rasp/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function handleResult (result, req, res, abortController, config, raspRule) {
4141
const ruleTriggered = !!result?.events?.length
4242

4343
if (generateStackTraceAction && enabled && canReportStackTrace(rootSpan, maxStackTraces)) {
44-
const frames = getCallsiteFrames(maxDepth)
44+
const frames = getCallsiteFrames(maxDepth, handleResult)
4545

4646
reportStackTrace(
4747
rootSpan,

packages/dd-trace/src/appsec/stack_trace.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,36 @@ const STACK_TRACE_NAMESPACES = {
99
IAST: 'vulnerability'
1010
}
1111

12-
function getCallSiteList (maxDepth = 100) {
12+
function prepareStackTrace (_, callsites) {
13+
return callsites
14+
}
15+
16+
function getCallSiteList (maxDepth = 100, constructorOpt) {
1317
const previousPrepareStackTrace = Error.prepareStackTrace
1418
const previousStackTraceLimit = Error.stackTraceLimit
15-
let callsiteList
1619
// Since some frames will be discarded because they come from tracer codebase, a buffer is added
1720
// to the limit in order to get as close as `maxDepth` number of frames.
1821
Error.stackTraceLimit = maxDepth + LIBRARY_FRAMES_BUFFER
1922

2023
try {
21-
Error.prepareStackTrace = function (_, callsites) {
22-
callsiteList = callsites
23-
}
24-
const e = new Error('message')
25-
e.stack
24+
Error.prepareStackTrace = prepareStackTrace
25+
const obj = {}
26+
Error.captureStackTrace(obj, constructorOpt)
27+
return obj.stack
2628
} finally {
2729
Error.prepareStackTrace = previousPrepareStackTrace
2830
Error.stackTraceLimit = previousStackTraceLimit
2931
}
30-
31-
return callsiteList
3232
}
3333

3434
function filterOutFramesFromLibrary (callSiteList) {
3535
return callSiteList.filter(callSite => !callSite.getFileName()?.startsWith(ddBasePath))
3636
}
3737

38-
function getCallsiteFrames (maxDepth = 32, callSiteListGetter = getCallSiteList) {
38+
function getCallsiteFrames (maxDepth = 32, constructorOpt = getCallsiteFrames, callSiteListGetter = getCallSiteList) {
3939
if (maxDepth < 1) maxDepth = Infinity
4040

41-
const callSiteList = callSiteListGetter(maxDepth)
41+
const callSiteList = callSiteListGetter(maxDepth, constructorOpt)
4242
const filteredFrames = filterOutFramesFromLibrary(callSiteList)
4343

4444
const half = filteredFrames.length > maxDepth ? Math.round(maxDepth / 2) : Infinity

packages/dd-trace/test/appsec/iast/path-line.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ describe('path-line', function () {
199199
const basePath = pathLine.ddBasePath
200200
pathLine.ddBasePath = path.join('test', 'base', 'path')
201201

202-
const list = getCallsiteFrames(32, getCallSiteInfo)
202+
const list = getCallsiteFrames(32, getCallSiteInfo, getCallSiteInfo)
203203
const firstNonDDPath = pathLine.getNonDDCallSiteFrames(list)[0]
204204

205205
const expectedPath = path.join('node_modules', firstNonDDPath.path)

packages/dd-trace/test/appsec/stack_trace.spec.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ describe('Stack trace reporter', () => {
6666
const rootSpan = {}
6767
const stackId = 'test_stack_id'
6868
const maxDepth = 32
69-
const frames = getCallsiteFrames(maxDepth, () => callSiteList)
69+
const frames = getCallsiteFrames(maxDepth, getCallsiteFrames, () => callSiteList)
7070

7171
reportStackTrace(rootSpan, stackId, frames)
7272

@@ -112,7 +112,7 @@ describe('Stack trace reporter', () => {
112112
}
113113
))
114114

115-
const frames = getCallsiteFrames(maxDepth, () => callSiteList)
115+
const frames = getCallsiteFrames(maxDepth, getCallsiteFrames, () => callSiteList)
116116

117117
reportStackTrace(rootSpan, stackId, frames)
118118

@@ -141,7 +141,7 @@ describe('Stack trace reporter', () => {
141141
}
142142
))
143143

144-
const frames = getCallsiteFrames(maxDepth, () => callSiteList)
144+
const frames = getCallsiteFrames(maxDepth, getCallsiteFrames, () => callSiteList)
145145

146146
reportStackTrace(rootSpan, stackId, frames)
147147

@@ -174,7 +174,7 @@ describe('Stack trace reporter', () => {
174174
}
175175
))
176176

177-
const frames = getCallsiteFrames(maxDepth, () => callSiteList)
177+
const frames = getCallsiteFrames(maxDepth, getCallsiteFrames, () => callSiteList)
178178

179179
reportStackTrace(rootSpan, stackId, frames)
180180

@@ -216,7 +216,7 @@ describe('Stack trace reporter', () => {
216216
const stackId = 'test_stack_id'
217217
const maxDepth = 32
218218

219-
const frames = getCallsiteFrames(maxDepth, () => callSiteList)
219+
const frames = getCallsiteFrames(maxDepth, getCallsiteFrames, () => callSiteList)
220220

221221
reportStackTrace(rootSpan, stackId, frames)
222222

@@ -265,7 +265,7 @@ describe('Stack trace reporter', () => {
265265
}
266266
))
267267

268-
const frames = getCallsiteFrames(maxDepth, () => callSiteList)
268+
const frames = getCallsiteFrames(maxDepth, getCallsiteFrames, () => callSiteList)
269269

270270
reportStackTrace(rootSpan, stackId, frames)
271271

@@ -316,7 +316,7 @@ describe('Stack trace reporter', () => {
316316
}
317317
))
318318

319-
const frames = getCallsiteFrames(maxDepth, () => callSiteListWithLibraryFrames)
319+
const frames = getCallsiteFrames(maxDepth, getCallsiteFrames, () => callSiteListWithLibraryFrames)
320320

321321
reportStackTrace(rootSpan, stackId, frames)
322322

@@ -339,7 +339,7 @@ describe('Stack trace reporter', () => {
339339
}
340340
))
341341

342-
const frames = getCallsiteFrames(maxDepth, () => callSiteList)
342+
const frames = getCallsiteFrames(maxDepth, getCallsiteFrames, () => callSiteList)
343343

344344
reportStackTrace(rootSpan, stackId, frames)
345345

@@ -362,7 +362,7 @@ describe('Stack trace reporter', () => {
362362
}
363363
))
364364

365-
const frames = getCallsiteFrames(maxDepth, () => callSiteList)
365+
const frames = getCallsiteFrames(maxDepth, getCallsiteFrames, () => callSiteList)
366366

367367
reportStackTrace(rootSpan, stackId, frames)
368368

0 commit comments

Comments
 (0)