Add Perfetto profiling support to CI workflow#341
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds Perfetto profiling infrastructure to the CI workflow, enabling performance profiling of the C++ codebase. It integrates the Perfetto SDK into the build system, adds Perfetto as a build matrix option alongside existing sanitizers, and schedules weekly automated profiling runs.
Changes:
- Adds Perfetto SDK (perfetto.h and perfetto.cc) installation to the CI Docker image
- Creates FindPerfetto.cmake module for CMake integration with ENABLE_PERFETTO option
- Extends build matrix with gcc/perfetto and clang/perfetto combinations and adds weekly scheduled trigger
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| ci/Dockerfile | Installs Perfetto SDK files to /opt/perfetto for use during CI builds |
| Modules/FindPerfetto.cmake | CMake Find module that locates Perfetto SDK and creates imported target |
| CMakeLists.txt | Adds ENABLE_PERFETTO option and links Perfetto to phlex executable when enabled |
| .gitignore | Adds /out/ directory to ignore list (presumably for Perfetto trace output) |
| .github/workflows/cmake-build.yaml | Adds schedule trigger, Perfetto test step, and configuration for Perfetto builds |
| .github/actions/generate-build-matrix/generate_matrix.py | Adds Perfetto to available combinations and sets it as default for scheduled runs |
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #341 +/- ##
=======================================
Coverage 82.26% 82.26%
=======================================
Files 127 127
Lines 3102 3102
Branches 547 547
=======================================
Hits 2552 2552
Misses 333 333
Partials 217 217
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
|
@phlexbot format |
|
No automatic markdownlint fixes were necessary. |
|
No automatic cmake-format fixes were necessary. |
|
No automatic jsonnetfmt fixes were necessary. |
|
No automatic clang-format fixes were necessary. |
|
@phlexbot python-fix |
|
Automatic ruff fixes pushed (commit 5566be8). |
|
@phlexbot cmake-fix |
|
Automatic cmake-format fixes pushed (commit 234e0c0). |
234e0c0 to
bd89c43
Compare
|
@phlexbot cmake-fix |
|
No automatic cmake-format fixes were necessary. |
|
|
||
| container: | ||
| image: ghcr.io/framework-r-d/phlex-ci:latest | ||
| options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined |
There was a problem hiding this comment.
The container options --cap-add=SYS_PTRACE --security-opt seccomp=unconfined are being applied to all build matrix combinations, not just Perfetto builds. While SYS_PTRACE is needed for Perfetto and Valgrind, and possibly for sanitizers, applying seccomp=unconfined to all builds reduces container security unnecessarily.
Consider either:
- Making these options conditional on the sanitizer type (e.g., only for perfetto, valgrind, asan, tsan)
- Documenting why these options are needed for all builds
- At minimum, removing
seccomp=unconfinedand only keeping--cap-add=SYS_PTRACEif it's truly needed for all sanitizer combinations
| options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined | |
| options: --cap-add=SYS_PTRACE |
| perfetto-heap-profile: | ||
| description: "Enable heap profiling for Perfetto runs" | ||
| required: false | ||
| type: boolean | ||
| default: false | ||
| perfetto-cpu-profile: | ||
| description: "Enable CPU profiling for Perfetto runs" | ||
| required: false | ||
| type: boolean | ||
| default: true |
There was a problem hiding this comment.
The workflow_dispatch inputs perfetto-heap-profile and perfetto-cpu-profile (lines 29-38) are not available when this workflow is triggered via workflow_call. This means external workflows that call this workflow cannot control Perfetto profiling options.
Consider adding corresponding inputs to the workflow_call section (starting at line 39) so that calling workflows can pass through these profiling configuration options.
| PERFETTO_HEAP_PROFILE: ${{ github.event.inputs.perfetto-heap-profile || 'false' }} | ||
| PERFETTO_CPU_PROFILE: ${{ github.event.inputs.perfetto-cpu-profile || 'true' }} |
There was a problem hiding this comment.
The Perfetto profiling step defaults PERFETTO_CPU_PROFILE to 'true' when inputs are not available (line 286). This creates different defaults for scheduled runs versus manual workflow_dispatch runs - scheduled runs will default to the string 'true', but workflow_dispatch defaults to the boolean true (line 38).
In Bash string comparisons, both will work, but for consistency, consider using consistent types. Either make both boolean true or both the string 'true'. Additionally, for scheduled event triggers, github.event.inputs will be null, so this will always use the fallback defaults. Document this behavior or ensure consistent handling across all event types.
| PERFETTO_HEAP_PROFILE: ${{ github.event.inputs.perfetto-heap-profile || 'false' }} | |
| PERFETTO_CPU_PROFILE: ${{ github.event.inputs.perfetto-cpu-profile || 'true' }} | |
| # For scheduled events, github.event.inputs is null, so these fallbacks | |
| # define the effective defaults (aligned with the workflow_dispatch inputs). | |
| PERFETTO_HEAP_PROFILE: ${{ github.event.inputs.perfetto-heap-profile || 'false' }} | |
| PERFETTO_CPU_PROFILE: ${{ github.event.inputs.perfetto-cpu-profile || true }} |
| # Run tests with or without tracebox wrapper | ||
| if [ -n "$TRACEBOX_ARGS" ]; then | ||
| echo "::group::Running ctest with tracebox" | ||
| tracebox $TRACEBOX_ARGS -o "$GITHUB_WORKSPACE/${{ env.local_build_path }}/perfetto-trace.pftrace" -- ctest --progress --output-on-failure -j "$(nproc)" || TEST_RESULT=$? | ||
| else | ||
| echo "::group::Running ctest with Perfetto SDK tracing" | ||
| ctest --progress --output-on-failure -j "$(nproc)" || TEST_RESULT=$? | ||
| fi | ||
|
|
||
| echo "::endgroup::" | ||
| if [ "${TEST_RESULT:-0}" -eq 0 ]; then |
There was a problem hiding this comment.
The test result variable TEST_RESULT is used on line 320 but only conditionally set on lines 313 and 316. If neither branch sets it (which shouldn't happen with the current logic, but the code structure suggests defensive programming), the expression ${TEST_RESULT:-0} will correctly default to 0. However, for clarity and to follow shell best practices, consider initializing TEST_RESULT=0 before the conditional block to make the intent explicit.
| add_library(perfetto_impl STATIC "${Perfetto_SOURCE}") | ||
| target_include_directories(perfetto_impl PUBLIC "${Perfetto_INCLUDE_DIR}") | ||
| target_compile_definitions(perfetto_impl PUBLIC PERFETTO_ENABLE_TRACING=1) | ||
| target_link_libraries(perfetto_impl PUBLIC Threads::Threads) | ||
| add_library(Perfetto::Perfetto ALIAS perfetto_impl) |
There was a problem hiding this comment.
The FindPerfetto.cmake module creates a static library target perfetto_impl (line 24) but doesn't set any visibility properties. Consider marking this as an internal/private target or giving it a more unique name to avoid potential conflicts with user code. Using a namespaced name like Perfetto_impl or setting visibility properties would follow CMake best practices for Find modules.
| add_library(perfetto_impl STATIC "${Perfetto_SOURCE}") | |
| target_include_directories(perfetto_impl PUBLIC "${Perfetto_INCLUDE_DIR}") | |
| target_compile_definitions(perfetto_impl PUBLIC PERFETTO_ENABLE_TRACING=1) | |
| target_link_libraries(perfetto_impl PUBLIC Threads::Threads) | |
| add_library(Perfetto::Perfetto ALIAS perfetto_impl) | |
| add_library(Perfetto_impl STATIC "${Perfetto_SOURCE}") | |
| target_include_directories(Perfetto_impl PUBLIC "${Perfetto_INCLUDE_DIR}") | |
| target_compile_definitions(Perfetto_impl PUBLIC PERFETTO_ENABLE_TRACING=1) | |
| target_link_libraries(Perfetto_impl PUBLIC Threads::Threads) | |
| add_library(Perfetto::Perfetto ALIAS Perfetto_impl) |
| # Install tracebox for system-wide profiling | ||
| wget -O tracebox https://get.perfetto.dev/tracebox | ||
| chmod +x tracebox |
There was a problem hiding this comment.
This step downloads and installs the tracebox binary from https://get.perfetto.dev/tracebox without any integrity verification or pinning to an immutable version. If the remote host, DNS, or TLS is compromised, an attacker could serve a malicious binary that runs in your CI environment with access to source code and potentially secrets. To reduce supply-chain risk, pin to a specific, versioned artifact and verify its integrity (e.g., via checksum or signature) before installing and executing it.
3d3dca5 to
6744794
Compare
This commit adds Perfetto profiling as a matrix item in the cmake-build GitHub workflow, enabling performance profiling of the C++ codebase. Changes: - Add FindPerfetto.cmake module that searches standard locations (/opt/perfetto, /usr/local/include, /usr/include) and creates a Perfetto::Perfetto imported target following CMake best practices - Add ENABLE_PERFETTO CMake option and integrate Perfetto SDK linking to the phlex executable when profiling is enabled - Install Perfetto SDK (perfetto.h and perfetto.cc) in CI Docker image at /opt/perfetto for use during CI builds - Add gcc/perfetto and clang/perfetto to available build matrix combinations in generate_matrix.py - Add dedicated workflow step for Perfetto profiling runs that executes tests with profiling enabled, following the pattern established by the Valgrind step - Add weekly scheduled trigger (Saturdays at 18:00 UTC) that runs gcc/perfetto by default for regular performance profiling The implementation follows existing workflow conventions for modularity, naming, and reusable actions. Users can trigger Perfetto builds via workflow_dispatch, issue comments (@phlexbot build gcc/perfetto), or wait for the weekly scheduled run.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Add artifact upload step to the Perfetto profiling workflow to capture trace files generated during test execution, enabling offline analysis via the Perfetto UI. Changes: - Add upload-artifact step after Perfetto profiling runs that collects all .pftrace files from the build directory - Name artifacts by compiler (perfetto-traces-gcc, perfetto-traces-clang) to distinguish between different compiler runs - Set 30-day retention period for trace files to allow sufficient time for analysis while managing storage costs - Configure if-no-files-found: warn to alert if profiling did not generate expected trace output Users can download the trace artifacts from the workflow run and analyze them at https://ui.perfetto.dev/ for detailed performance profiling and visualization of the test execution.
Enable heap profiling, CPU profiling, and system-wide tracing via Perfetto's tracebox tool for comprehensive performance analysis. Changes: - Install tracebox binary in CI Docker image from get.perfetto.dev for system-wide profiling capabilities - Add workflow_dispatch inputs for perfetto-heap-profile and perfetto-cpu-profile to control profiling modes (CPU profiling enabled by default, heap profiling opt-in) - Add SYS_PTRACE capability and disable seccomp in container options to enable perf_event access required for CPU profiling - Configure perf_event_paranoid=-1 at runtime when CPU profiling is enabled to allow non-root access to performance counters - Update Perfetto profiling step to conditionally wrap ctest execution with tracebox when heap or CPU profiling is enabled, passing appropriate flags (--heapprofd for heap, --cpu-freq/--cpu-idle/ --cpu-sched for CPU) - Fall back to SDK-only tracing when no system profiling is requested Users can now enable heap profiling and CPU counter profiling via workflow_dispatch inputs to capture detailed memory allocation patterns and CPU performance metrics alongside application traces.
- Restrict artifact upload path to build directory only to avoid collecting unintended files from source tree - Use absolute path for tracebox output file to ensure trace is written to expected location within build directory - Move Perfetto linking to phlex/app/CMakeLists.txt immediately after cet_make_exec() to localize it to the executable creation - Use specific Perfetto SDK version (v51.0) instead of main branch for reproducible container builds
6744794 to
66f4542
Compare
|
|
||
| option(ENABLE_TSAN "Enable Thread Sanitizer" OFF) | ||
| option(ENABLE_ASAN "Enable Address Sanitizer" OFF) | ||
| option(ENABLE_PERFETTO "Enable Perfetto profiling" OFF) |
There was a problem hiding this comment.
Can this option be enabled only for Linux?
This commit adds Perfetto profiling as a matrix item in the cmake-build
GitHub workflow, enabling performance profiling of the C++ codebase.
Changes:
Add FindPerfetto.cmake module that searches standard locations
(/opt/perfetto, /usr/local/include, /usr/include) and creates a
Perfetto::Perfetto imported target following CMake best practices
Add ENABLE_PERFETTO CMake option and integrate Perfetto SDK linking
to the phlex executable when profiling is enabled
Install Perfetto SDK (perfetto.h and perfetto.cc) in CI Docker image
at /opt/perfetto for use during CI builds
Add gcc/perfetto and clang/perfetto to available build matrix
combinations in generate_matrix.py
Add dedicated workflow step for Perfetto profiling runs that executes
tests with profiling enabled, following the pattern established by
the Valgrind step
Add weekly scheduled trigger (Saturdays at 18:00 UTC) that runs
gcc/perfetto by default for regular performance profiling
The implementation follows existing workflow conventions for modularity,
naming, and reusable actions. Users can trigger Perfetto builds via
workflow_dispatch, issue comments (@phlexbot build gcc/perfetto), or
wait for the weekly scheduled run.
Note: this PR adds the infrastructure only: it does not add any instrumentation to the code.