Merge "trace_processor: Add execution time to raw_query.proto"
diff --git a/include/perfetto/base/file_utils.h b/include/perfetto/base/file_utils.h
index 3126b7c..1efb450 100644
--- a/include/perfetto/base/file_utils.h
+++ b/include/perfetto/base/file_utils.h
@@ -17,9 +17,9 @@
#ifndef INCLUDE_PERFETTO_BASE_FILE_UTILS_H_
#define INCLUDE_PERFETTO_BASE_FILE_UTILS_H_
-#include <string>
+#include <stddef.h>
-#include "perfetto/base/build_config.h"
+#include <string>
namespace perfetto {
namespace base {
@@ -27,8 +27,6 @@
bool ReadFileDescriptor(int fd, std::string* out);
bool ReadFile(const std::string& path, std::string* out);
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-
// Call write until all data is written or an error is detected.
//
// man 2 write:
@@ -38,8 +36,6 @@
// succeeds, and returns the number of bytes written.
ssize_t WriteAll(int fd, const void* buf, size_t count);
-#endif
-
} // namespace base
} // namespace perfetto
diff --git a/protos/perfetto/trace/chrome/chrome_trace_event.proto b/protos/perfetto/trace/chrome/chrome_trace_event.proto
index a004d92..7911f42 100644
--- a/protos/perfetto/trace/chrome/chrome_trace_event.proto
+++ b/protos/perfetto/trace/chrome/chrome_trace_event.proto
@@ -41,7 +41,7 @@
// Takes precedence over |name| if set,
// and is an index into |string_table|.
- optional int32 name_index = 9;
+ optional uint32 name_index = 9;
}
optional string name = 1;
@@ -63,8 +63,8 @@
// Takes precedence over respectively |name| and
// |category_group_name_index| if set,
// and are indices into |string_table|.
- optional int32 name_index = 15;
- optional int32 category_group_name_index = 16;
+ optional uint32 name_index = 15;
+ optional uint32 category_group_name_index = 16;
}
message ChromeMetadata {
diff --git a/src/base/file_utils.cc b/src/base/file_utils.cc
index 89440b1..44b27f7 100644
--- a/src/base/file_utils.cc
+++ b/src/base/file_utils.cc
@@ -16,12 +16,15 @@
#include <sys/stat.h>
+#include "perfetto/base/build_config.h"
#include "perfetto/base/file_utils.h"
-
#include "perfetto/base/logging.h"
#include "perfetto/base/scoped_file.h"
+
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <unistd.h>
+#else
+#include <corecrt_io.h>
#endif
namespace perfetto {
@@ -63,8 +66,6 @@
return ReadFileDescriptor(*fd, out);
}
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-
ssize_t WriteAll(int fd, const void* buf, size_t count) {
size_t written = 0;
while (written < count) {
@@ -79,7 +80,5 @@
return static_cast<ssize_t>(written);
}
-#endif
-
} // namespace base
} // namespace perfetto
diff --git a/src/base/unix_socket.cc b/src/base/unix_socket.cc
index fb4f5ff..bb56248 100644
--- a/src/base/unix_socket.cc
+++ b/src/base/unix_socket.cc
@@ -65,7 +65,8 @@
#endif
void ShiftMsgHdr(size_t n, struct msghdr* msg) {
- for (size_t i = 0; i < msg->msg_iovlen; ++i) {
+ using LenType = decltype(msg->msg_iovlen); // Mac and Linux don't agree.
+ for (LenType i = 0; i < msg->msg_iovlen; ++i) {
struct iovec* vec = &msg->msg_iov[i];
if (n < vec->iov_len) {
// We sent a part of this iovec.
diff --git a/src/base/unix_socket_unittest.cc b/src/base/unix_socket_unittest.cc
index 06dd63a..531f1e4 100644
--- a/src/base/unix_socket_unittest.cc
+++ b/src/base/unix_socket_unittest.cc
@@ -16,6 +16,7 @@
#include "perfetto/base/unix_socket.h"
+#include <signal.h>
#include <sys/mman.h>
#include <list>
diff --git a/src/profiling/memory/unwinding.cc b/src/profiling/memory/unwinding.cc
index 8ed2780..f43743b 100644
--- a/src/profiling/memory/unwinding.cc
+++ b/src/profiling/memory/unwinding.cc
@@ -145,7 +145,7 @@
flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP;
}
maps_.push_back(
- new unwindstack::MapInfo(start, end, pgoff, flags, name));
+ new unwindstack::MapInfo(nullptr, start, end, pgoff, flags, name));
});
}
diff --git a/tools/install-build-deps b/tools/install-build-deps
index 7770631..1efaf33 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -163,7 +163,7 @@
# These dependencies are for libunwindstack, which is used by src/profiling.
('buildtools/android-core',
'https://android.googlesource.com/platform/system/core.git',
- 'ec004eb1b376d2d9008829a25f47ac3fcfd728ab',
+ 'd3a7ddcf8dd97e162d7d4a9b3f87b4f1ef797d5f',
'all'
),
@@ -175,7 +175,7 @@
('buildtools/bionic',
'https://android.googlesource.com/platform/bionic.git',
- '3fd45bba4857fdbf320b6e89d2ae0569d9463bf5',
+ '4b7c5cca7fbd0330cdfef41c97f1401824e78fba',
'all'
),
diff --git a/ui/src/assets/perfetto.scss b/ui/src/assets/perfetto.scss
index cac3d75..8ef1161 100644
--- a/ui/src/assets/perfetto.scss
+++ b/ui/src/assets/perfetto.scss
@@ -312,6 +312,19 @@
height: 25px;
}
+header.overview {
+ display: flex;
+ justify-content: space-between;
+}
+
+.query-error {
+ user-select: text;
+}
+
+span.code {
+ user-select: text;
+}
+
.text-column {
font-size: 115%;
// 2-3 alphabets per line is comfortable for reading.
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index 98cc5e4..e68d26c 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -199,9 +199,13 @@
}));
}
- const threadQuery = await engine.query(
- 'select upid, utid, tid, thread.name, max(slices.depth) ' +
- 'from thread inner join slices using(utid) group by utid');
+ const threadQuery = await engine.query(`
+ select upid, utid, tid, thread.name, depth
+ from thread inner join (
+ select utid, max(slices.depth) as depth
+ from slices
+ group by utid
+ ) using(utid)`);
for (let i = 0; i < threadQuery.numRecords; i++) {
const upid = threadQuery.columns[0].longValues![i];
const utid = threadQuery.columns[1].longValues![i];
diff --git a/ui/src/frontend/clipboard.ts b/ui/src/frontend/clipboard.ts
new file mode 100644
index 0000000..28d70be
--- /dev/null
+++ b/ui/src/frontend/clipboard.ts
@@ -0,0 +1,23 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+export async function copyToClipboard(text: string): Promise<void> {
+ try {
+ // TODO(hjd): Fix typescript type for navigator.
+ // tslint:disable-next-line no-any
+ await(navigator as any).clipboard.writeText(text);
+ } catch (err) {
+ console.error(`Failed to copy "${text}" to clipboard: ${err}`);
+ }
+}
diff --git a/ui/src/frontend/record_page.ts b/ui/src/frontend/record_page.ts
index 79d8417..21e295e 100644
--- a/ui/src/frontend/record_page.ts
+++ b/ui/src/frontend/record_page.ts
@@ -14,21 +14,12 @@
import * as m from 'mithril';
+import {copyToClipboard} from './clipboard';
import {createPage} from './pages';
const RECORD_COMMAND_LINE =
'echo CgYIgKAGIAESIwohCgxsaW51eC5mdHJhY2UQAKIGDhIFc2NoZWQSBWlucHV0GJBOMh0KFnBlcmZldHRvLnRyYWNlZF9wcm9iZXMQgCAYBEAASAA= | base64 --decode | adb shell "perfetto -c - -o /data/misc/perfetto-traces/trace" && adb pull /data/misc/perfetto-traces/trace /tmp/trace';
-async function copyToClipboard(text: string): Promise<void> {
- try {
- // TODO(hjd): Fix typescript type for navigator.
- // tslint:disable-next-line no-any
- await(navigator as any).clipboard.writeText(text);
- } catch (err) {
- console.error(`Failed to copy "${text}" to clipboard: ${err}`);
- }
-}
-
interface CodeSampleAttrs {
text: string;
}
diff --git a/ui/src/frontend/viewer_page.ts b/ui/src/frontend/viewer_page.ts
index adca962..d89bd5d 100644
--- a/ui/src/frontend/viewer_page.ts
+++ b/ui/src/frontend/viewer_page.ts
@@ -17,6 +17,7 @@
import {QueryResponse} from '../common/queries';
import {TimeSpan} from '../common/time';
+import {copyToClipboard} from './clipboard';
import {FlameGraphPanel} from './flame_graph_panel';
import {globals} from './globals';
import {HeaderPanel} from './header_panel';
@@ -54,8 +55,27 @@
return m(
'div',
m('header.overview',
- `Query result - ${Math.round(resp.durationMs)} ms`,
- m('span.code', resp.query)),
+ m('span',
+ `Query result - ${Math.round(resp.durationMs)} ms`,
+ m('span.code', resp.query)),
+ resp.error ? null :
+ m('button',
+ {
+ onclick: () => {
+ const lines: string[][] = [];
+ lines.push(resp.columns);
+ for (const row of resp.rows) {
+ const line = [];
+ for (const col of resp.columns) {
+ line.push(row[col].toString());
+ }
+ lines.push(line);
+ }
+ copyToClipboard(
+ lines.map(line => line.join('\t')).join('\n'));
+ },
+ },
+ 'Copy as .tsv')),
resp.error ?
m('.query-error', `SQL error: ${resp.error}`) :
m('table.query-table', m('thead', header), m('tbody', rows)));