UI: fix exceptions when only thread info is avilable
Fixes a crash in the UI that happens when recording
a trace with only sched_switch and no process association.
There were two problems here:
1) The controller was partly lying on the thread info,
providing a proc name == thread name, but NULL proc id.
2) The frontend should be robust to deal with thread info
that don't have any matching process info.
Test: http://localhost:3002#!/?s=2efeb0931cd8c808ca4f62a2b81d6cfdcd573d2e5e9b4462ddf3974bf36cc
Change-Id: I4a3b6a4de8af80847f2d2f11d3d9e9aab481c784
diff --git a/ui/src/frontend/globals.ts b/ui/src/frontend/globals.ts
index 37bf7a5..40e5539 100644
--- a/ui/src/frontend/globals.ts
+++ b/ui/src/frontend/globals.ts
@@ -34,8 +34,8 @@
utid: number;
tid: number;
threadName: string;
- pid: number;
- procName: string;
+ pid?: number;
+ procName?: string;
}
type ThreadMap = Map<number, ThreadDesc>;
diff --git a/ui/src/tracks/cpu_slices/frontend.ts b/ui/src/tracks/cpu_slices/frontend.ts
index 7864742..bdffdec 100644
--- a/ui/src/tracks/cpu_slices/frontend.ts
+++ b/ui/src/tracks/cpu_slices/frontend.ts
@@ -213,10 +213,17 @@
const threadInfo = globals.threads.get(utid);
if (threadInfo !== undefined) {
- const procName = threadInfo.procName.split('/').slice(-1);
- title = `${procName} [${threadInfo.pid}]`;
- subTitle = `${threadInfo.threadName} [${threadInfo.tid}]`;
- const colorIdx = hash(threadInfo.pid.toString(), 16);
+ const hasProc = !!threadInfo.pid;
+ const procName = threadInfo.procName || '';
+ let hashKey = threadInfo.tid;
+ if (hasProc) {
+ title = `${procName} [${threadInfo.pid}]`;
+ subTitle = `${threadInfo.threadName} [${threadInfo.tid}]`;
+ hashKey = threadInfo.pid!;
+ } else {
+ title = `${threadInfo.threadName} [${threadInfo.tid}]`;
+ }
+ const colorIdx = hash(hashKey.toString(), 16);
Object.assign(color, MD_PALETTE[colorIdx]);
}
@@ -243,21 +250,26 @@
const hoveredThread = globals.threads.get(this.utidHoveredInThisTrack);
if (hoveredThread !== undefined) {
- const procTitle = `P: ${hoveredThread.procName} [${hoveredThread.pid}]`;
- const threadTitle =
- `T: ${hoveredThread.threadName} [${hoveredThread.tid}]`;
+ let line1 = '';
+ let line2 = '';
+ if (hoveredThread.pid) {
+ line1 = `P: ${hoveredThread.procName} [${hoveredThread.pid}]`;
+ line2 = `T: ${hoveredThread.threadName} [${hoveredThread.tid}]`;
+ } else {
+ line1 = `T: ${hoveredThread.threadName} [${hoveredThread.tid}]`;
+ }
ctx.font = '10px Google Sans';
- const procTitleWidth = ctx.measureText(procTitle).width;
- const threadTitleWidth = ctx.measureText(threadTitle).width;
- const width = Math.max(procTitleWidth, threadTitleWidth);
+ const line1Width = ctx.measureText(line1).width;
+ const line2Width = ctx.measureText(line2).width;
+ const width = Math.max(line1Width, line2Width);
ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
ctx.fillRect(this.mouseXpos!, MARGIN_TOP, width + 16, RECT_HEIGHT);
ctx.fillStyle = 'hsl(200, 50%, 40%)';
ctx.textAlign = 'left';
- ctx.fillText(procTitle, this.mouseXpos! + 8, 18);
- ctx.fillText(threadTitle, this.mouseXpos! + 8, 28);
+ ctx.fillText(line1, this.mouseXpos! + 8, 18);
+ ctx.fillText(line2, this.mouseXpos! + 8, 28);
}
}