blob: 08aa9df050946bf1a415929fda6b76e8e3d7e7cd [file] [log] [blame]
/*
* Copyright (C) 2019 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.
*/
#ifndef SRC_TRACE_PROCESSOR_TABLES_PROFILER_TABLES_H_
#define SRC_TRACE_PROCESSOR_TABLES_PROFILER_TABLES_H_
#include "src/trace_processor/tables/macros.h"
#include "src/trace_processor/tables/track_tables.h"
namespace perfetto {
namespace trace_processor {
namespace tables {
// The profiler smaps contains the memory stats for virtual memory ranges
// captured by the [heap profiler](/docs/data-sources/native-heap-profiler.md).
// @param upid The UniquePID of the process {@joinable process.upid}.
// @param ts Timestamp of the snapshot. Multiple rows will have the same
// timestamp.
// @param path The mmaped file, as per /proc/pid/smaps.
// @param size_kb Total size of the mapping.
// @param private_dirty_kb KB of this mapping that are private dirty RSS.
// @param swap_kb KB of this mapping that are in swap.
// @param file_name
// @param file_name_iid
// @param path_iid
// @param start_address
// @param module_timestamp
// @param module_debugid
// @param module_debug_path
// @param protection_flags
// @param private_clean_resident_kb
// @param shared_dirty_resident_kb
// @param shared_clean_resident_kb
// @param locked_kb
// @param proportional_resident_kb
// @tablegroup Callstack profilers
#define PERFETTO_TP_PROFILER_SMAPS_DEF(NAME, PARENT, C) \
NAME(ProfilerSmapsTable, "profiler_smaps") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(uint32_t, upid) \
C(int64_t, ts) \
C(StringPool::Id, path) \
C(int64_t, size_kb) \
C(int64_t, private_dirty_kb) \
C(int64_t, swap_kb) \
C(StringPool::Id, file_name) \
C(int64_t, start_address) \
C(int64_t, module_timestamp) \
C(StringPool::Id, module_debugid) \
C(StringPool::Id, module_debug_path) \
C(int64_t, protection_flags) \
C(int64_t, private_clean_resident_kb) \
C(int64_t, shared_dirty_resident_kb) \
C(int64_t, shared_clean_resident_kb) \
C(int64_t, locked_kb) \
C(int64_t, proportional_resident_kb)
PERFETTO_TP_TABLE(PERFETTO_TP_PROFILER_SMAPS_DEF);
// Metadata about packages installed on the system.
// This is generated by the packages_list data-source.
// @param package_name name of the package, e.g. com.google.android.gm.
// @param uid UID processes of this package run as.
// @param debuggable bool whether this app is debuggable.
// @param profileable_from_shell bool whether this app is profileable.
// @param version_code versionCode from the APK.
#define PERFETTO_TP_PACKAGES_LIST_DEF(NAME, PARENT, C) \
NAME(PackageListTable, "package_list") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(StringPool::Id, package_name) \
C(int64_t, uid) \
C(int32_t, debuggable) \
C(int32_t, profileable_from_shell) \
C(int64_t, version_code)
PERFETTO_TP_TABLE(PERFETTO_TP_PACKAGES_LIST_DEF);
// A mapping (binary / library) in a process.
// This is generated by the stack profilers: heapprofd and traced_perf.
// @param build_id hex-encoded Build ID of the binary / library.
// @param start start of the mapping in the process' address space.
// @param end end of the mapping in the process' address space.
// @param name filename of the binary / library {@joinable profiler_smaps.path}.
// @tablegroup Callstack profilers
#define PERFETTO_TP_STACK_PROFILE_MAPPING_DEF(NAME, PARENT, C) \
NAME(StackProfileMappingTable, "stack_profile_mapping") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(StringPool::Id, build_id) \
C(int64_t, exact_offset) \
C(int64_t, start_offset) \
C(int64_t, start) \
C(int64_t, end) \
C(int64_t, load_bias) \
C(StringPool::Id, name)
PERFETTO_TP_TABLE(PERFETTO_TP_STACK_PROFILE_MAPPING_DEF);
// A frame on the callstack. This is a location in a program.
// This is generated by the stack profilers: heapprofd and traced_perf.
// @param name name of the function this location is in.
// @param mapping the mapping (library / binary) this location is in.
// @param rel_pc the program counter relative to the start of the mapping.
// @param symbol_set_id if the profile was offline symbolized, the offline
// symbol information of this frame.
// {@joinable stack_profile_symbol.symbol_set_id}
// @tablegroup Callstack profilers
#define PERFETTO_TP_STACK_PROFILE_FRAME_DEF(NAME, PARENT, C) \
NAME(StackProfileFrameTable, "stack_profile_frame") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(StringPool::Id, name) \
C(StackProfileMappingTable::Id, mapping) \
C(int64_t, rel_pc) \
C(base::Optional<uint32_t>, symbol_set_id) \
C(base::Optional<StringPool::Id>, deobfuscated_name)
PERFETTO_TP_TABLE(PERFETTO_TP_STACK_PROFILE_FRAME_DEF);
// A callsite. This is a list of frames that were on the stack.
// This is generated by the stack profilers: heapprofd and traced_perf.
// @param depth distance from the bottom-most frame of the callstack.
// @param parent_id parent frame on the callstack. NULL for the bottom-most.
// @param frame_id frame at this position in the callstack.
// @tablegroup Callstack profilers
#define PERFETTO_TP_STACK_PROFILE_CALLSITE_DEF(NAME, PARENT, C) \
NAME(StackProfileCallsiteTable, "stack_profile_callsite") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(uint32_t, depth) \
C(base::Optional<StackProfileCallsiteTable::Id>, parent_id) \
C(StackProfileFrameTable::Id, frame_id)
PERFETTO_TP_TABLE(PERFETTO_TP_STACK_PROFILE_CALLSITE_DEF);
// TODO(rsavitski): rethink what to do with the root table now that only chrome
// callstacks use it.
// Root table for timestamped stack samples.
// @param ts timestamp of the sample.
// @param callsite_id unwound callstack.
// @tablegroup Callstack profilers
#define PERFETTO_TP_STACK_SAMPLE_DEF(NAME, PARENT, C) \
NAME(StackSampleTable, "stack_sample") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(int64_t, ts, Column::Flag::kSorted) \
C(StackProfileCallsiteTable::Id, callsite_id)
PERFETTO_TP_TABLE(PERFETTO_TP_STACK_SAMPLE_DEF);
// Samples from the Chromium stack sampler.
// @param ts timestamp this sample was taken at.
// @param utid thread that was active when the sample was taken.
// @param callsite_id callstack in active thread at time of sample.
// @tablegroup Callstack profilers
#define PERFETTO_TP_CPU_PROFILE_STACK_SAMPLE_DEF(NAME, PARENT, C) \
NAME(CpuProfileStackSampleTable, "cpu_profile_stack_sample") \
PARENT(PERFETTO_TP_STACK_SAMPLE_DEF, C) \
C(uint32_t, utid) \
C(int32_t, process_priority)
PERFETTO_TP_TABLE(PERFETTO_TP_CPU_PROFILE_STACK_SAMPLE_DEF);
// Samples from the traced_perf perf sampler.
//
// The table currently provides no means of discriminating between multiple data
// sources producing samples within a single trace.
// @param ts timestamp of the sample.
// @param utid sampled thread. {@joinable thread.utid}.
// @param cpu the core the sampled thread was running on.
// @param cpu_mode execution state (userspace/kernelspace) of the sampled
// thread.
// @param callsite_id if set, unwound callstack of the sampled thread.
// @param unwind_error if set, indicates that the unwinding for this sample
// encountered an error. Such samples still reference the best-effort
// result via the callsite_id (with a synthetic error frame at the point
// where unwinding stopped).
// @param perf_session_id distinguishes samples from different profiling
// streams (i.e. multiple data sources).
// {@joinable perf_counter_track.perf_session_id}
// @tablegroup Callstack profilers
#define PERFETTO_TP_PERF_SAMPLE_DEF(NAME, PARENT, C) \
NAME(PerfSampleTable, "perf_sample") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(int64_t, ts, Column::Flag::kSorted) \
C(uint32_t, utid) \
C(uint32_t, cpu) \
C(StringPool::Id, cpu_mode) \
C(base::Optional<StackProfileCallsiteTable::Id>, callsite_id) \
C(base::Optional<StringPool::Id>, unwind_error) \
C(uint32_t, perf_session_id)
PERFETTO_TP_TABLE(PERFETTO_TP_PERF_SAMPLE_DEF);
// Symbolization data for a frame. Rows with the same symbol_set_id describe
// one callframe, with the most-inlined symbol having id == symbol_set_id.
//
// For instance, if the function foo has an inlined call to the function bar,
// which has an inlined call to baz, the stack_profile_symbol table would look
// like this.
//
// ```
// |id|symbol_set_id|name |source_file|line_number|
// |--|-------------|-------------|-----------|-----------|
// |1 | 1 |baz |foo.cc | 36 |
// |2 | 1 |bar |foo.cc | 30 |
// |3 | 1 |foo |foo.cc | 60 |
// ```
// @param name name of the function.
// @param source_file name of the source file containing the function.
// @param line_number line number of the frame in the source file. This is the
// exact line for the corresponding program counter, not the beginning of the
// function.
// @tablegroup Callstack profilers
#define PERFETTO_TP_SYMBOL_DEF(NAME, PARENT, C) \
NAME(SymbolTable, "stack_profile_symbol") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(uint32_t, symbol_set_id) \
C(StringPool::Id, name) \
C(StringPool::Id, source_file) \
C(uint32_t, line_number)
PERFETTO_TP_TABLE(PERFETTO_TP_SYMBOL_DEF);
// Allocations that happened at a callsite.
//
//
// NOTE: this table is not sorted by timestamp intentionanlly - see b/193757386
// for details.
// TODO(b/193757386): readd the sorted flag once this bug is fixed.
//
// This is generated by heapprofd.
// @param ts the timestamp the allocations happened at. heapprofd batches
// allocations and frees, and all data from a dump will have the same
// timestamp.
// @param upid the UniquePID of the allocating process.
// {@joinable process.upid}
// @param callsite_id the callsite the allocation happened at.
// @param count if positive: number of allocations that happened at this
// callsite. if negative: number of allocations that happened at this callsite
// that were freed.
// @param size if positive: size of allocations that happened at this
// callsite. if negative: size of allocations that happened at this callsite
// that were freed.
// @tablegroup Callstack profilers
#define PERFETTO_TP_HEAP_PROFILE_ALLOCATION_DEF(NAME, PARENT, C) \
NAME(HeapProfileAllocationTable, "heap_profile_allocation") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(int64_t, ts) \
C(uint32_t, upid) \
C(StringPool::Id, heap_name) \
C(StackProfileCallsiteTable::Id, callsite_id) \
C(int64_t, count) \
C(int64_t, size)
PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_PROFILE_ALLOCATION_DEF);
// Table used to render flamegraphs. This gives cumulative sizes of nodes in
// the flamegraph.
//
// WARNING: This is experimental and the API is subject to change.
// @tablegroup Callstack profilers
#define PERFETTO_TP_EXPERIMENTAL_FLAMEGRAPH_NODES(NAME, PARENT, C) \
NAME(ExperimentalFlamegraphNodesTable, "experimental_flamegraph_nodes") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(int64_t, ts, Column::Flag::kSorted | Column::Flag::kHidden) \
C(uint32_t, upid, Column::Flag::kHidden) \
C(StringPool::Id, profile_type, Column::Flag::kHidden) \
C(StringPool::Id, focus_str, Column::Flag::kHidden) \
C(uint32_t, depth) \
C(StringPool::Id, name) \
C(StringPool::Id, map_name) \
C(int64_t, count) \
C(int64_t, cumulative_count) \
C(int64_t, size) \
C(int64_t, cumulative_size) \
C(int64_t, alloc_count) \
C(int64_t, cumulative_alloc_count) \
C(int64_t, alloc_size) \
C(int64_t, cumulative_alloc_size) \
C(base::Optional<ExperimentalFlamegraphNodesTable::Id>, parent_id) \
C(base::Optional<StringPool::Id>, source_file) \
C(base::Optional<uint32_t>, line_number) \
C(base::Optional<StringPool::Id>, upid_group)
PERFETTO_TP_TABLE(PERFETTO_TP_EXPERIMENTAL_FLAMEGRAPH_NODES);
// @param name (potentially obfuscated) name of the class.
// @param deobfuscated_name if class name was obfuscated and deobfuscation map
// for it provided, the deobfuscated name.
// @param location the APK / Dex / JAR file the class is contained in.
// @tablegroup ART Heap Graphs
//
// classloader_id should really be HeapGraphObject::id, but that would
// create a loop, which is currently not possible.
// TODO(lalitm): resolve this
#define PERFETTO_TP_HEAP_GRAPH_CLASS_DEF(NAME, PARENT, C) \
NAME(HeapGraphClassTable, "heap_graph_class") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(StringPool::Id, name) \
C(base::Optional<StringPool::Id>, deobfuscated_name) \
C(base::Optional<StringPool::Id>, location) \
C(base::Optional<HeapGraphClassTable::Id>, superclass_id) \
C(base::Optional<uint32_t>, classloader_id) \
C(StringPool::Id, kind)
PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_GRAPH_CLASS_DEF);
// The objects on the Dalvik heap.
//
// All rows with the same (upid, graph_sample_ts) are one dump.
// @param upid UniquePid of the target {@joinable process.upid}.
// @param graph_sample_ts timestamp this dump was taken at.
// @param self_size size this object uses on the Java Heap.
// @param native_size approximate amount of native memory used by this object,
// as reported by libcore.util.NativeAllocationRegistry.size.
// @param reference_set_id join key with heap_graph_reference containing all
// objects referred in this object's fields.
// {@joinable heap_graph_reference.reference_set_id}
// @param reachable bool whether this object is reachable from a GC root. If
// false, this object is uncollected garbage.
// @param type_id class this object is an instance of.
// @param root_type if not NULL, this object is a GC root.
// @tablegroup ART Heap Graphs
#define PERFETTO_TP_HEAP_GRAPH_OBJECT_DEF(NAME, PARENT, C) \
NAME(HeapGraphObjectTable, "heap_graph_object") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(uint32_t, upid) \
C(int64_t, graph_sample_ts) \
C(int64_t, self_size) \
C(int64_t, native_size) \
C(base::Optional<uint32_t>, reference_set_id, Column::Flag::kDense) \
C(int32_t, reachable) \
C(HeapGraphClassTable::Id, type_id) \
C(base::Optional<StringPool::Id>, root_type) \
C(int32_t, root_distance, Column::Flag::kHidden)
PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_GRAPH_OBJECT_DEF);
// Many-to-many mapping between heap_graph_object.
//
// This associates the object with given reference_set_id with the objects
// that are referred to by its fields.
// @param reference_set_id join key to heap_graph_object.
// @param owner_id id of object that has this reference_set_id.
// @param owned_id id of object that is referred to.
// @param field_name the field that refers to the object. E.g. Foo.name.
// @param field_type_name the static type of the field. E.g. java.lang.String.
// @param deobfuscated_field_name if field_name was obfuscated and a
// deobfuscation mapping was provided for it, the deobfuscated name.
// @tablegroup ART Heap Graphs
#define PERFETTO_TP_HEAP_GRAPH_REFERENCE_DEF(NAME, PARENT, C) \
NAME(HeapGraphReferenceTable, "heap_graph_reference") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(uint32_t, reference_set_id, Column::Flag::kSorted) \
C(HeapGraphObjectTable::Id, owner_id) \
C(base::Optional<HeapGraphObjectTable::Id>, owned_id) \
C(StringPool::Id, field_name) \
C(StringPool::Id, field_type_name) \
C(base::Optional<StringPool::Id>, deobfuscated_field_name)
PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_GRAPH_REFERENCE_DEF);
// @param arg_set_id {@joinable args.arg_set_id}
#define PERFETTO_TP_VULKAN_MEMORY_ALLOCATIONS_DEF(NAME, PARENT, C) \
NAME(VulkanMemoryAllocationsTable, "vulkan_memory_allocations") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(StringPool::Id, source) \
C(StringPool::Id, operation) \
C(int64_t, timestamp) \
C(base::Optional<uint32_t>, upid) \
C(base::Optional<int64_t>, device) \
C(base::Optional<int64_t>, device_memory) \
C(base::Optional<uint32_t>, memory_type) \
C(base::Optional<uint32_t>, heap) \
C(base::Optional<StringPool::Id>, function_name) \
C(base::Optional<int64_t>, object_handle) \
C(base::Optional<int64_t>, memory_address) \
C(base::Optional<int64_t>, memory_size) \
C(StringPool::Id, scope) \
C(base::Optional<uint32_t>, arg_set_id)
PERFETTO_TP_TABLE(PERFETTO_TP_VULKAN_MEMORY_ALLOCATIONS_DEF);
#define PERFETTO_TP_GPU_COUNTER_GROUP_DEF(NAME, PARENT, C) \
NAME(GpuCounterGroupTable, "gpu_counter_group") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(int32_t, group_id) \
C(TrackTable::Id, track_id)
PERFETTO_TP_TABLE(PERFETTO_TP_GPU_COUNTER_GROUP_DEF);
} // namespace tables
} // namespace trace_processor
} // namespace perfetto
#endif // SRC_TRACE_PROCESSOR_TABLES_PROFILER_TABLES_H_