Skip to content

Commit 927fc67

Browse files
committed
fix(flamegraph): handle Source events with no filename
1 parent 33f9edc commit 927fc67

File tree

3 files changed

+71
-23
lines changed

3 files changed

+71
-23
lines changed

flamegraph/dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flamegraph/dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flamegraph/index.js

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -149,37 +149,61 @@ function isSubpath(childPath, parentPath) {
149149
return childPathAbs.startsWith(parentPathAbs + path.sep)
150150
}
151151

152-
function addFilenameDetail(event, includePaths, sourceDir, buildDir) {
152+
/**
153+
* Adjust the args.detail field of the event to be a path relative
154+
* to the sourceDir or buildDir.
155+
*
156+
* @param event {Object} The event to adjust
157+
* @param includePaths {Set<string>} The include paths to check
158+
* @param sourceDir {string} The source directory
159+
* @param buildDir {string} The build directory
160+
*/
161+
function adjustEventDetailFilename(event, includePaths, sourceDir, buildDir) {
162+
function fnlog(msg) {
163+
trace_commands.log(`adjustEventDetailFilename: ${msg}`)
164+
}
165+
166+
fnlog(`Adjust event detail filename`)
153167
const eventDetailIsExistingFile =
154168
event.args &&
155169
event.args.detail &&
156170
typeof event.args.detail === 'string'
157171
if (!eventDetailIsExistingFile) {
172+
fnlog(`Event does not have a detail field to adjust`)
158173
return
159174
}
160175
if (event.name === 'ParseFunctionDefinition') {
161176
// Can't resolve a function definition
177+
fnlog(`Event is a function definition, can't resolve the file`)
162178
return
163179
}
164180
// Some paths contain a spelling, such as:
165181
// unistd.h:27:1 <Spelling=/usr/include/x86_64-linux-gnu/sys/cdefs.h:133:24>
166182
const spellingIndex = event.args.detail.indexOf(' <Spelling=')
167183
if (spellingIndex !== -1) {
184+
fnlog(`Event has a spelling field, removing it from ${event.args.detail}`)
168185
event.args.detail = event.args.detail.slice(0, spellingIndex)
186+
fnlog(`Event detail: ${event.args.detail}`)
169187
}
170188
// Some paths contains a final location suffix, such
171189
// unistd.h:27:1
172190
// We want to remove these two numbers with regex
173191
const locationRegex = /:[0-9]+:[0-9]+$/
174192
event.args.detail = event.args.detail.replace(locationRegex, '')
175193
if (isSubpath(event.args.detail, sourceDir)) {
194+
fnlog(`Event is a source file ${event.args.detail}`)
176195
event.args.detail = path.relative(sourceDir, event.args.detail)
196+
fnlog(`Event detail: ${event.args.detail}`)
177197
} else if (isSubpath(event.args.detail, buildDir)) {
198+
fnlog(`Event is a build file ${event.args.detail}`)
178199
event.args.detail = path.relative(buildDir, event.args.detail)
200+
fnlog(`Event detail: ${event.args.detail}`)
179201
} else {
180202
for (const includePath of includePaths) {
181203
if (isSubpath(event.args.detail, includePath)) {
204+
fnlog(`Event is an include file ${event.args.detail}`)
182205
event.args.detail = path.relative(includePath, event.args.detail)
206+
fnlog(`Event detail: ${event.args.detail}`)
183207
break
184208
}
185209
}
@@ -204,6 +228,7 @@ function addFilenameDetail(event, includePaths, sourceDir, buildDir) {
204228
// and detail headers
205229
event.args.detail = `<${event.args.detail}>`
206230
}
231+
fnlog(`Final event detail: ${event.args.detail}`)
207232
}
208233

209234
class TimestampRange {
@@ -254,7 +279,12 @@ class TimestampRanges {
254279
* @param {string} displayFilename
255280
*/
256281
function updateReportData(event, reportData, parsingRegions, instantiationRegions, displayFilename) {
282+
function fnlog(msg) {
283+
trace_commands.log(`adjustEventDetailFilename: ${msg}`)
284+
}
285+
257286
if (event.name === 'Source') {
287+
fnlog(`Adding source event ${event.name} (${event.ph}) with duration ${event.dur}`)
258288
// Add to total
259289
const ts = event.ts
260290
const dur = event.dur
@@ -264,9 +294,15 @@ function updateReportData(event, reportData, parsingRegions, instantiationRegion
264294
parsingRegions.addRange(ts, ts + dur)
265295
}
266296
// Add to file total
267-
const file = event.args.detail
297+
// ! Some Source events don't have a filename. We default to
298+
// the display filename
299+
const file =
300+
'args' in event && 'detail' in event.args ?
301+
event.args.detail :
302+
displayFilename
268303
reportData.addFileParseData(file, 1, dur)
269304
} else if (event.name.startsWith('Parse') && event.args && event.args.detail) {
305+
fnlog(`Adding parse event ${event.name} (${event.ph}) with duration ${event.dur}`)
270306
// const fileParseEventNames = ['ParseDeclarationOrFunctionDefinition', 'ParseTranslationUnit', 'ParseFunctionDefinition']
271307
const fileParseEventNames = ['ParseDeclarationOrFunctionDefinition']
272308
if (fileParseEventNames.includes(event.name)) {
@@ -278,6 +314,7 @@ function updateReportData(event, reportData, parsingRegions, instantiationRegion
278314
const symbol = event.args.detail
279315
reportData.addSymbolParseData(symbol, 1, dur)
280316
} else if (event.name.startsWith('Instantiate') && event.args && event.args.detail) {
317+
fnlog(`Adding instantiate event ${event.name} (${event.ph}) with duration ${event.dur}`)
281318
// Add to total
282319
const ts = event.ts
283320
const dur = event.dur
@@ -290,26 +327,34 @@ function updateReportData(event, reportData, parsingRegions, instantiationRegion
290327
const symbol = event.args.detail
291328
reportData.addSymbolInstantiateData(symbol, 1, dur)
292329
} else if (event.name === 'PerformPendingInstantiations') {
330+
fnlog(`Adding perform pending instantiations event ${event.name} (${event.ph}) with duration ${event.dur}`)
293331
// Add to total
294332
const ts = event.ts
295333
const dur = event.dur
296334
reportData.total_instantiations.update(1, dur)
297335
instantiationRegions.addRange(ts, ts + dur)
298336
} else if (event.name === 'Frontend') {
337+
fnlog(`Adding frontend event ${event.name} (${event.ph}) with duration ${event.dur}`)
299338
reportData.total_frontend.update(1, event.dur)
300339
} else if (event.name === 'Backend') {
340+
fnlog(`Adding backend event ${event.name} (${event.ph}) with duration ${event.dur}`)
301341
reportData.total_backend.update(1, event.dur)
302342
} else if (event.name === 'Optimizer') {
343+
fnlog(`Adding optimizer event ${event.name} (${event.ph}) with duration ${event.dur}`)
303344
reportData.total_optimize.update(1, event.dur)
304345
} else if (event.name === 'CodeGenPasses') {
346+
fnlog(`Adding codegen passes event ${event.name} (${event.ph}) with duration ${event.dur}`)
305347
reportData.total_codegen.update(1, event.dur)
306348
} else if (event.name === 'ExecuteCompiler') {
349+
fnlog(`Adding execute compiler event ${event.name} (${event.ph}) with duration ${event.dur}`)
307350
// Add to total
308351
const ts = event.ts
309352
const dur = event.dur
310353
reportData.total_compile.update(1, dur)
311354
// Add to files total
312355
reportData.addFileCompileData(displayFilename, 1, dur)
356+
} else {
357+
fnlog(`Unknown event type ${event.name} (Ignored)`)
313358
}
314359
}
315360

@@ -496,7 +541,7 @@ async function combineTraces(sourceDir, buildDir) {
496541
fnlog(`Loaded ${includePaths.size} include paths`)
497542

498543
/** @type {ReportData} */
499-
let reportData = new ReportData()
544+
let aggregateReport = new ReportData()
500545

501546
// Combine traces
502547
/** @type {number} */
@@ -521,43 +566,46 @@ async function combineTraces(sourceDir, buildDir) {
521566
continue
522567
}
523568

524-
let event = {...traceEvent}
525-
addFilenameDetail(event, includePaths, sourceDir, buildDir)
526-
updateReportData(event, reportData, parsingRegions, instantiationRegions, displayFilename)
569+
fnlog(`Processing event ${traceEvent.name} (${traceEvent.ph}) with duration ${traceEvent.dur} in ${displayFilename}`)
570+
fnlog(`traceEvent: ${JSON.stringify(traceEvent)}`)
571+
let eventObj = {...traceEvent}
572+
fnlog(`Event Object: ${JSON.stringify(eventObj)}`)
573+
adjustEventDetailFilename(eventObj, includePaths, sourceDir, buildDir)
574+
updateReportData(eventObj, aggregateReport, parsingRegions, instantiationRegions, displayFilename)
527575

528576
// Keep track of the main ExecuteCompiler event, which exists for each file
529-
if (event.name === 'ExecuteCompiler') {
530-
fileTotalTime = event.dur
577+
if (eventObj.name === 'ExecuteCompiler') {
578+
fileTotalTime = eventObj.dur
531579
fnlog(`${displayFilename} took ${fileTotalTime}`)
532580
// Also set the file name in ExecuteCompiler
533-
if (!event.args) {
534-
event.args = {}
581+
if (!eventObj.args) {
582+
eventObj.args = {}
535583
}
536-
event.args.detail = displayFilename
584+
eventObj.args.detail = displayFilename
537585
}
538586

539587
// Replace source event names with filename
540-
if (event.name === 'Source') {
541-
if (event.args && event.args.detail) {
542-
event.name = event.args.detail
588+
if (eventObj.name === 'Source') {
589+
if (eventObj.args && eventObj.args.detail) {
590+
eventObj.name = eventObj.args.detail
543591
} else {
544-
event.name = displayFilename
592+
eventObj.name = displayFilename
545593
}
546-
event.cat = 'Source'
594+
eventObj.cat = 'Source'
547595
}
548596

549597
// Offset combined data by start time to make events
550598
// sequential in the combined timeline
551-
event.ts += startTime
599+
eventObj.ts += startTime
552600

553601
// Put all events in the same pid
554602
// Different pids tend to be rendered in different tabs in some
555603
// visualizers, which is not what we want
556-
event.pid = 0
557-
event.tid = 0
604+
eventObj.pid = 0
605+
eventObj.tid = 0
558606

559607
// Add event to combined data
560-
combinedEvents.push(event)
608+
combinedEvents.push(eventObj)
561609
}
562610

563611
// Increase the start time for the next file
@@ -569,7 +617,7 @@ async function combineTraces(sourceDir, buildDir) {
569617
const combinedTrace = {
570618
traceEvents: combinedEvents
571619
}
572-
return {combinedTrace, reportData}
620+
return {combinedTrace, reportData: aggregateReport}
573621
}
574622

575623
class Event {

0 commit comments

Comments
 (0)