Merge "Do not depend on elf.h for symbolization."
diff --git a/docs/README.md b/docs/README.md
index 00a5e9a..f41504c 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,7 +1,7 @@
# Perfetto - System profiling, app tracing and trace analysis
Perfetto is a production-grade open-source stack for performance
-instrumentation and trace analysis. It offers services and libraries and for
+instrumentation and trace analysis. It offers services and libraries for
recording system-level and app-level traces, native + java heap profiling, a
library for analyzing traces using SQL and a web-based UI to visualize and
explore multi-GB traces.
@@ -12,23 +12,23 @@
At its core, Perfetto introduces a novel userspace-to-userspace
[tracing protocol](/docs/design-docs/api-and-abi.md#tracing-protocol-abi) based
-on direct protobuf serization onto a shared memory buffer. The tracing protocol
-is used both internally for the built-in data sources and exposed to C++ apps
-through the [Tracing SDK](/docs/instrumentation/tracing-sdk.md) and the
+on direct protobuf serialization onto a shared memory buffer. The tracing
+protocol is used both internally for the built-in data sources and exposed to
+C++ apps through the [Tracing SDK](/docs/instrumentation/tracing-sdk.md) and the
[Track Event Library](/docs/instrumentation/track-events.md).
This new tracing protocol allows dynamic configuration of all aspects of tracing
through an extensible protobuf-based capability advertisement and data source
configuration mechanism (see
[Trace configuration docs](/docs/concepts/config.md)).
-Different data sources can be multiplexed onto different sub-sets of
+Different data sources can be multiplexed onto different subsets of
user-defined buffers, allowing also streaming of
[arbitrarily long traces](/docs/concepts/config.md#long-traces) into the
filesystem.
### System-wide tracing on Android and Linux
-On Linux and Anroid, Perfetto bundles a number of data sources that are able to
+On Linux and Android, Perfetto bundles a number of data sources that are able to
gather detailed performance data from different system interfaces. For the full
sets and details see the _Data Sources_ section of the documentation. Same
examples:
@@ -46,7 +46,7 @@
* [Native heap profiling](/docs/data-sources/native-heap-profiler.md): a
low-overhead heap profiler for hooking malloc/free/new/delete and associating
- memory to callstacks, based on out-of-process unwinding, configurable
+ memory to call-stacks, based on out-of-process unwinding, configurable
sampling, attachable to already running processes.
* [Java heap profiling](/docs/data-sources/java-heap-profiler.md): an
@@ -70,7 +70,7 @@
between the flexibility of defining your own strongly-typed events and creating
custom data sources or using the easier-to-use
[Track Event Library](/docs/instrumentation/track-events.md) which allows to
-easily create time-boudned slices, counters and time markers using annotations
+easily create time-bounded slices, counters and time markers using annotations
of the form `TRACE_EVENT("category", "event_name", "x", "str", "y", 42)`.
The SDK is designed for tracing of multi-process systems and multi-threaded
@@ -109,8 +109,8 @@
dedicated project for importing, parsing and querying new and legacy trace
formats, [Trace Processor](/docs/analysis/trace-processor.md).
-Trace Processor is a portable C++11 library that provides a column-oriented
-table storage, designed ad-hoc for for efficiently holding hours of trace data
+Trace Processor is a portable C++11 library that provides column-oriented
+table storage, designed ad-hoc for efficiently holding hours of trace data
into memory and exposes a SQL query interface based on the popular SQLite query
engine.
The trace data model becomes a set of
@@ -136,7 +136,7 @@
Perfetto provides also a brand new trace visualizer for opening and querying
hours-long traces, available at [ui.perfetto.dev](https://ui.perfetto.dev).
-The new visualizer takes advantage of modern web platform technolgies.
+The new visualizer takes advantage of modern web platform technologies.
Its multi-threading design based WebWorkers keeps the UI always responsive;
the analytical power of Trace Processor and SQLite is fully available in-browser
through WebAssembly.
diff --git a/src/profiling/symbolizer/local_symbolizer.cc b/src/profiling/symbolizer/local_symbolizer.cc
index 144a55f..814b5a1 100644
--- a/src/profiling/symbolizer/local_symbolizer.cc
+++ b/src/profiling/symbolizer/local_symbolizer.cc
@@ -304,6 +304,7 @@
size_t size = static_cast<size_t>(statbuf.st_size);
+ static_assert(EI_CLASS > EI_MAG3, "mem[EI_MAG?] accesses are in range.");
if (size <= EI_CLASS)
return false;
diff --git a/test/cts/producer/AndroidManifest.xml b/test/cts/producer/AndroidManifest.xml
index 6139dca..7a5d35d 100755
--- a/test/cts/producer/AndroidManifest.xml
+++ b/test/cts/producer/AndroidManifest.xml
@@ -20,7 +20,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application>
- <activity android:name=".ProducerActivity" >
+ <activity android:name=".ProducerActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
diff --git a/test/cts/test_apps/AndroidManifest_debuggable.xml b/test/cts/test_apps/AndroidManifest_debuggable.xml
index c85ab05..871544e 100755
--- a/test/cts/test_apps/AndroidManifest_debuggable.xml
+++ b/test/cts/test_apps/AndroidManifest_debuggable.xml
@@ -21,11 +21,12 @@
<application android:debuggable="true">
<activity
android:name="android.perfetto.cts.app.MainActivity"
- android:exported="false">
+ android:exported="true">
</activity>
<activity-alias
android:name="android.perfetto.cts.app.debuggable.MainActivity"
- android:targetActivity="android.perfetto.cts.app.MainActivity">
+ android:targetActivity="android.perfetto.cts.app.MainActivity"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -33,11 +34,12 @@
</activity-alias>
<activity
android:name="android.perfetto.cts.app.BusyWaitActivity"
- android:exported="false">
+ android:exported="true">
</activity>
<activity-alias
android:name="android.perfetto.cts.app.debuggable.BusyWaitActivity"
- android:targetActivity="android.perfetto.cts.app.BusyWaitActivity">
+ android:targetActivity="android.perfetto.cts.app.BusyWaitActivity"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -45,4 +47,3 @@
</activity-alias>
</application>
</manifest>
-
diff --git a/test/cts/test_apps/AndroidManifest_profileable.xml b/test/cts/test_apps/AndroidManifest_profileable.xml
index 129e922..6322806 100755
--- a/test/cts/test_apps/AndroidManifest_profileable.xml
+++ b/test/cts/test_apps/AndroidManifest_profileable.xml
@@ -22,11 +22,12 @@
<profileable android:shell="true"/>
<activity
android:name="android.perfetto.cts.app.MainActivity"
- android:exported="false">
+ android:exported="true">
</activity>
<activity-alias
android:name="android.perfetto.cts.app.profileable.MainActivity"
- android:targetActivity="android.perfetto.cts.app.MainActivity">
+ android:targetActivity="android.perfetto.cts.app.MainActivity"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -34,11 +35,12 @@
</activity-alias>
<activity
android:name="android.perfetto.cts.app.BusyWaitActivity"
- android:exported="false">
+ android:exported="true">
</activity>
<activity-alias
android:name="android.perfetto.cts.app.profileable.BusyWaitActivity"
- android:targetActivity="android.perfetto.cts.app.BusyWaitActivity">
+ android:targetActivity="android.perfetto.cts.app.BusyWaitActivity"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
diff --git a/test/cts/test_apps/AndroidManifest_release.xml b/test/cts/test_apps/AndroidManifest_release.xml
index 5b64a94..83d9c47 100755
--- a/test/cts/test_apps/AndroidManifest_release.xml
+++ b/test/cts/test_apps/AndroidManifest_release.xml
@@ -21,11 +21,12 @@
<application>
<activity
android:name="android.perfetto.cts.app.MainActivity"
- android:exported="false">
+ android:exported="true">
</activity>
<activity-alias
android:name="android.perfetto.cts.app.release.MainActivity"
- android:targetActivity="android.perfetto.cts.app.MainActivity">
+ android:targetActivity="android.perfetto.cts.app.MainActivity"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -33,11 +34,12 @@
</activity-alias>
<activity
android:name="android.perfetto.cts.app.BusyWaitActivity"
- android:exported="false">
+ android:exported="true">
</activity>
<activity-alias
android:name="android.perfetto.cts.app.release.BusyWaitActivity"
- android:targetActivity="android.perfetto.cts.app.BusyWaitActivity">
+ android:targetActivity="android.perfetto.cts.app.BusyWaitActivity"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -45,4 +47,3 @@
</activity-alias>
</application>
</manifest>
-
diff --git a/tools/heap_profile b/tools/heap_profile
index 127035d..62f99e4 100755
--- a/tools/heap_profile
+++ b/tools/heap_profile
@@ -160,6 +160,8 @@
"Default 7 days.",
type=int,
default=604800000)
+ # This flag is a no-op now. We never start heapprofd explicitly using system
+ # properties.
parser.add_argument(
"--no-start", help="Do not start heapprofd.", action='store_true')
parser.add_argument(
@@ -363,16 +365,6 @@
['adb', 'shell', 'su root setenforce %s' % enforcing])
subprocess.check_call(['adb', 'shell', 'su root setenforce 0'])
- if not args.no_start:
- heapprofd_prop = subprocess.check_output(
- ['adb', 'shell', 'getprop persist.heapprofd.enable'])
- if heapprofd_prop.strip() != '1':
- subprocess.check_call(
- ['adb', 'shell', 'setprop persist.heapprofd.enable 1'])
- atexit.register(subprocess.check_call,
- ['adb', 'shell', 'setprop persist.heapprofd.enable 0'])
-
-
if args.simpleperf:
subprocess.check_call([
'adb', 'shell', 'mkdir -p /data/local/tmp/heapprofd_profile && '
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index 14f2b8a..deeae01 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -159,7 +159,7 @@
const selectionArgs: SelectionControllerArgs = {engine};
childControllers.push(
- Child('selection', SelectionController, selectionArgs));
+ Child('selection', SelectionController, selectionArgs));
const cpuProfileArgs: CpuProfileControllerArgs = {engine};
childControllers.push(
@@ -540,6 +540,7 @@
const threadCounters = await engine.query(`
select thread_counter_track.name, utid, thread_counter_track.id,
start_ts, end_ts from thread_counter_track join thread using(utid)
+ where thread_counter_track.name not in ('time_in_state')
`);
for (let i = 0; i < threadCounters.numRecords; i++) {
const name = threadCounters.columns[0].stringValues![i];
diff --git a/ui/src/frontend/legacy_trace_viewer.ts b/ui/src/frontend/legacy_trace_viewer.ts
index 4f90fb7..a200ea9 100644
--- a/ui/src/frontend/legacy_trace_viewer.ts
+++ b/ui/src/frontend/legacy_trace_viewer.ts
@@ -17,6 +17,27 @@
import {assertTrue} from '../base/logging';
import {showModal} from './modal';
+const CTRACE_HEADER = 'TRACE:\n';
+
+async function isCtrace(file: File): Promise<boolean> {
+ const fileName = file.name.toLowerCase();
+
+ if (fileName.endsWith('.ctrace')) {
+ return true;
+ }
+
+ // .ctrace files sometimes end with .txt. We can detect these via
+ // the presence of TRACE: near the top of the file.
+ if (fileName.endsWith('.txt')) {
+ const header = await readText(file.slice(0, 128));
+ if (header.includes(CTRACE_HEADER)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
function readText(blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
@@ -35,8 +56,11 @@
export async function isLegacyTrace(file: File): Promise<boolean> {
const fileName = file.name.toLowerCase();
if (fileName.endsWith('.json') || fileName.endsWith('.json.gz') ||
- fileName.endsWith('.zip') || fileName.endsWith('.ctrace') ||
- fileName.endsWith('.html')) {
+ fileName.endsWith('.zip') || fileName.endsWith('.html')) {
+ return true;
+ }
+
+ if (await isCtrace(file)) {
return true;
}
@@ -61,7 +85,7 @@
return false;
}
-export function openFileWithLegacyTraceViewer(file: File) {
+export async function openFileWithLegacyTraceViewer(file: File) {
const reader = new FileReader();
reader.onload = () => {
if (reader.result instanceof ArrayBuffer) {
@@ -76,7 +100,7 @@
console.error(err);
};
if (file.name.endsWith('.gz') || file.name.endsWith('.zip') ||
- file.name.endsWith('.ctrace')) {
+ await isCtrace(file)) {
reader.readAsArrayBuffer(file);
} else {
reader.readAsText(file);
@@ -93,9 +117,10 @@
// Handle .ctrace files.
const enc = new TextDecoder('utf-8');
- const header = enc.decode(data.slice(0, 7));
- if (header === 'TRACE:\n') {
- data = inflate(new Uint8Array(data.slice(7, size)), {to: 'string'});
+ const header = enc.decode(data.slice(0, 128));
+ if (header.includes(CTRACE_HEADER)) {
+ const offset = header.indexOf(CTRACE_HEADER) + CTRACE_HEADER.length;
+ data = inflate(new Uint8Array(data.slice(offset)), {to: 'string'});
}
}
diff --git a/ui/src/frontend/sidebar.ts b/ui/src/frontend/sidebar.ts
index a71d371..3a48a6f 100644
--- a/ui/src/frontend/sidebar.ts
+++ b/ui/src/frontend/sidebar.ts
@@ -646,7 +646,10 @@
if (isDownloadAndShareDisabled() &&
item.hasOwnProperty('checkDownloadDisabled')) {
attrs = {
- onclick: () => alert('Can not download or share external trace.'),
+ onclick: e => {
+ e.preventDefault();
+ alert('Can not download or share external trace.');
+ },
href: '#',
target: null,
disabled: true,