Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions .github/actions/generate-build-matrix/generate_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@

def get_default_combinations(event_name, all_combinations):
"""Gets the default build combinations based on the GitHub event type."""
if event_name in ("push", "pull_request", "pull_request_target"):
if event_name in (
"push",
"pull_request",
"pull_request_target",
"issue_comment",
"workflow_dispatch",
):
return ["gcc/none"]
elif event_name == "issue_comment":
return ["gcc/none", "clang/none"]
elif event_name == "workflow_dispatch":
return all_combinations
elif event_name == "schedule":
return ["gcc/perfetto"]
else:
# Default to a minimal safe configuration for unknown events
return ["gcc/none"]
Expand All @@ -25,10 +29,12 @@ def main():
"gcc/asan",
"gcc/tsan",
"gcc/valgrind",
"gcc/perfetto",
"clang/none",
"clang/asan",
"clang/tsan",
"clang/valgrind",
"clang/perfetto",
]
user_input = os.getenv("USER_INPUT", "")
comment_body = os.getenv("COMMENT_BODY", "")
Expand Down
75 changes: 73 additions & 2 deletions .github/workflows/cmake-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
types: [created]
push:
branches: [ main, develop ]
schedule:
- cron: '0 18 * * 6'
workflow_dispatch:
inputs:
ref:
Expand All @@ -21,9 +23,19 @@ on:
- `all` (run all combinations)
- `all -clang/none -clang/valgrind` (run all except specified)
- `+clang/none +clang/valgrind` (run default matrix plus specified)
Default (if empty): Run all except clang/none and clang/valgrind.
Default (if empty): Run `gcc/none`
required: false
default: ''
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
Comment on lines +29 to +38
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
workflow_call:
inputs:
checkout-path:
Expand Down Expand Up @@ -76,6 +88,7 @@ jobs:
github.event_name == 'workflow_dispatch' ||
github.event_name == 'pull_request' ||
github.event_name == 'push' ||
github.event_name == 'schedule' ||
github.event_name == 'workflow_call' ||
(
github.event_name == 'issue_comment' &&
Expand Down Expand Up @@ -190,6 +203,7 @@ jobs:

container:
image: ghcr.io/framework-r-d/phlex-ci:latest
options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. Making these options conditional on the sanitizer type (e.g., only for perfetto, valgrind, asan, tsan)
  2. Documenting why these options are needed for all builds
  3. At minimum, removing seccomp=unconfined and only keeping --cap-add=SYS_PTRACE if it's truly needed for all sanitizer combinations
Suggested change
options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined
options: --cap-add=SYS_PTRACE

Copilot uses AI. Check for mistakes.

steps:
- name: Check out code
Expand Down Expand Up @@ -224,6 +238,7 @@ jobs:
extra-options: |
${{ matrix.sanitizer == 'asan' && format('-D{0}_ENABLE_ASAN=ON', steps.repo_name.outputs.name) || '' }}
${{ matrix.sanitizer == 'tsan' && format('-D{0}_ENABLE_TSAN=ON', steps.repo_name.outputs.name) || '' }}
${{ matrix.sanitizer == 'perfetto' && format('-D{0}_ENABLE_PERFETTO=ON', steps.repo_name.outputs.name) || '' }}

- name: Build
id: build
Expand All @@ -232,7 +247,7 @@ jobs:
build-path: ${{ env.local_build_path }}

- name: Run tests
if: matrix.sanitizer != 'valgrind'
if: matrix.sanitizer != 'valgrind' && matrix.sanitizer != 'perfetto'
run: |
. /entrypoint.sh
cd "$GITHUB_WORKSPACE/${{ env.local_build_path }}"
Expand Down Expand Up @@ -264,6 +279,62 @@ jobs:
echo "⚠️ Valgrind tests failed, but the workflow will continue."
fi

- name: Run Perfetto profiling
if: matrix.sanitizer == 'perfetto'
env:
PERFETTO_HEAP_PROFILE: ${{ github.event.inputs.perfetto-heap-profile || 'false' }}
PERFETTO_CPU_PROFILE: ${{ github.event.inputs.perfetto-cpu-profile || 'true' }}
Comment on lines +285 to +286
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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 }}

Copilot uses AI. Check for mistakes.
run: |
. /entrypoint.sh
cd "$GITHUB_WORKSPACE/${{ env.local_build_path }}"

echo "➡️ Running tests with Perfetto profiling..."

# Set perf_event_paranoid for CPU profiling
if [ "$PERFETTO_CPU_PROFILE" = "true" ]; then
echo "Configuring perf_event_paranoid for CPU profiling"
echo -1 | tee /proc/sys/kernel/perf_event_paranoid 2>/dev/null || echo "Warning: Could not set perf_event_paranoid"
fi

# Configure profiling based on environment
TRACEBOX_ARGS=""
if [ "$PERFETTO_HEAP_PROFILE" = "true" ]; then
echo "Enabling heap profiling"
TRACEBOX_ARGS="$TRACEBOX_ARGS --app '*' --heapprofd"
fi
if [ "$PERFETTO_CPU_PROFILE" = "true" ]; then
echo "Enabling CPU profiling"
TRACEBOX_ARGS="$TRACEBOX_ARGS --cpu-freq --cpu-idle --cpu-sched"
fi

# 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
Comment on lines +310 to +320
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
echo "✅ Perfetto profiling completed."
else
echo "::error:: Perfetto profiling failed."
exit 1
fi

- name: Upload Perfetto traces
if: matrix.sanitizer == 'perfetto'
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: perfetto-traces-${{ matrix.compiler }}
path: |
${{ env.local_build_path }}/**/*.pftrace
${{ env.local_build_path }}/**/perfetto-trace.pftrace
retention-days: 30
if-no-files-found: warn

cmake-build-skipped:
needs: [pre-check, detect-changes]
if: >
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/_deps/
/build-*/
/build/
/out/
/phlex-build/
/phlex-src/
CMakeFiles/
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ include(Modules/private/CreateCoverageTargets.cmake)

option(ENABLE_TSAN "Enable Thread Sanitizer" OFF)
option(ENABLE_ASAN "Enable Address Sanitizer" OFF)
option(ENABLE_PERFETTO "Enable Perfetto profiling" OFF)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this option be enabled only for Linux?

option(PHLEX_USE_FORM "Enable experimental integration with FORM" OFF)
option(ENABLE_COVERAGE "Enable code coverage instrumentation" OFF)
option(ENABLE_CLANG_TIDY "Enable clang-tidy checks during build" OFF)
Expand Down Expand Up @@ -145,6 +146,12 @@ if(ENABLE_ASAN)
endif()
endif()

# Configure Perfetto profiling if enabled
if(ENABLE_PERFETTO)
message(STATUS "Enabling Perfetto profiling")
find_package(Perfetto REQUIRED)
endif()

# Configure code coverage if enabled
if(ENABLE_COVERAGE)
# Check if the compiler supports code coverage
Expand Down
31 changes: 31 additions & 0 deletions Modules/FindPerfetto.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# FindPerfetto.cmake
# Finds the Perfetto SDK (single-header implementation)

include(FindPackageHandleStandardArgs)

find_path(
Perfetto_INCLUDE_DIR
NAMES perfetto.h
PATHS /opt/perfetto /usr/local/include /usr/include
DOC "Perfetto SDK header location"
)

find_file(
Perfetto_SOURCE
NAMES perfetto.cc
PATHS /opt/perfetto /usr/local/include /usr/include
DOC "Perfetto SDK implementation file"
)

find_package_handle_standard_args(Perfetto REQUIRED_VARS Perfetto_INCLUDE_DIR Perfetto_SOURCE)

if(Perfetto_FOUND AND NOT TARGET Perfetto::Perfetto)
find_package(Threads REQUIRED)
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)
Comment on lines +24 to +28
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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)

Copilot uses AI. Check for mistakes.
endif()

mark_as_advanced(Perfetto_INCLUDE_DIR Perfetto_SOURCE)
26 changes: 26 additions & 0 deletions ci/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,32 @@ set -euo pipefail
rm -f /tmp/spack.yaml
CLEAN_TEMP_FILES

########################################################################
# Install Perfetto SDK for profiling

RUN <<'INSTALL_PERFETTO'
set -euo pipefail

# Install Perfetto SDK and tools
apt-get update
apt-get install -y --no-install-recommends \
wget
apt-get clean
rm -rf /var/lib/apt/lists/*

mkdir -p /opt/perfetto
cd /opt/perfetto
PERFETTO_VERSION=v51.0
wget -O perfetto.h https://raw.githubusercontent.com/google/perfetto/${PERFETTO_VERSION}/sdk/perfetto.h
wget -O perfetto.cc https://raw.githubusercontent.com/google/perfetto/${PERFETTO_VERSION}/sdk/perfetto.cc
chmod 644 perfetto.h perfetto.cc

# Install tracebox for system-wide profiling
wget -O tracebox https://get.perfetto.dev/tracebox
chmod +x tracebox
Comment on lines +303 to +305
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
mv tracebox /usr/local/bin/
INSTALL_PERFETTO

########################################################################
# Finalize CI image stage

Expand Down
4 changes: 4 additions & 0 deletions phlex/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ cet_make_exec(
jsonnet::lib
)

if(ENABLE_PERFETTO)
target_link_libraries(phlex PRIVATE Perfetto::Perfetto)
endif()

set_target_properties(phlex PROPERTIES INSTALL_RPATH "$ORIGIN/../lib")
Loading