Skip to content

Commit 74eab85

Browse files
authored
Merge branch 'main' into dev/annabauza/android_users_table_processor
2 parents 4b6a18d + 60d98b4 commit 74eab85

File tree

19 files changed

+1500
-197
lines changed

19 files changed

+1500
-197
lines changed

docs/AGENTS.md

Lines changed: 116 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,48 @@
1-
# Perfetto Project Development Guidelines
1+
# Perfetto Project Development Guidelines for AI Agents
22

3-
This document provides essential instructions and best practices for developing
4-
in the Perfetto codebase. Adhere to these guidelines to ensure consistency and
5-
quality.
3+
This document provides essential instructions and best practices for developing in the Perfetto codebase. Adhere to these guidelines to ensure consistency and quality.
64

7-
## 1. Building the Project
5+
## Overview
6+
7+
The perfetto repo contains several projects. These are the major ones
8+
9+
1. Tracing services: a set of C++ projects that ship on the target device being traced. They live in src/{traced, traced_probes, tracing}. Target names: perfetto, traced, traced_probes, traced_perf, heapprofd.
10+
11+
2. Tracing SDK: this lives in src/tracing. They are used by apps that want to use Perfetto tro emit trace events. There are two flavours of this SDK.
12+
- The (older) C++ SDK: reachable via include/perfetto/tracing/.
13+
- The (newer) C SDK: reachable via include/perfetto/public.
14+
15+
3. TraceProcessor: a C++ project that lives in src/trace_processor/. This code is typically NOT shipped on device and is used by offline tools. It is internally based on sqlite and it extends its query engine via the vtable API. The UI uses this building in Wasm (Web Assembly).
16+
17+
4. Perfetto UI: This is a Single Page Web Application, client-only (no server component) written in TypeScript that powers ui.perfetto.dev. It lives in ui/. It embeds TraceProcessor via Wasm.
18+
19+
5. A bunch of other tools and utilities used rarely, in tools/ and src/tools.
20+
21+
## Core Software Engineering Principles
22+
23+
Follow these principles when writing and modifying code.
24+
25+
- Avoid code duplication: Before writing a new function, search the codebase for existing functions that provide similar functionality.
26+
- Reuse and refactor: If a suitable function exists, reuse it. If it's close but not an exact match, consider refactoring the existing function to accommodate the new use case instead of creating a copy.
27+
- Consult if unsure: If you are considering duplicating a function or a significant block of code, consult with the user first.
28+
29+
## C++ projects overview
30+
31+
GN supports different configurations, one per out/* folder. You can inspect them by looking at out/xxx/args.gn. Typically when building/running tests while developing, we target our local machine (linux or mac) and we do NOT use android targets.
832

933
Use the following commands to build the project for different configurations.
1034
All commands should be run from the root of the repository.
1135

12-
The output folder where code is built lives in out/xxx. Different people use
13-
different output folders. Pick the output folder as follows
36+
The output folder where code is built lives in out/xxx. Different people use different output folders.
37+
Pick the output folder as follows
38+
1439
- The $OUT env var should contain the path of the output folder. If it exists respect that.
15-
- If $OUT is empty/unset, set it by looking at the most recent out/ subdir, i.e.
16-
`OUT=out/$(ls -t1 out | head -n1)`
40+
- If $OUT is empty/unset, set it by looking at the most recent out/ subdir, i.e. `export OUT=out/$(ls -t1 out | head -n1)`
1741

1842
### Building C++ code
1943

20-
Our C++ sources use tools/gn and tools/ninja to build.
44+
Our primary build system is "gn" (GenerateNinja) + "ninja".
45+
These tools are checked in and accessible via wrapper scripts in our repo, tools/gn and tools/ninja.
2146

2247
- If you touch a .gn or .gni file, rerun `tools/gn gen --check $OUT`
2348
- Afterwards, you can build code running `tools/ninja -C $OUT TARGET_NAME"
@@ -31,16 +56,72 @@ When adding/removing source files, keep BUILD.gn files updated.
3156
Usually there is a BUILD.gn file in each directory. If not, look at closer parent dirs for precedent.
3257

3358
Never bother manually updating Android.bp files or bazel BUILD files.
34-
Those are autogenerated later when uploading the pull request via
35-
`tools/gen_all $OUT`, but humans will take care of that.
59+
Those are autogenerated later when uploading the pull request via `tools/gen_all $OUT`, but humans will take care of that.
3660

3761
To build one or more targets:
3862

3963
```sh
4064
tools/ninja -C $OUT -k 10000 trace_processor_shell perfetto_unittests
4165
```
4266

43-
### 2. Running C++ Tests
67+
All the C++ projects share the same "base" target (include/perfetto/base, include/ext/perfetto/base) and can share some other targets (See GN).
68+
69+
### C++ Code style
70+
71+
We mainly adhere to the Google C++ style guide, which you can consult here
72+
https://google.github.io/styleguide/cppguide.html
73+
74+
Highlights:
75+
76+
- Use C++17.
77+
- Don't use exceptions, don't bother with try/catch.
78+
- Try to keep template usage to a minimum.
79+
- Prefer forward declarations in header files, and #include the needed deps in the .cc files.
80+
- We fail fast. If something shouldn't happen add a PERFETTO_DCHECK() (debug only) or a PERFETTO_CHECK() (production).
81+
- Remember to never put code with side effects inside a PERFETTO_DCHECK, as those become no-ops in release builds.
82+
- If a function argument is out or inout, pass it by pointer, not by reference.
83+
- Delete copy and move constructors unless they are really needed.
84+
- If you need a copy/move constructor use the same pattern seen in include/perfetto/ext/base/circular_queue.h
85+
- Use PERFETTO_DLOG (debug only), PERFETTO_LOG/ILOG/ELOG() for logging.
86+
- Variable names should be proportional to the scope and distance. Variables used in a small loop can be called i,j; Variables scoped to a function should be shorter; Variables/function used across different files should be longer (within reasonable limits) and less prone to collisions when code-searching.
87+
- Avoid libraries other than STL, posix/Unix common headers, and other libraries that we already pull in buildtools/. If you think you need a new library, ask the user.
88+
- Generally, be consistent with the style of the file.
89+
90+
When possible try to use data structures and constructs available in include/perfetto/base/ and include/perfetto/ext/base/. Generally look for precedent in the codebase. If in doubt, ask the .
91+
92+
Frequently used includes you should look into are, under include/:
93+
94+
- perfetto/base/task_runner.h"
95+
- perfetto/base/compiler.h"
96+
- perfetto/base/time.h"
97+
- perfetto/ext/base/status_or.h"
98+
- perfetto/ext/base/scoped_file.h"
99+
- perfetto/ext/base/file_utils.h"
100+
- perfetto/ext/base/flat_hash_map.h"
101+
- perfetto/ext/base/utils.h"
102+
- perfetto/ext/base/string_view.h"
103+
- perfetto/ext/base/string_utils.h"
104+
- perfetto/base/status.h"
105+
- perfetto/base/logging.h"
106+
107+
When creating new files, this is where you put headers:
108+
109+
- .cc files always go under src/, with the exception of some test/ code.
110+
- If possible, keep .h headers private and keep them alongside the .cc file.
111+
- If needed you can put headers in include/perfetto/ext, as that is a non-public API surface.
112+
- In rare cases, if the user says so, you can put new headers in include/perfetto/public, but that's only for C-SDK cases.
113+
- Note that "include/" is in the include path, so you never need to type #include "include/perfetto/foo" but only #include "perfetto/foo".
114+
115+
### Supporting different OSes in C++
116+
117+
We generally support all the major platforms (Linux, Android, MacOS/iOS, Windows) in our codebase, with the exception of src/traced which is supported only on Linux/Android (and few parts on MacOS).
118+
119+
If you need to split code for different platforms, you must use perfetto/base/build_config.h, and specifically the macros therein defined as `#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)` and so on.
120+
121+
Note that every PERFETTO_BUILDFLAG_DEFINE_XXX that you see there must be used via the PERFETTO_BUILDFLAG(XXX) wrapper.
122+
For example PERFETTO_BUILDFLAG(PERFETTO_OS_QNX) when you see PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_QNX.
123+
124+
### Running C++ Tests
44125

45126
Perfetto uses the Google Test framework. You will see c++ sources like
46127
```cpp
@@ -69,55 +150,33 @@ For perfetto_benchmarks you need instead to run
69150
$OUT/perfetto_benchmarks --benchmark_filter='.*BM_RtMutex_NoContention.*'
70151
```
71152

72-
Note that unlike Google Test, where the filter is a glob, in Google Benchmarks the filter is a regex.
153+
Note that unlike Google Test, where the filter is a glob, in Google Benchmarks
154+
the filter is a regex.
73155

74156
### Trace Processor Diff Tests
75157

76-
Trace Processor Diff Tests (or diff tests for short) are executed by running the
77-
following command:
158+
Trace Processor Diff Tests (or diff tests for short) are executed by running the following command:
78159

79160
```sh
80161
tools/diff_test_trace_processor.py $OUT$/trace_processor_shell --keep-input --quiet --name-filter="<regex of test names>"
81162
```
82163

83-
**Note:** These tests can also be run with ASan or MSan builds by changing the
84-
path from `out/linux_clang_release/` to `out/linux_asan/` or `out/linux_msan/`
85-
respectively. **Note:** The `--name-filter` argument is optional. **Note:** When
86-
using the `--name-filter` flag, do not include `test_` in the filter. The test
87-
runner automatically drops this prefix. For example, to run `test_my_cool_test`,
88-
use the filter `MyTestSuite.my_cool_test`.
89-
164+
**Note:** These tests can also be run with ASan or MSan builds by changing the path from `out/linux_clang_release/` to `out/linux_asan/` or `out/linux_msan/` respectively.
90165

91-
### Test Guidelines
92-
93-
- **Prefer test suites over individual tests.** When using the `--gtest_filter`
94-
flag, specify a whole test suite (e.g., `"MyTestSuite.*"`) instead of a single
95-
test case (e.g., `"MyTestSuite.MySpecificTest"`). This ensures broader test
96-
coverage.
97-
- **Do not test unstable IDs.** When writing diff tests, do not include columns
98-
that contain unstable IDs (e.g. `upid`, `utid`, `id`, etc) in the output. These
99-
IDs can change between different runs of the same test, which will cause the
100-
test to fail.
101-
- **Remove `test_` prefix for diff tests.** When using the `--name-filter` flag
102-
for diff tests, do not include `test_` in the filter. The test
103-
runner automatically drops this prefix. For example, to run `test_my_cool_test`,
104-
use the filter `MyTestSuite.my_cool_test`.
105-
106-
## 3. Core Software Engineering Principles
166+
**Note:** The `--name-filter` argument is optional.
107167

108-
Follow these principles when writing and modifying code.
168+
**Note:** When using the `--name-filter` flag, do not include `test_` in the filter. The test
169+
runner automatically drops this prefix.
170+
For example, to run `test_my_cool_test`, use the filter `MyTestSuite.my_cool_test`.
109171

110-
### Principle 1: Don't Repeat Yourself (DRY)
172+
### Test Guidelines
111173

112-
- **Avoid code duplication.** Before writing a new function, search the codebase
113-
for existing functions that provide similar functionality.
114-
- **Reuse and refactor.** If a suitable function exists, reuse it. If it's close
115-
but not an exact match, consider refactoring the existing function to
116-
accommodate the new use case instead of creating a copy.
117-
- **Consult if unsure.** If you are considering duplicating a function or a
118-
significant block of code, consult with the user first.
174+
- **Prefer test suites over individual tests.** When using the `--gtest_filter` flag, specify a whole test suite (e.g., `"MyTestSuite.*"`) instead of a single test case (e.g., `"MyTestSuite.MySpecificTest"`). This ensures broader test coverage.
175+
- **Do not test unstable IDs.** When writing diff tests, do not include columns that contain unstable IDs (e.g. `upid`, `utid`, `id`, etc) in the output. These IDs can change between different runs of the same test, which will cause the test to fail.
176+
177+
- **Remove `test_` prefix for diff tests.** When using the `--name-filter` flag for diff tests, do not include `test_` in the filter. The test runner automatically drops this prefix. For example, to run `test_my_cool_test`, use the filter `MyTestSuite.my_cool_test`.
119178

120-
## 4. Getting Diffs
179+
## Getting Diffs
121180

122181
When asked to "get a diff" or "read the current diff", run the following
123182
command:
@@ -126,7 +185,7 @@ command:
126185
git diff $(git config branch.$(git rev-parse --abbrev-ref HEAD).parent)
127186
```
128187

129-
## 5. Fixing GN Dependencies
188+
## Fixing GN Dependencies
130189

131190
When asked to fix GN dependencies, run the following command and fix any errors
132191
that are reported:
@@ -139,7 +198,7 @@ tools/gn check $OUT
139198
unless explicitly instructed to by the user. Instead, add a direct dependency to
140199
the target that requires it.
141200

142-
## 6. Other Configurations
201+
## Other Configurations
143202

144203
### ASan (AddressSanitizer) Build
145204

@@ -174,25 +233,21 @@ out/linux_asan/perfetto_unittests --gtest_brief=1 --gtest_filter="<TestSuiteName
174233
MSAN_SYMBOLIZER_PATH="$(pwd)/buildtools/linux64/clang/bin/llvm-symbolizer" \
175234
out/linux_msan/perfetto_unittests --gtest_brief=1 --gtest_filter="<TestSuiteName.*>"
176235

177-
## 7. Creating Pull Requests
236+
## Creating Pull Requests
178237

179238
When creating a pull request, follow these steps:
180239

181240
1. **Create a new branch:**
182-
Use the command `git new-branch dev/lalitm/<name-of-branch>` to create a new branch for your pull request.
241+
Use the command `git new-branch dev/$USER$/<name-of-branch>` to create a new branch for your pull request.
183242

184243
2. **Create a stacked/dependent pull request:**
185244
To create a pull request that depends on another, use the command `git new-branch --parent <name-of-parent-branch> dev/lalitm/<name-of-branch>`.
186245

187-
**Note:** The `git new-branch` command only creates and switches to a new
188-
branch. The normal `git add` and `git commit` workflow should be used to add
189-
changes to the branch.
246+
**Note:** The `git new-branch` command only creates and switches to a new branch. The normal `git add` and `git commit` workflow should be used to add changes to the branch.
190247

191-
## 8. Commit Messages
248+
## Commit Messages
192249

193250
When writing commit messages, follow these guidelines:
194251

195-
- **Prefix your commits.** Prefix changes to Trace Processor code with `tp:`,
196-
UI code with `ui:`, and general Perfetto changes with `perfetto:`.
197-
- **Keep it concise.** A short one-line summary followed by a paragraph
198-
describing the change is the best commit message.
252+
- Prefix your commits: Prefix changes to Trace Processor code with `tp:`, UI code with `ui:`, and general Perfetto changes with `perfetto:`.
253+
- Keep it concise: A short one-line summary followed by a \n then a paragraph describing the change is the best commit message. Wrap the commit message at 72 cols.

include/perfetto/trace_processor/trace_processor.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,33 @@ class PERFETTO_EXPORT_COMPONENT TraceProcessor : public TraceProcessorStorage {
4646

4747
~TraceProcessor() override;
4848

49+
// =================================================================
50+
// | Trace loading related functionality starts here |
51+
// =================================================================
52+
53+
// The entry point to push trace data into the processor. The trace format
54+
// will be automatically discovered on the first push call. It is possible
55+
// to make queries between two pushes.
56+
// Returns the Ok status if parsing has been succeeding so far, and Error
57+
// status if some unrecoverable error happened. If this happens, the
58+
// TraceProcessor will ignore the following Parse() requests, drop data on the
59+
// floor and return errors forever.
60+
base::Status Parse(TraceBlobView) override = 0;
61+
62+
// Shorthand for Parse(TraceBlobView(TraceBlob(TakeOwnership(buf, size))).
63+
// For compatibility with older API clients.
64+
base::Status Parse(std::unique_ptr<uint8_t[]> buf, size_t size);
65+
66+
// Forces all data in the trace to be pushed to tables without buffering data
67+
// in sorting queues. This is useful if queries need to be performed to
68+
// compute post-processing data (e.g. deobfuscation, symbolization etc) which
69+
// will be appended to the trace in a future call to Parse.
70+
void Flush() override = 0;
71+
72+
// Calls Flush and finishes all of the actions required for parsing the trace.
73+
// Calling this function multiple times is undefined behaviour.
74+
base::Status NotifyEndOfFile() override = 0;
75+
4976
// =================================================================
5077
// | PerfettoSQL related functionality starts here |
5178
// =================================================================

include/perfetto/trace_processor/trace_processor_storage.h

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@
1717
#ifndef INCLUDE_PERFETTO_TRACE_PROCESSOR_TRACE_PROCESSOR_STORAGE_H_
1818
#define INCLUDE_PERFETTO_TRACE_PROCESSOR_TRACE_PROCESSOR_STORAGE_H_
1919

20+
#include <cstddef>
2021
#include <cstdint>
21-
2222
#include <memory>
2323

2424
#include "perfetto/base/export.h"
2525
#include "perfetto/base/status.h"
2626
#include "perfetto/trace_processor/basic_types.h"
27-
#include "perfetto/trace_processor/status.h"
2827
#include "perfetto/trace_processor/trace_blob_view.h"
2928

3029
namespace perfetto::trace_processor {
@@ -37,27 +36,16 @@ class PERFETTO_EXPORT_COMPONENT TraceProcessorStorage {
3736

3837
virtual ~TraceProcessorStorage();
3938

40-
// The entry point to push trace data into the processor. The trace format
41-
// will be automatically discovered on the first push call. It is possible
42-
// to make queries between two pushes.
43-
// Returns the Ok status if parsing has been succeeding so far, and Error
44-
// status if some unrecoverable error happened. If this happens, the
45-
// TraceProcessor will ignore the following Parse() requests, drop data on the
46-
// floor and return errors forever.
39+
// See comment on TraceProcessor::Parse.
4740
virtual base::Status Parse(TraceBlobView) = 0;
4841

49-
// Shorthand for Parse(TraceBlobView(TraceBlob(TakeOwnership(buf, size))).
50-
// For compatibility with older API clients.
42+
// See comment on TraceProcessor::Parse.
5143
base::Status Parse(std::unique_ptr<uint8_t[]> buf, size_t size);
5244

53-
// Forces all data in the trace to be pushed to tables without buffering data
54-
// in sorting queues. This is useful if queries need to be performed to
55-
// compute post-processing data (e.g. deobfuscation, symbolization etc) which
56-
// will be appended to the trace in a future call to Parse.
45+
// See comment on TraceProcessor::Flush.
5746
virtual void Flush() = 0;
5847

59-
// Calls Flush and finishes all of the actions required for parsing the trace.
60-
// Calling this function multiple times is undefined behaviour.
48+
// See comment on TraceProcessor::NotifyEndOfFile.
6149
virtual base::Status NotifyEndOfFile() = 0;
6250
};
6351

src/trace_processor/read_trace_internal.cc

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,27 @@
1616

1717
#include "src/trace_processor/read_trace_internal.h"
1818

19+
#include <fcntl.h>
20+
#include <algorithm>
21+
#include <cerrno>
22+
#include <cstddef>
23+
#include <cstdint>
24+
#include <cstdlib>
25+
#include <cstring>
26+
#include <functional>
27+
#include <utility>
28+
1929
#include "perfetto/base/logging.h"
30+
#include "perfetto/base/status.h"
2031
#include "perfetto/ext/base/file_utils.h"
2132
#include "perfetto/ext/base/scoped_file.h"
2233
#include "perfetto/ext/base/scoped_mmap.h"
23-
#include "perfetto/ext/base/utils.h"
24-
#include "perfetto/protozero/proto_utils.h"
25-
#include "perfetto/trace_processor/trace_processor.h"
26-
2734
#include "perfetto/ext/base/status_macros.h"
2835
#include "perfetto/trace_processor/trace_blob.h"
2936
#include "perfetto/trace_processor/trace_blob_view.h"
30-
#include "src/trace_processor/forwarding_trace_parser.h"
31-
#include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
32-
#include "src/trace_processor/util/gzip_utils.h"
33-
34-
#include "protos/perfetto/trace/trace.pbzero.h"
35-
#include "protos/perfetto/trace/trace_packet.pbzero.h"
37+
#include "perfetto/trace_processor/trace_processor.h"
3638

37-
namespace perfetto {
38-
namespace trace_processor {
39+
namespace perfetto::trace_processor {
3940
namespace {
4041

4142
// 1MB chunk size seems the best tradeoff on a MacBook Pro 2013 - i7 2.8 GHz.
@@ -112,5 +113,4 @@ base::Status ReadTraceUnfinalized(
112113
progress_callback(bytes_read);
113114
return base::OkStatus();
114115
}
115-
} // namespace trace_processor
116-
} // namespace perfetto
116+
} // namespace perfetto::trace_processor

0 commit comments

Comments
 (0)