Merge "fix zombie process"
diff --git a/ui/src/assets/common.scss b/ui/src/assets/common.scss
index 065a306..fb4a2fa 100644
--- a/ui/src/assets/common.scss
+++ b/ui/src/assets/common.scss
@@ -761,6 +761,10 @@
   .empty-result {
     padding: 10px;
   }
+
+  td.menu {
+    text-align: left;
+  }
 }
 
 .name-completion {
diff --git a/ui/src/common/empty_state.ts b/ui/src/common/empty_state.ts
index 1e6e303..197cbad 100644
--- a/ui/src/common/empty_state.ts
+++ b/ui/src/common/empty_state.ts
@@ -62,7 +62,7 @@
     pivotTableRedux: {
       selectionArea: null,
       queryResult: null,
-      editMode: true,
+      editMode: false,
       selectedPivotsMap: keyedMap(
           columnKey,
           {kind: 'regular', table: 'slice', column: 'category'},
diff --git a/ui/src/controller/track_decider.ts b/ui/src/controller/track_decider.ts
index baad0de..eddf018 100644
--- a/ui/src/controller/track_decider.ts
+++ b/ui/src/controller/track_decider.ts
@@ -1285,12 +1285,11 @@
     ) using (upid)
     left join (
       select
-        process.upid as upid,
-        count(*) as perfSampleCount
-      from process
-        join thread on process.upid = thread.upid
-        join perf_sample on thread.utid = perf_sample.utid
-      group by process.upid
+        thread.upid as upid,
+        sum(cnt) as perfSampleCount
+      from (select utid, count(*) as cnt from perf_sample group by utid) s
+        join thread on thread.utid = s.utid
+      group by thread.upid
     ) using (upid)
     left join (
       select
@@ -1313,10 +1312,10 @@
       perfSampleCount desc,
       total_dur desc,
       sliceCount desc,
-      processName,
-      the_tracks.upid,
-      threadName,
-      the_tracks.utid;
+      processName asc nulls last,
+      the_tracks.upid asc nulls last,
+      threadName asc nulls last,
+      the_tracks.utid asc nulls last;
   `);
 
     const it = result.iter({
diff --git a/ui/src/frontend/pivot_table_redux.ts b/ui/src/frontend/pivot_table_redux.ts
index 05a1595..c3d3393 100644
--- a/ui/src/frontend/pivot_table_redux.ts
+++ b/ui/src/frontend/pivot_table_redux.ts
@@ -186,14 +186,6 @@
   renderResultsView(attrs: PivotTableReduxAttrs) {
     return m(
         '.pivot-table-redux',
-        m('button.mode-button',
-          {
-            onclick: () => {
-              globals.dispatch(Actions.setPivotTableEditMode({editMode: true}));
-              globals.rafScheduler.scheduleFullRedraw();
-            },
-          },
-          'Edit'),
         this.renderResultsTable(attrs));
   }
 
@@ -500,7 +492,19 @@
           // columns, as well as popup menus to modify the columns. Last cell
           // is empty because of an extra column with "drill down" button for
           // each pivot table row.
-          m('tr', pivotTableHeaders, aggregationTableHeaders, m('td'))),
+          m('tr',
+            pivotTableHeaders,
+            aggregationTableHeaders,
+            m('td.menu', m(PopupMenuButton, {
+                icon: 'menu',
+                items: [{
+                  text: 'Edit mode',
+                  callback: () => {
+                    globals.dispatch(
+                        Actions.setPivotTableEditMode({editMode: true}));
+                  },
+                }],
+              })))),
         m('tbody', this.renderTotalsRow(state.queryResult), renderedRows));
   }
 
diff --git a/ui/src/test/diff_viewer/script.js b/ui/src/test/diff_viewer/script.js
index c9c14bd..b193c55 100644
--- a/ui/src/test/diff_viewer/script.js
+++ b/ui/src/test/diff_viewer/script.js
@@ -40,10 +40,16 @@
 function processLines(lines) {
   const container = document.querySelector('.container');
   container.innerHTML = '';
+  let hasErrors = false;
 
   // report.txt is a text file with a pair of file names on each line, separated
   // by semicolon. E.g. "screenshot.png;screenshot-diff.png"
   for (const line of lines) {
+    // Skip empty lines (happens when the file is completely empty).
+    if (line.length === 0) {
+      continue;
+    }
+
     const parts = line.split(';');
     if (parts.length !== 2) {
       console.warn(
@@ -52,6 +58,7 @@
       continue;
     }
 
+    hasErrors = true;
     const [output, diff] = parts;
     const outputImage = m('img');
     outputImage.src = output;
@@ -64,7 +71,7 @@
           m('div.cell', diff, m('div.image-wrapper', diffImage))));
   }
 
-  if (lines.length === 0) {
+  if (!hasErrors) {
     container.appendChild(m('div', 'All good!'));
   }
 }