Merge "Edit inline comments in .proto files"
diff --git a/include/perfetto/profiling/memory/client_ext.h b/include/perfetto/profiling/memory/client_ext.h
index 2ad34b3..ca4ce2a 100644
--- a/include/perfetto/profiling/memory/client_ext.h
+++ b/include/perfetto/profiling/memory/client_ext.h
@@ -26,10 +26,12 @@
extern "C" {
#endif
-// This struct is append only. Be very careful that the ABI of this does not
-// change. We want to be able to correctly handle structs from clients that
-// compile against old versions of this header, setting all the newly added
-// fields to zero.
+// Metadata of a custom heap.
+//
+// NB: This struct is append only. Be very careful that the ABI of this does
+// not change. We want to be able to correctly handle structs from clients
+// that compile against old versions of this header, setting all the newly
+// added fields to zero.
//
// TODO(fmayer): Sort out alignment etc. before stabilizing the ABI.
struct HeapprofdHeapInfo {
@@ -38,12 +40,23 @@
void (*callback)(bool /* enabled */);
};
+// Called by libc upon receipt of the profiling signal.
+// DO NOT CALL FROM OTHER CLIENTS!
bool heapprofd_init_session(void* (*malloc_fn)(size_t), void (*free_fn)(void*));
+// Register a heap. Options are given in the HeapprofdHeapInfo struct.
+//
+// On error, returns 0, which can be safely passed to any function, and will
+// turn them into a no-op.
uint32_t heapprofd_register_heap(const HeapprofdHeapInfo* heap_info, size_t n);
+// Reports an allocation on the given heap.
+// Returns whether the allocation was sampled.
bool heapprofd_report_allocation(uint32_t heap_id, uint64_t id, uint64_t size);
+// Report allocation was freed on the given heap.
+// It is allowed to call with an id that was not previously reported as
+// allocated, in which case it does not change the output.
void heapprofd_report_free(uint32_t heap_id, uint64_t id);
#ifdef __cplusplus
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker.cc b/src/trace_processor/importers/proto/heap_graph_tracker.cc
index 663d578..d43d29c 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker.cc
+++ b/src/trace_processor/importers/proto/heap_graph_tracker.cc
@@ -687,6 +687,10 @@
void HeapGraphTracker::NotifyEndOfFile() {
if (!sequence_state_.empty()) {
context_->storage->IncrementStats(stats::heap_graph_non_finalized_graph);
+ // There might still be valuable data even though the trace is truncated.
+ while (!sequence_state_.empty()) {
+ FinalizeProfile(sequence_state_.begin()->first);
+ }
}
}
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 26c0c14..7ff4f18 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -324,6 +324,10 @@
return;
}
sqlite3_value* value = argv[0];
+ if (sqlite3_value_type(value) == SQLITE_NULL) {
+ sqlite3_result_null(ctx);
+ return;
+ }
if (sqlite3_value_type(value) != SQLITE_TEXT) {
sqlite3_result_error(ctx, "Unsupported type of arg passed to DEMANGLE", -1);
return;
diff --git a/ui/src/controller/search_controller.ts b/ui/src/controller/search_controller.ts
index 46cf95c..b81977c 100644
--- a/ui/src/controller/search_controller.ts
+++ b/ui/src/controller/search_controller.ts
@@ -19,12 +19,16 @@
import {Controller} from './controller';
import {App} from './globals';
+export function escapeQuery(s: string): string {
+ // See https://www.sqlite.org/lang_expr.html#:~:text=A%20string%20constant
+ return `'%${s.replace('\'', '\'\'')}%'`;
+}
+
export interface SearchControllerArgs {
engine: Engine;
app: App;
}
-
export class SearchController extends Controller<'main'> {
private engine: Engine;
private app: App;
@@ -126,6 +130,8 @@
resolution: number): Promise<SearchSummary> {
const quantumNs = Math.round(resolution * 10 * 1e9);
+ const searchLiteral = escapeQuery(search);
+
startNs = Math.floor(startNs / quantumNs) * quantumNs;
await this.query(`update search_summary_window set
@@ -135,8 +141,8 @@
where rowid = 0;`);
const rawUtidResult = await this.query(`select utid from thread join process
- using(upid) where thread.name like "%${search}%" or process.name like "%${
- search}%"`);
+ using(upid) where thread.name like ${searchLiteral}
+ or process.name like ${searchLiteral}`);
const utids = [...rawUtidResult.columns[0].longValues!];
@@ -157,7 +163,7 @@
select
quantum_ts
from search_summary_slice_span
- where name like '%${search}%'
+ where name like ${searchLiteral}
)
group by quantum_ts
order by quantum_ts;`);
@@ -179,6 +185,7 @@
}
private async specificSearch(search: string) {
+ const searchLiteral = escapeQuery(search);
// TODO(hjd): we should avoid recomputing this every time. This will be
// easier once the track table has entries for all the tracks.
const cpuToTrackId = new Map();
@@ -197,8 +204,9 @@
}
const rawUtidResult = await this.query(`select utid from thread join process
- using(upid) where thread.name like "%${search}%" or process.name like "%${
- search}%"`);
+ using(upid) where
+ thread.name like ${searchLiteral} or
+ process.name like ${searchLiteral}`);
const utids = [...rawUtidResult.columns[0].longValues!];
const rawResult = await this.query(`
@@ -218,7 +226,7 @@
0 as utid
from slice
inner join track on slice.track_id = track.id
- and slice.name like '%${search}%'
+ and slice.name like ${searchLiteral}
order by ts`);
const numRows = +rawResult.numRecords;
diff --git a/ui/src/controller/search_controller_unittest.ts b/ui/src/controller/search_controller_unittest.ts
new file mode 100644
index 0000000..e3774b4
--- /dev/null
+++ b/ui/src/controller/search_controller_unittest.ts
@@ -0,0 +1,21 @@
+// Copyright (C) 2020 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.
+
+import {escapeQuery} from './search_controller';
+
+test('escapeQuery', () => {
+ expect(escapeQuery(``)).toEqual(`'%%'`);
+ expect(escapeQuery(`hello`)).toEqual(`'%hello%'`);
+ expect(escapeQuery('foo\'bar')).toEqual(`'%foo''bar%'`);
+});