From 6759bdc408d0bd807b8ad5e09271cfec89864a92 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 10:22:16 +0200 Subject: [PATCH 01/17] ci: restore EL7 stresstest coverage, add nightly EL7 functional tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #790 moved build:x64 onto AlmaLinux 8, which took stresstest:x64 with it since it ran in the same image — runtime coverage at the shipped binary's glibc 2.17 floor went to zero. This follows up on the two items proposed there: - .stresstest_job now takes RUNTIME_IMAGE independently of BUILD_IMAGE, and stresstest:x64 points it at a new Oracle Linux 7 image so it goes back to running against glibc 2.17 while build:x64 stays on EL8. - adds a nightly functional:x64-el7-jdk{8,17,21} job matrix that runs the ddprof-test debug suite against the shipped x64 artifact on the same EL7 image, covering the libc-sensitive suites without multiplying the per-PR matrix. The new .gitlab/base/el7/Dockerfile is runtime-only (no compiler): both jobs consume the AlmaLinux-8-built .so via -Pskip-native -Pwith-libs. functional-tests.sh fetches the JDK under test from Adoptium into JAVA_TEST_HOME so Gradle itself keeps running on JDK 21 regardless of which JDK is under test. BUILD_IMAGE_X64_EL7 is a placeholder pin — the image still needs to be built and pushed via a real pipeline (REBUILD_IMAGES="x64-el7") before this can merge, same as #790's own image rebuild. Co-Authored-By: Claude Sonnet 5 --- .gitlab/base/el7/Dockerfile | 25 ++++++++++ .gitlab/build-deploy/.gitlab-ci.yml | 68 ++++++++++++++++++++++++-- .gitlab/build-deploy/images.yml | 6 +++ .gitlab/scripts/check-image-updates.sh | 1 + .gitlab/scripts/functional-tests.sh | 65 ++++++++++++++++++++++++ .gitlab/scripts/rebuild-images.sh | 6 ++- 6 files changed, 164 insertions(+), 7 deletions(-) create mode 100644 .gitlab/base/el7/Dockerfile create mode 100644 .gitlab/scripts/functional-tests.sh diff --git a/.gitlab/base/el7/Dockerfile b/.gitlab/base/el7/Dockerfile new file mode 100644 index 0000000000..c88040b8c0 --- /dev/null +++ b/.gitlab/base/el7/Dockerfile @@ -0,0 +1,25 @@ +# Runtime-only image for exercising the shipped x64 binary on its actual +# glibc floor (2.17). Oracle Linux 7 is the best-maintained EL7 derivative — +# live CDN, current package levels, no ELS subscription needed — see PR #790. +# +# This image never compiles anything: the shipped libjavaProfiler.so is built +# in the AlmaLinux 8 image (.gitlab/base/el8/Dockerfile) and consumed here +# via -Pskip-native -Pwith-libs, so no compiler toolchain is installed. +# +# Gradle 9 requires JDK 17+ to run, so JAVA_HOME is a single build JDK (21). +# Suites that test against other JDKs (8, 11, 17, ...) fetch that JDK at job +# runtime into JAVA_TEST_HOME (see .gitlab/scripts/functional-tests.sh) — +# the profiler-test Gradle plugin already runs the test JVM from +# JAVA_TEST_HOME when it is set, independently of the JDK running Gradle +# itself. +ARG BASE_IMAGE=oraclelinux:7 +FROM ${BASE_IMAGE} as base +WORKDIR /root + +RUN yum -y install git make zip unzip which wget curl jq \ + && yum -y clean all + +RUN curl -s "https://get.sdkman.io" | bash && \ + bash -c "source /root/.sdkman/bin/sdkman-init.sh && sdk install java 21.0.3-tem" +ENV JAVA_HOME=/root/.sdkman/candidates/java/current +ENV PATH="/root/.sdkman/candidates/java/current/bin:${PATH}" diff --git a/.gitlab/build-deploy/.gitlab-ci.yml b/.gitlab/build-deploy/.gitlab-ci.yml index fdb5dab756..f251033fdc 100644 --- a/.gitlab/build-deploy/.gitlab-ci.yml +++ b/.gitlab/build-deploy/.gitlab-ci.yml @@ -9,6 +9,10 @@ variables: BUILD_IMAGE_X64_GLIBC: registry.ddbuild.io/ci/async-profiler-build:v137281788-x64-glibc-base@sha256:270a9101716a0865071182e0ef0e40e98f874535b90722949b33a4a8998fe08d # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 BUILD_IMAGE_ARM64_GLIBC: registry.ddbuild.io/ci/async-profiler-build:v137281788-arm64-glibc-base@sha256:511d051d37ed99b2ca9cd3af797aa9de63e4b4b952af1e738b2cea913bbcc057 + # TODO: repin after running `REBUILD_IMAGES="x64-el7"` through rebuild-images.sh + # in a real pipeline (see .gitlab/base/el7/Dockerfile) — this digest is a + # placeholder and does not exist in the registry yet. + BUILD_IMAGE_X64_EL7: registry.ddbuild.io/ci/async-profiler-build:v0-x64-el7-base@sha256:0000000000000000000000000000000000000000000000000000000000000 # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 BUILD_IMAGE_X64_MUSL: registry.ddbuild.io/ci/async-profiler-build:v137281788-x64-musl-base@sha256:fd3803695771de3eabf44e4953c0474273f9dbb97d88c22e99ac507b88572481 # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 @@ -58,7 +62,12 @@ variables: artifacts: true when: on_success tags: [ "arch:amd64" ] - image: ${BUILD_IMAGE} + # RUNTIME_IMAGE decouples the runtime environment from the image the + # artifact was built in (BUILD_IMAGE): stresstest:x64 runs on Oracle Linux 7 + # to exercise the shipped binary's actual glibc floor, while consuming the + # same artifact build:x64 produced in the AlmaLinux 8 image. Other stresstest + # jobs set RUNTIME_IMAGE to their own BUILD_IMAGE, unchanged from before. + image: ${RUNTIME_IMAGE} script: - .gitlab/scripts/stresstests.sh artifacts: @@ -127,7 +136,9 @@ stresstest:x64: - job: build:x64 artifacts: true variables: - BUILD_IMAGE: ${BUILD_IMAGE_X64_GLIBC} + # Oracle Linux 7 (glibc 2.17) — the artifact's actual floor, restoring the + # runtime coverage build:x64 lost when it moved to AlmaLinux 8 (PR #790). + RUNTIME_IMAGE: ${BUILD_IMAGE_X64_EL7} TARGET: linux-x64 stresstest:x64-musl: @@ -138,7 +149,7 @@ stresstest:x64-musl: - job: build:x64-musl artifacts: true variables: - BUILD_IMAGE: ${BUILD_IMAGE_X64_MUSL} + RUNTIME_IMAGE: ${BUILD_IMAGE_X64_MUSL} TARGET: linux-x64-musl stresstest:arm64: @@ -151,7 +162,7 @@ stresstest:arm64: tags: [ "arch:arm64" ] variables: # same image as build:arm64, so the stress run exercises the shipped build - BUILD_IMAGE: ${BUILD_IMAGE_ARM64_GLIBC} + RUNTIME_IMAGE: ${BUILD_IMAGE_ARM64_GLIBC} TARGET: linux-arm64 stresstest:arm64-musl: @@ -164,9 +175,56 @@ stresstest:arm64-musl: timeout: 3h tags: [ "arch:arm64" ] variables: - BUILD_IMAGE: ${BUILD_IMAGE_ARM64_MUSL} + RUNTIME_IMAGE: ${BUILD_IMAGE_ARM64_MUSL} TARGET: linux-arm64-musl +# Runs the functional (ddprof-test) suite on Oracle Linux 7 against the +# shipped x64 artifact, so the libc-sensitive suites get real coverage at the +# glibc 2.17 floor (see PR #790's follow-up) without multiplying the regular +# per-PR test matrix. Schedule-only (nightly): a 2-3 JDK subset is enough to +# catch a libc regression, and Temurin 8/17/21 all start on glibc 2.17. +.functional_job: + extends: + - .retry-config + - .cache-config-pull + stage: stresstest + needs: + - job: prepare:start + artifacts: true + - job: build:x64 + artifacts: true + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule"' + when: always + - when: never + tags: [ "arch:amd64" ] + image: ${BUILD_IMAGE_X64_EL7} + variables: + TARGET: linux-x64 + script: + - .gitlab/scripts/functional-tests.sh + artifacts: + when: always + paths: + - functional/$TARGET/jdk$TEST_JDK/reports + - functional/$TARGET/jdk$TEST_JDK/logs + expire_in: 2 weeks + +functional:x64-el7-jdk8: + extends: .functional_job + variables: + TEST_JDK: "8" + +functional:x64-el7-jdk17: + extends: .functional_job + variables: + TEST_JDK: "17" + +functional:x64-el7-jdk21: + extends: .functional_job + variables: + TEST_JDK: "21" + # Builds the chaos reliability harness once per pipeline so the per-cell # reliability jobs can pull it as an artifact instead of compiling inline. # Schedule-only because reliability cells are schedule-only. diff --git a/.gitlab/build-deploy/images.yml b/.gitlab/build-deploy/images.yml index 3774fa71ec..ab0f79e805 100644 --- a/.gitlab/build-deploy/images.yml +++ b/.gitlab/build-deploy/images.yml @@ -20,5 +20,11 @@ variables: # and must be one that still gets security rebuilds. The resulting .so # requires GLIBC_2.27. Multi-arch manifest, pinned by digest. BASE_IMAGE_GLIBC: almalinux:8@sha256:9f355ae942d6a6c0561f0771dc053a2cfae9580fc45fa4252756db7c7e80c09f + # Oracle Linux 7 (glibc 2.17) — best-maintained EL7 derivative (live CDN, + # both arches, working collections). Runtime-only: runs the x64 stresstest + # and functional suites against the AlmaLinux-8-built shipped binary, so + # that coverage at the actual glibc floor doesn't go to zero (PR #790). + # Multi-arch manifest, pinned by digest. + BASE_IMAGE_EL7: oraclelinux:7@sha256:767c93c07b1fa621ae56d1f5f090e8c0dce7eb452e7dda1e74bbe7546504d63f DOCKER_IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/images/docker:24.0.4-gbi-focal diff --git a/.gitlab/scripts/check-image-updates.sh b/.gitlab/scripts/check-image-updates.sh index 7013977421..2c241fb3cf 100755 --- a/.gitlab/scripts/check-image-updates.sh +++ b/.gitlab/scripts/check-image-updates.sh @@ -40,6 +40,7 @@ IMAGE_DEFS=( "BUILD_IMAGE_X64|.gitlab/build-deploy/.gitlab-ci.yml|x64-base|image-base-build-x64|async-profiler-build" "BUILD_IMAGE_X64_GLIBC|.gitlab/build-deploy/.gitlab-ci.yml|x64-glibc-base|image-base-build-x64-glibc|async-profiler-build" "BUILD_IMAGE_ARM64_GLIBC|.gitlab/build-deploy/.gitlab-ci.yml|arm64-glibc-base|image-base-build-arm64-glibc|async-profiler-build" + "BUILD_IMAGE_X64_EL7|.gitlab/build-deploy/.gitlab-ci.yml|x64-el7-base|image-base-build-x64-el7|async-profiler-build" "BUILD_IMAGE_X64_MUSL|.gitlab/build-deploy/.gitlab-ci.yml|x64-musl-base|image-base-build-x64-musl|async-profiler-build" "BUILD_IMAGE_ARM64|.gitlab/build-deploy/.gitlab-ci.yml|arm64-base|image-base-build-arm64|async-profiler-build" "BUILD_IMAGE_ARM64_MUSL|.gitlab/build-deploy/.gitlab-ci.yml|arm64-musl-base|image-base-build-arm64-musl|async-profiler-build" diff --git a/.gitlab/scripts/functional-tests.sh b/.gitlab/scripts/functional-tests.sh new file mode 100644 index 0000000000..d5737b3e91 --- /dev/null +++ b/.gitlab/scripts/functional-tests.sh @@ -0,0 +1,65 @@ +#! /bin/bash + +set -eo pipefail # exit on any failure, including mid-pipeline +set -x + +if [ ! -z "${CANCELLED:-}" ]; then + exit 0 +fi + +if [ -z "$TARGET" ]; then + echo "Expecting the TARGET variable to be set" + exit 1 +fi + +if [ -z "$TEST_JDK" ]; then + echo "Expecting the TEST_JDK variable to be set (Adoptium major version, e.g. 8, 11, 17, 21)" + exit 1 +fi + +TEST_CONFIG="${TEST_CONFIG:-Debug}" + +HERE=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +REPO_ROOT=$( cd "${HERE}/../.." && pwd ) + +if [ -z "${JAVA_HOME}" ]; then + # workaround for CI when JAVA_HOME is not properly defined + export JAVA_HOME=~/.sdkman/candidates/java/current +fi + +echo "Using Java (build) @ ${JAVA_HOME}" + +# Fetch the JDK under test independently of the JDK running Gradle: the +# profiler-test Gradle plugin runs the test JVM from JAVA_TEST_HOME when it +# is set, so this is the only way to exercise multiple JDKs without needing +# a Gradle version that runs on each of them. +JDK_CACHE_DIR="${REPO_ROOT}/.jdk-cache/${TEST_JDK}" +if [ ! -x "${JDK_CACHE_DIR}/bin/java" ]; then + rm -rf "${JDK_CACHE_DIR}" + mkdir -p "${JDK_CACHE_DIR}" + curl -sL "https://api.adoptium.net/v3/binary/latest/${TEST_JDK}/ga/linux/x64/jdk/hotspot/normal/eclipse" \ + -o /tmp/test-jdk.tar.gz + tar -xzf /tmp/test-jdk.tar.gz -C "${JDK_CACHE_DIR}" --strip-components=1 + rm -f /tmp/test-jdk.tar.gz +fi +export JAVA_TEST_HOME="${JDK_CACHE_DIR}" +echo "Using Java (test) @ ${JAVA_TEST_HOME}" +"${JAVA_TEST_HOME}/bin/java" -version + +source .gitlab/scripts/includes.sh + +function onexit { + local out_dir="${REPO_ROOT}/functional/${TARGET}/jdk${TEST_JDK}" + mkdir -p "${out_dir}/reports" + mkdir -p "${out_dir}/logs" + mv "${REPO_ROOT}/ddprof-test/build/reports" "${out_dir}/" 2>/dev/null || true + mv /tmp/*.jfr "${out_dir}/logs" 2>/dev/null || true + mv /tmp/*.json "${out_dir}/logs" 2>/dev/null || true + mv /tmp/*.txt "${out_dir}/logs" 2>/dev/null || true + find . -name 'hs_err*' | xargs -I {} cp {} "${out_dir}/logs" 2>/dev/null || true +} + +trap onexit EXIT + +./gradlew -Pddprof_version="$(get_version)" -Pskip-native -Pwith-libs="$(pwd)/libs" -PCI \ + ":ddprof-test:test${TEST_CONFIG}" --max-workers=1 --build-cache --stacktrace --info --no-watch-fs --no-daemon diff --git a/.gitlab/scripts/rebuild-images.sh b/.gitlab/scripts/rebuild-images.sh index 5df3736cd4..919eac23dc 100755 --- a/.gitlab/scripts/rebuild-images.sh +++ b/.gitlab/scripts/rebuild-images.sh @@ -16,8 +16,8 @@ # Base image variables come from .gitlab/build-deploy/images.yml which is # included in the root pipeline and available as CI variables: # OPENJDK_BASE_IMAGE, OPENJDK_BASE_IMAGE_ARM64, OPENJDK_BASE_IMAGE_MUSL, -# OPENJDK_BASE_IMAGE_ARM64_MUSL, BASE_IMAGE_GLIBC, BASE_BENCHMARK_IMAGE_NAME, -# DOCKER_IMAGE +# OPENJDK_BASE_IMAGE_ARM64_MUSL, BASE_IMAGE_GLIBC, BASE_IMAGE_EL7, +# BASE_BENCHMARK_IMAGE_NAME, DOCKER_IMAGE set -euo pipefail @@ -43,6 +43,7 @@ usage() { echo " x64 glibc x86_64 build image" >&2 echo " x64-glibc shipped-binary x86_64 build image (AlmaLinux 8)" >&2 echo " arm64-glibc shipped-binary aarch64 build image (AlmaLinux 8)" >&2 + echo " x64-el7 runtime-only x86_64 stresstest/functional image (Oracle Linux 7)" >&2 echo " x64-musl musl x86_64 build image" >&2 echo " arm64 glibc arm64 build image" >&2 echo " arm64-musl musl arm64 build image" >&2 @@ -61,6 +62,7 @@ IMAGE_DEFS=( "x64|BUILD_IMAGE_X64|.gitlab/build-deploy/.gitlab-ci.yml|x64-base|.gitlab/base/Dockerfile|linux/amd64|async-profiler-build|OPENJDK_BASE_IMAGE" "x64-glibc|BUILD_IMAGE_X64_GLIBC|.gitlab/build-deploy/.gitlab-ci.yml|x64-glibc-base|.gitlab/base/el8/Dockerfile|linux/amd64|async-profiler-build|BASE_IMAGE_GLIBC" "arm64-glibc|BUILD_IMAGE_ARM64_GLIBC|.gitlab/build-deploy/.gitlab-ci.yml|arm64-glibc-base|.gitlab/base/el8/Dockerfile|linux/arm64|async-profiler-build|BASE_IMAGE_GLIBC" + "x64-el7|BUILD_IMAGE_X64_EL7|.gitlab/build-deploy/.gitlab-ci.yml|x64-el7-base|.gitlab/base/el7/Dockerfile|linux/amd64|async-profiler-build|BASE_IMAGE_EL7" "x64-musl|BUILD_IMAGE_X64_MUSL|.gitlab/build-deploy/.gitlab-ci.yml|x64-musl-base|.gitlab/base/Dockerfile.musl|linux/amd64|async-profiler-build|OPENJDK_BASE_IMAGE_MUSL" "arm64|BUILD_IMAGE_ARM64|.gitlab/build-deploy/.gitlab-ci.yml|arm64-base|.gitlab/base/Dockerfile|linux/arm64|async-profiler-build|OPENJDK_BASE_IMAGE_ARM64" "arm64-musl|BUILD_IMAGE_ARM64_MUSL|.gitlab/build-deploy/.gitlab-ci.yml|arm64-musl-base|.gitlab/base/Dockerfile.musl|linux/arm64|async-profiler-build|OPENJDK_BASE_IMAGE_ARM64_MUSL" From 11c391b4fc34f128a0bd2a9a7bbc20ea9dd63419 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 10:34:07 +0200 Subject: [PATCH 02/17] ci: run functional:x64-el7-jdk8 on every PR, not just nightly Keeps the 3-JDK sweep nightly but lets one JDK's worth of EL7 functional coverage run on every pipeline, so it isn't gated entirely on the nightly schedule. Co-Authored-By: Claude Sonnet 5 --- .gitlab/build-deploy/.gitlab-ci.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.gitlab/build-deploy/.gitlab-ci.yml b/.gitlab/build-deploy/.gitlab-ci.yml index f251033fdc..03cab1c5c2 100644 --- a/.gitlab/build-deploy/.gitlab-ci.yml +++ b/.gitlab/build-deploy/.gitlab-ci.yml @@ -180,9 +180,10 @@ stresstest:arm64-musl: # Runs the functional (ddprof-test) suite on Oracle Linux 7 against the # shipped x64 artifact, so the libc-sensitive suites get real coverage at the -# glibc 2.17 floor (see PR #790's follow-up) without multiplying the regular -# per-PR test matrix. Schedule-only (nightly): a 2-3 JDK subset is enough to -# catch a libc regression, and Temurin 8/17/21 all start on glibc 2.17. +# glibc 2.17 floor (see PR #790's follow-up). Schedule-only by default: a +# 2-3 JDK subset is enough to catch a libc regression, and Temurin 8/17/21 +# all start on glibc 2.17. jdk8 additionally runs on every PR (below), so +# EL7 functional coverage isn't gated on the nightly schedule entirely. .functional_job: extends: - .retry-config @@ -210,8 +211,13 @@ stresstest:arm64-musl: - functional/$TARGET/jdk$TEST_JDK/logs expire_in: 2 weeks +# Runs on every pipeline (not just nightly): JDK 8 is the oldest/most +# different from the JDK 21 that runs Gradle, giving the most distinct +# per-PR signal for a libc regression at low added cost. functional:x64-el7-jdk8: extends: .functional_job + rules: + - when: on_success variables: TEST_JDK: "8" From 8e2a2fb0c2579df1b8064d2be5a8e99a32e6c3d2 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 12:55:37 +0200 Subject: [PATCH 03/17] ci: pin BUILD_IMAGE_X64_EL7 to the rebuilt image digest Built and pushed successfully in pipeline 138399627, job 2056785023. Co-Authored-By: Claude Sonnet 5 --- .gitlab/build-deploy/.gitlab-ci.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitlab/build-deploy/.gitlab-ci.yml b/.gitlab/build-deploy/.gitlab-ci.yml index 03cab1c5c2..3dd9df9165 100644 --- a/.gitlab/build-deploy/.gitlab-ci.yml +++ b/.gitlab/build-deploy/.gitlab-ci.yml @@ -9,10 +9,8 @@ variables: BUILD_IMAGE_X64_GLIBC: registry.ddbuild.io/ci/async-profiler-build:v137281788-x64-glibc-base@sha256:270a9101716a0865071182e0ef0e40e98f874535b90722949b33a4a8998fe08d # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 BUILD_IMAGE_ARM64_GLIBC: registry.ddbuild.io/ci/async-profiler-build:v137281788-arm64-glibc-base@sha256:511d051d37ed99b2ca9cd3af797aa9de63e4b4b952af1e738b2cea913bbcc057 - # TODO: repin after running `REBUILD_IMAGES="x64-el7"` through rebuild-images.sh - # in a real pipeline (see .gitlab/base/el7/Dockerfile) — this digest is a - # placeholder and does not exist in the registry yet. - BUILD_IMAGE_X64_EL7: registry.ddbuild.io/ci/async-profiler-build:v0-x64-el7-base@sha256:0000000000000000000000000000000000000000000000000000000000000 + # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2056785023 + BUILD_IMAGE_X64_EL7: registry.ddbuild.io/ci/async-profiler-build:v138399627-x64-el7-base@sha256:d324b9b6c3fc48c552185e8969d88c836fb1e17a0e5dc483ba04bbd4f4ed2f38 # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 BUILD_IMAGE_X64_MUSL: registry.ddbuild.io/ci/async-profiler-build:v137281788-x64-musl-base@sha256:fd3803695771de3eabf44e4953c0474273f9dbb97d88c22e99ac507b88572481 # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 From 696f18e06a31aadf7483e011f57250cb39b24b76 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 13:20:32 +0200 Subject: [PATCH 04/17] fix(ci): install gcc-c++ in the EL7 image to satisfy Gradle's compiler probe stresstest:x64 failed with "No C++ compiler found": ConfigurationPresets. setupStandardConfigurations() calls PlatformUtils.findCompiler() unconditionally at project-configuration time, before -Pskip-native is consulted, so an image with no compiler at all fails to even configure the build. The stock EL7 gcc-c++ (4.8.5, base repo, no EPEL) satisfies that --version probe; -Pskip-native still gates every real compile/link task onlyIf, so it's never invoked to build anything. Verified the image still builds and g++ --version succeeds. This needs another `REBUILD_IMAGES="x64-el7"` run and a re-pin of BUILD_IMAGE_X64_EL7 before the fix takes effect. Co-Authored-By: Claude Sonnet 5 --- .gitlab/base/el7/Dockerfile | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.gitlab/base/el7/Dockerfile b/.gitlab/base/el7/Dockerfile index c88040b8c0..5c6f261199 100644 --- a/.gitlab/base/el7/Dockerfile +++ b/.gitlab/base/el7/Dockerfile @@ -2,9 +2,16 @@ # glibc floor (2.17). Oracle Linux 7 is the best-maintained EL7 derivative — # live CDN, current package levels, no ELS subscription needed — see PR #790. # -# This image never compiles anything: the shipped libjavaProfiler.so is built -# in the AlmaLinux 8 image (.gitlab/base/el8/Dockerfile) and consumed here -# via -Pskip-native -Pwith-libs, so no compiler toolchain is installed. +# This image never compiles anything real: the shipped libjavaProfiler.so is +# built in the AlmaLinux 8 image (.gitlab/base/el8/Dockerfile) and consumed +# here via -Pskip-native -Pwith-libs, which gates every actual compile/link +# task onlyIf. It still needs *a* C++ compiler on PATH, though: Gradle's +# ConfigurationPresets.setupStandardConfigurations() calls +# PlatformUtils.findCompiler() unconditionally at project-configuration time +# (build-logic/conventions/.../ConfigurationPresets.kt:35), before -Pskip-native +# is even consulted — with none present, configuration itself fails with +# "No C++ compiler found." The stock EL7 gcc-c++ (4.8.5) is only here to +# satisfy that `--version` probe; it is never invoked to build anything. # # Gradle 9 requires JDK 17+ to run, so JAVA_HOME is a single build JDK (21). # Suites that test against other JDKs (8, 11, 17, ...) fetch that JDK at job @@ -16,7 +23,7 @@ ARG BASE_IMAGE=oraclelinux:7 FROM ${BASE_IMAGE} as base WORKDIR /root -RUN yum -y install git make zip unzip which wget curl jq \ +RUN yum -y install git make zip unzip which wget curl jq gcc-c++ \ && yum -y clean all RUN curl -s "https://get.sdkman.io" | bash && \ From a2e55b16d56ea0f20a087ff973759c2b19ec19a3 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 14:02:31 +0200 Subject: [PATCH 05/17] ci: repin BUILD_IMAGE_X64_EL7 to the gcc-c++ fixed image Rebuilt in pipeline 138438605 with the gcc-c++ fix from the previous commit; pushed and signed successfully before the rebuild-images log cuts off (mid-way through the unrelated datadog-ci image build). Co-Authored-By: Claude Sonnet 5 --- .gitlab/build-deploy/.gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/build-deploy/.gitlab-ci.yml b/.gitlab/build-deploy/.gitlab-ci.yml index 3dd9df9165..3a926988c1 100644 --- a/.gitlab/build-deploy/.gitlab-ci.yml +++ b/.gitlab/build-deploy/.gitlab-ci.yml @@ -9,8 +9,8 @@ variables: BUILD_IMAGE_X64_GLIBC: registry.ddbuild.io/ci/async-profiler-build:v137281788-x64-glibc-base@sha256:270a9101716a0865071182e0ef0e40e98f874535b90722949b33a4a8998fe08d # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 BUILD_IMAGE_ARM64_GLIBC: registry.ddbuild.io/ci/async-profiler-build:v137281788-arm64-glibc-base@sha256:511d051d37ed99b2ca9cd3af797aa9de63e4b4b952af1e738b2cea913bbcc057 - # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2056785023 - BUILD_IMAGE_X64_EL7: registry.ddbuild.io/ci/async-profiler-build:v138399627-x64-el7-base@sha256:d324b9b6c3fc48c552185e8969d88c836fb1e17a0e5dc483ba04bbd4f4ed2f38 + # Generated by pipeline 138438605 (rebuilt with gcc-c++ added, see el7/Dockerfile) + BUILD_IMAGE_X64_EL7: registry.ddbuild.io/ci/async-profiler-build:v138438605-x64-el7-base@sha256:2f4d2852979d7b190dcb997bbc833eb795f2f0db9905300ec239516480e8599d # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 BUILD_IMAGE_X64_MUSL: registry.ddbuild.io/ci/async-profiler-build:v137281788-x64-musl-base@sha256:fd3803695771de3eabf44e4953c0474273f9dbb97d88c22e99ac507b88572481 # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 From 997092a5efb8b8e4d01b5471f1303fdc8e58edca Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 14:15:58 +0200 Subject: [PATCH 06/17] fix(ci): make functional-tests.sh executable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit functional:x64-el7-jdk8 failed with "Permission denied" — the script was committed as mode 100644 instead of 100755. Co-Authored-By: Claude Sonnet 5 --- .gitlab/scripts/functional-tests.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .gitlab/scripts/functional-tests.sh diff --git a/.gitlab/scripts/functional-tests.sh b/.gitlab/scripts/functional-tests.sh old mode 100644 new mode 100755 From d5de3878dc5cb40a691576436743d08e94741ce4 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 15:20:47 +0200 Subject: [PATCH 07/17] fix(ci): raise test heap for the EL7 functional job ContendedCallTraceStorageTest OOM'd with "GC overhead limit exceeded" on jdk8: it drives availableProcessors()*2 threads of CPU/allocation load against the standard -Xmx512m test heap, and the GitLab shared runner pod apparently gives it less headroom than GitHub's ubuntu-latest runners do. Adds an opt-in -PtestMaxHeap gradle property to ddprof-test (appended after the plugin's default -Xmx512m, so the last -Xmx wins) and passes -PtestMaxHeap=1536m from functional-tests.sh only. The shared default used by every other caller (GH Actions matrix, stresstest, etc.) is untouched. Co-Authored-By: Claude Sonnet 5 --- .gitlab/scripts/functional-tests.sh | 1 + ddprof-test/build.gradle.kts | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/.gitlab/scripts/functional-tests.sh b/.gitlab/scripts/functional-tests.sh index d5737b3e91..9bd6813c96 100755 --- a/.gitlab/scripts/functional-tests.sh +++ b/.gitlab/scripts/functional-tests.sh @@ -62,4 +62,5 @@ function onexit { trap onexit EXIT ./gradlew -Pddprof_version="$(get_version)" -Pskip-native -Pwith-libs="$(pwd)/libs" -PCI \ + -PtestMaxHeap=1536m \ ":ddprof-test:test${TEST_CONFIG}" --max-workers=1 --build-cache --stacktrace --info --no-watch-fs --no-daemon diff --git a/ddprof-test/build.gradle.kts b/ddprof-test/build.gradle.kts index d4d3f631a2..cbbb573b57 100644 --- a/ddprof-test/build.gradle.kts +++ b/ddprof-test/build.gradle.kts @@ -24,6 +24,15 @@ configure { "-Dddprof.disable_unsafe=true", "-XX:OnError=/tmp/do_stuff.sh", ) + + // Optional per-invocation heap override (-PtestMaxHeap=1536m). Appended after + // standardJvmArgs' default -Xmx512m, so the last -Xmx on the command line wins. + // Left unset everywhere except CI environments that need more headroom (e.g. + // the EL7 functional job's shared runner pod, see functional-tests.sh) so the + // shared 512m default is unaffected elsewhere. + (project.findProperty("testMaxHeap") as String?)?.let { maxHeap -> + extraJvmArgs.add("-Xmx$maxHeap") + } } // Generate JNI headers using javac From c93ae515af1699793d4275919ad81ed4f70245d4 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 15:55:45 +0200 Subject: [PATCH 08/17] fix(ci): let -Pskip-native target specific projects Several ddprof-test suites (NativeThread, DynamicNativeThread, ThreadEntryDetectionTest, ...) need ddprof-test-native's small JNI test helper on java.library.path regardless of which profiler binary is under test. Bare -Pskip-native disabled ALL native compilation project-wide, so those suites failed with UnsatisfiedLinkError/ NoClassDefFoundError on the EL7 functional job, which needs to skip only ddprof-lib's own build (substituted via -Pwith-libs) while still compiling that helper for real. PlatformUtils.isNativeSkipped() now supports -Pskip-native=, skipping only those; bare -Pskip-native (no value) keeps skipping everywhere, unchanged for every existing caller (stresstests.sh, build.sh, GH Actions). SimpleNativeLibPlugin (used by ddprof-test-native and malloc-shim) and ddprof-lib/build.gradle.kts's own skip-native check now go through it. functional-tests.sh passes -Pskip-native=ddprof-lib,malloc-shim (malloc-shim excluded too: it's unrelated to ddprof-test and its -std=c++17 flag doesn't compile under EL7's stock gcc 4.8.5). Verified locally: with -Pskip-native=ddprof-lib,malloc-shim, ddprof-test-native:linkLib actually compiles and links, while ddprof-lib:assembleDebugJar only runs copyExternalLibs (no native compile task in the graph at all). Co-Authored-By: Claude Sonnet 5 --- .gitlab/scripts/functional-tests.sh | 2 +- .../datadoghq/native/SimpleNativeLibPlugin.kt | 4 +-- .../datadoghq/native/util/PlatformUtils.kt | 25 +++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/.gitlab/scripts/functional-tests.sh b/.gitlab/scripts/functional-tests.sh index 9bd6813c96..7938736b21 100755 --- a/.gitlab/scripts/functional-tests.sh +++ b/.gitlab/scripts/functional-tests.sh @@ -61,6 +61,6 @@ function onexit { trap onexit EXIT -./gradlew -Pddprof_version="$(get_version)" -Pskip-native -Pwith-libs="$(pwd)/libs" -PCI \ +./gradlew -Pddprof_version="$(get_version)" -Pskip-native=ddprof-lib,malloc-shim -Pwith-libs="$(pwd)/libs" -PCI \ -PtestMaxHeap=1536m \ ":ddprof-test:test${TEST_CONFIG}" --max-workers=1 --build-cache --stacktrace --info --no-watch-fs --no-daemon diff --git a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/SimpleNativeLibPlugin.kt b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/SimpleNativeLibPlugin.kt index f39087c02d..c0a7513d9a 100644 --- a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/SimpleNativeLibPlugin.kt +++ b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/SimpleNativeLibPlugin.kt @@ -56,7 +56,7 @@ class SimpleNativeLibPlugin : Plugin { // Compile task val compileTask = project.tasks.register("compileLib", NativeCompileTask::class.java) { - onlyIf { extension.enabled.get() && !project.hasProperty("skip-native") } + onlyIf { extension.enabled.get() && !PlatformUtils.isNativeSkipped(project) } group = "build" description = "Compile the $libraryName library" @@ -76,7 +76,7 @@ class SimpleNativeLibPlugin : Plugin { // Link task val linkTask = project.tasks.register("linkLib", NativeLinkTask::class.java) { - onlyIf { extension.enabled.get() && !project.hasProperty("skip-native") } + onlyIf { extension.enabled.get() && !PlatformUtils.isNativeSkipped(project) } dependsOn(compileTask) group = "build" description = "Link the $libraryName shared library" diff --git a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/util/PlatformUtils.kt b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/util/PlatformUtils.kt index 33c63e3f19..f48055ac98 100644 --- a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/util/PlatformUtils.kt +++ b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/util/PlatformUtils.kt @@ -374,6 +374,31 @@ object PlatformUtils { } } + /** + * Whether native compilation should be skipped for [project]. + * + * `-Pskip-native` (bare, no value) skips it everywhere — the long-standing + * behavior, used when consuming a prebuilt shipped library via -Pwith-libs + * and never touching a compiler. + * + * `-Pskip-native=` skips it only for those + * projects. This lets a caller substitute the prebuilt *shipped* library + * (ddprof-lib) while still compiling something unrelated to its ABI, like + * ddprof-test-native's small JNI test helper, which several ddprof-test + * suites need on java.library.path regardless of which profiler binary + * is under test. + */ + fun isNativeSkipped(project: Project): Boolean { + if (!project.hasProperty("skip-native")) { + return false + } + val value = project.property("skip-native") as? String + if (value.isNullOrEmpty()) { + return true + } + return value.split(",").map { it.trim() }.contains(project.name) + } + /** * Find a C++ compiler, respecting -Pnative.forceCompiler property. * Auto-detects clang++ or g++ if not specified. From fd1abe0fef50953453b4fa6471444b101d2b31cf Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 16:10:29 +0200 Subject: [PATCH 09/17] fix(ci): compile ddprof-test-native as C99 on Linux Now that -Pskip-native=ddprof-lib,malloc-shim actually compiles ddprof-test-native for the EL7 functional job, nativealloc.c failed: error: 'for' loop initial declarations are only allowed in C99 mode EL7's stock gcc (4.8.5) still defaults to gnu89; every other Linux gcc/ clang this project builds on already defaults to a C99+ dialect, so this was latent until a compiler this old actually built the file. Adds an explicit -std=gnu99. Verified against the real EL7 toolchain (oraclelinux:7 + gcc 4.8.5): all three ddprof-test-native source files compile and link. Co-Authored-By: Claude Sonnet 5 --- ddprof-test-native/build.gradle.kts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ddprof-test-native/build.gradle.kts b/ddprof-test-native/build.gradle.kts index 969a92629a..25e57c901f 100644 --- a/ddprof-test-native/build.gradle.kts +++ b/ddprof-test-native/build.gradle.kts @@ -22,9 +22,13 @@ simpleNativeLib { // Note: No optimization (-O0) to prevent inlining of static functions like do_primes() // which need to be visible in stack traces for profiler testing + // + // -std=gnu99: nativealloc.c uses a C99 for-loop-scoped declaration + // (`for (jint i = ...)`). Most Linux gcc/clang builds default to a C99+ + // dialect already, but EL7's stock gcc 4.8.5 still defaults to gnu89. compilerArgs.set( when (PlatformUtils.currentPlatform) { - Platform.LINUX -> listOf("-fPIC") + Platform.LINUX -> listOf("-fPIC", "-std=gnu99") Platform.MACOS -> emptyList() }, ) From c89382e79225c41c360192d05ee757ae0c30eb6a Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 16:38:48 +0200 Subject: [PATCH 10/17] fix(ci): run testRelease, not testDebug, in the EL7 functional job build:x64 (build.sh) only ever produces and ships the release-config libjavaProfiler.so -- that IS the shipped artifact this job exists to exercise. Running testDebug set ddprof_test.config=debug while the loaded library was actually release-built, so debug-only assertions failed outright instead of assumeTrue-skipping correctly, e.g. JVMAccessTest.agentOnLoadVMFlagDetectionTest checking for [TEST::INFO] log lines that only exist in debug builds ("initLibrary not found", "DebugNonSafepoints flag lookup log line was not observed"). Co-Authored-By: Claude Sonnet 5 --- .gitlab/scripts/functional-tests.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitlab/scripts/functional-tests.sh b/.gitlab/scripts/functional-tests.sh index 7938736b21..3ad233a191 100755 --- a/.gitlab/scripts/functional-tests.sh +++ b/.gitlab/scripts/functional-tests.sh @@ -17,7 +17,14 @@ if [ -z "$TEST_JDK" ]; then exit 1 fi -TEST_CONFIG="${TEST_CONFIG:-Debug}" +# Release, not Debug: build:x64 (.gitlab/scripts/build.sh) only ever produces +# and ships the release-config libjavaProfiler.so -- that's the actual +# shipped artifact this job exists to exercise. testDebug would set +# ddprof_test.config=debug while the loaded library was in fact built +# release, so debug-only assertions (e.g. JVMAccessTest's [TEST::INFO] log +# lines, only compiled into debug builds) would fail outright instead of +# correctly assumeTrue-skipping. +TEST_CONFIG="${TEST_CONFIG:-Release}" HERE=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) REPO_ROOT=$( cd "${HERE}/../.." && pwd ) From 09aed945181d868060fcf705f74a3817fdf57b26 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Sep 2026 18:14:26 +0200 Subject: [PATCH 11/17] ci: add temporary diagnostic jobs for the NativeSocket* investigation functional:x64-el7-jdk8 has NativeSocketEvent count: 0 across every retry (zero, not just fewer-than-expected), suggesting the send/recv/ write/read hooks (libraryPatcher_linux.cpp's GOT patching) never actually get installed in this environment -- but that can't be told apart from "installed but never firing" without the debug-only hook-fire counters, which only exist in a debug-config build. build:x64-debug-diag builds a real debug-config libjavaProfiler.so on the same AlmaLinux 8 toolchain build:x64 uses (release configs don't carry NativeSocketSampler's #ifdef DEBUG counters/TEST_LOG calls). functional:x64-el7-debug-diag runs just the NativeSocket* suite against it on the EL7 runtime (via functional-tests.sh's new TESTS_FILTER -> -Ptests passthrough), so --info output shows whether send_hook/recv_hook/write_hook/read_hook ever get called at all. Both are marked TEMPORARY and should be removed once this is root-caused. Co-Authored-By: Claude Sonnet 5 --- .gitlab/build-deploy/.gitlab-ci.yml | 45 +++++++++++++++++++++++++++++ .gitlab/scripts/functional-tests.sh | 7 ++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/.gitlab/build-deploy/.gitlab-ci.yml b/.gitlab/build-deploy/.gitlab-ci.yml index 3a926988c1..a181cb5484 100644 --- a/.gitlab/build-deploy/.gitlab-ci.yml +++ b/.gitlab/build-deploy/.gitlab-ci.yml @@ -229,6 +229,51 @@ functional:x64-el7-jdk21: variables: TEST_JDK: "21" +# --- TEMPORARY diagnostic jobs ------------------------------------------- +# Investigating why NativeSocket* tests produce zero events on the EL7 +# runtime (functional:x64-el7-jdk8 keeps failing there). Builds a real DEBUG +# config (which compiles in NativeSocketSampler's _send_hook_calls/ +# _recv_hook_calls atomics and TEST_LOG calls, gated #ifdef DEBUG) on the +# AlmaLinux 8 toolchain build:x64 already uses, then runs just the +# NativeSocket* suite against it on the EL7 runtime, so the --info log +# shows whether the hooks ever fire at all. Remove both jobs once this is +# root-caused. +build:x64-debug-diag: + extends: .build_job + variables: + BUILD_IMAGE: ${BUILD_IMAGE_X64_GLIBC} + # Matches NativeBuildExtension.platformIdentifier(), which is the actual + # subdirectory name under build/native/debug/META-INF/native-libs/ -- + # NOT a free-form label. build.sh's TARGET for build:x64 relies on the + # same match; a different TARGET here would nest the .so one directory + # too deep for the artifacts:paths pattern below to find it. + TARGET: linux-x64 + script: + - | + if [ -z "${JAVA_HOME}" ] || [ ! -x "${JAVA_HOME}/bin/java" ]; then + export JAVA_HOME=~/.sdkman/candidates/java/current + fi + source .gitlab/scripts/includes.sh + ./gradlew -Pddprof_version="$(get_version)" -Pskip-cpp-tests :ddprof-lib:assembleDebugJar --no-build-cache --stacktrace --info --no-watch-fs --no-daemon + mkdir -p libs + cp -r ddprof-lib/build/native/debug/META-INF/native-libs/* libs/ + +functional:x64-el7-debug-diag: + extends: .functional_job + needs: + - job: prepare:start + artifacts: true + - job: build:x64-debug-diag + artifacts: true + rules: + - when: on_success + variables: + TARGET: linux-x64 + TEST_JDK: "8" + TEST_CONFIG: "Debug" + TESTS_FILTER: "*NativeSocket*" +# --- end TEMPORARY diagnostic jobs --------------------------------------- + # Builds the chaos reliability harness once per pipeline so the per-cell # reliability jobs can pull it as an artifact instead of compiling inline. # Schedule-only because reliability cells are schedule-only. diff --git a/.gitlab/scripts/functional-tests.sh b/.gitlab/scripts/functional-tests.sh index 3ad233a191..5bb6f6eb4b 100755 --- a/.gitlab/scripts/functional-tests.sh +++ b/.gitlab/scripts/functional-tests.sh @@ -68,6 +68,11 @@ function onexit { trap onexit EXIT +GRADLE_EXTRA_ARGS=() +if [ -n "${TESTS_FILTER:-}" ]; then + GRADLE_EXTRA_ARGS+=("-Ptests=${TESTS_FILTER}") +fi + ./gradlew -Pddprof_version="$(get_version)" -Pskip-native=ddprof-lib,malloc-shim -Pwith-libs="$(pwd)/libs" -PCI \ - -PtestMaxHeap=1536m \ + -PtestMaxHeap=1536m "${GRADLE_EXTRA_ARGS[@]}" \ ":ddprof-test:test${TEST_CONFIG}" --max-workers=1 --build-cache --stacktrace --info --no-watch-fs --no-daemon From dd37c3f313c4b4c055419a2cca745845fca67e34 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Mon, 21 Sep 2026 10:58:48 +0200 Subject: [PATCH 12/17] ci(diag): statically link libstdc++ into the debug diagnostic build build:x64-debug-diag's first attempt failed to load on EL7: UnsatisfiedLinkError: libstdc++.so.6: version GLIBCXX_3.4.20 not found Debug configs link libstdc++ dynamically (only release gets -static-libstdc++), so the .so needed a newer GLIBCXX than EL7's stock gcc 4.8.5 provides. Statically linking (gated behind -Dddprof.debugStaticLibstdcxx=true, diagnostic-only) then surfaced a second, unrelated issue: -static-libstdc++ transitively pulls in libstdc++.a's cow-string-inst.o (legacy ABI string instantiations), which references std::random_device::_M_init -> getentropy@GLIBC_2.25 -- traced via the linker map (-Wl,-Map). That's dead code configureRelease's -Wl,--gc-sections already strips; debug's linkerArgs never had that flag. Adding --gc-sections and --exclude-libs,ALL alongside the static libstdc++ flags (same diagnostic gate) fixes both. Verified end to end: rebuilt in the real AlmaLinux 8 image, confirmed via objdump that the result has no libstdc++.so.6 NEEDED entry, no getentropy reference, and a max GLIBC_2.17 requirement, then loaded it inside the real EL7 image and saw VM::initLibrary log successfully. Co-Authored-By: Claude Sonnet 5 --- .gitlab/build-deploy/.gitlab-ci.yml | 8 +++++- .../native/config/ConfigurationPresets.kt | 27 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/.gitlab/build-deploy/.gitlab-ci.yml b/.gitlab/build-deploy/.gitlab-ci.yml index a181cb5484..daf3b3b2aa 100644 --- a/.gitlab/build-deploy/.gitlab-ci.yml +++ b/.gitlab/build-deploy/.gitlab-ci.yml @@ -254,7 +254,13 @@ build:x64-debug-diag: export JAVA_HOME=~/.sdkman/candidates/java/current fi source .gitlab/scripts/includes.sh - ./gradlew -Pddprof_version="$(get_version)" -Pskip-cpp-tests :ddprof-lib:assembleDebugJar --no-build-cache --stacktrace --info --no-watch-fs --no-daemon + # -Dddprof.debugStaticLibstdcxx=true: diagnostic-only (ConfigurationPresets.kt), + # statically links libstdc++/libgcc into the debug .so the same way release + # already does. Without it, the debug .so needs a GLIBCXX newer than EL7's + # stock gcc 4.8.5 provides -- confirmed by the UnsatisfiedLinkError this + # diagnostic build previously hit ("GLIBCXX_3.4.20 not found"). + ./gradlew -Pddprof_version="$(get_version)" -Pskip-cpp-tests -Dddprof.debugStaticLibstdcxx=true \ + :ddprof-lib:assembleDebugJar --no-build-cache --stacktrace --info --no-watch-fs --no-daemon mkdir -p libs cp -r ddprof-lib/build/native/debug/META-INF/native-libs/* libs/ diff --git a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/config/ConfigurationPresets.kt b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/config/ConfigurationPresets.kt index ea4a9c7c62..6b4f8a55fb 100644 --- a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/config/ConfigurationPresets.kt +++ b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/config/ConfigurationPresets.kt @@ -167,7 +167,32 @@ object ConfigurationPresets { // LibraryPatcher) is still executing wrapper code inside it, causing a // SIGSEGV with no hs_err. nodelete pins the mapping for the process's // lifetime no matter how many times the host dlcloses it. - config.linkerArgs.set(commonLinuxLinkerArgs() + listOf("-Wl,-z,nodelete")) + // + // TEMPORARY DIAGNOSTIC: -Dddprof.debugStaticLibstdcxx=true statically + // links libstdc++/libgcc the same way configureRelease always does, so + // a debug build can run on a host whose system libstdc++ doesn't carry + // a new enough GLIBCXX (debug builds normally link dynamically and + // don't need this). --gc-sections/--exclude-libs,ALL come along too: + // -static-libstdc++ transitively pulls in libstdc++.a's cow-string-inst.o + // (legacy ABI string instantiations), which references + // std::random_device::_M_init -> getentropy@GLIBC_2.25 -- unreachable + // dead code that configureRelease's --gc-sections already strips, but + // debug's linkerArgs never had that flag at all. Remove all of this + // once the EL7-functional-job NativeSocket* investigation (PR #805) + // concludes. + val debugStaticLibstdcxx = + System.getProperty("ddprof.debugStaticLibstdcxx") == "true" + config.linkerArgs.set( + commonLinuxLinkerArgs() + listOf("-Wl,-z,nodelete") + + if (debugStaticLibstdcxx) { + listOf( + "-static-libstdc++", "-static-libgcc", + "-Wl,--exclude-libs,ALL", "-Wl,--gc-sections" + ) + } else { + emptyList() + } + ) } Platform.MACOS -> { config.compilerArgs.set( From 8f241b4bc187656274a109a8d15d8ffdd3252f9c Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Mon, 21 Sep 2026 13:40:52 +0200 Subject: [PATCH 13/17] ci: remove the temporary NativeSocket* diagnostic jobs build:x64-debug-diag and functional:x64-el7-debug-diag did their job: they showed the socket hooks fire correctly on EL7 (send/recv/write/ read all called, PLT-patched libjvm.so/libnio.so/libnet.so), and that the real cause of NativeSocketEvent count: 0 is the sampler's rate limiter legitimately rejecting nearly every call because NativeSocketTestBase.doTcpTransfer()'s "the send buffer fills after ~32 iterations and blocks" assumption doesn't hold on this runner's network stack -- a real test bug, not a CI/EL7 problem. That will be quarantined separately now that #777 is merged. Drops the diagnostic-only -Dddprof.debugStaticLibstdcxx gate in ConfigurationPresets.kt and the now-unused TESTS_FILTER passthrough in functional-tests.sh along with the jobs that were the only callers of either. Co-Authored-By: Claude Sonnet 5 --- .gitlab/build-deploy/.gitlab-ci.yml | 51 ------------------- .gitlab/scripts/functional-tests.sh | 7 +-- .../native/config/ConfigurationPresets.kt | 27 +--------- 3 files changed, 2 insertions(+), 83 deletions(-) diff --git a/.gitlab/build-deploy/.gitlab-ci.yml b/.gitlab/build-deploy/.gitlab-ci.yml index daf3b3b2aa..3a926988c1 100644 --- a/.gitlab/build-deploy/.gitlab-ci.yml +++ b/.gitlab/build-deploy/.gitlab-ci.yml @@ -229,57 +229,6 @@ functional:x64-el7-jdk21: variables: TEST_JDK: "21" -# --- TEMPORARY diagnostic jobs ------------------------------------------- -# Investigating why NativeSocket* tests produce zero events on the EL7 -# runtime (functional:x64-el7-jdk8 keeps failing there). Builds a real DEBUG -# config (which compiles in NativeSocketSampler's _send_hook_calls/ -# _recv_hook_calls atomics and TEST_LOG calls, gated #ifdef DEBUG) on the -# AlmaLinux 8 toolchain build:x64 already uses, then runs just the -# NativeSocket* suite against it on the EL7 runtime, so the --info log -# shows whether the hooks ever fire at all. Remove both jobs once this is -# root-caused. -build:x64-debug-diag: - extends: .build_job - variables: - BUILD_IMAGE: ${BUILD_IMAGE_X64_GLIBC} - # Matches NativeBuildExtension.platformIdentifier(), which is the actual - # subdirectory name under build/native/debug/META-INF/native-libs/ -- - # NOT a free-form label. build.sh's TARGET for build:x64 relies on the - # same match; a different TARGET here would nest the .so one directory - # too deep for the artifacts:paths pattern below to find it. - TARGET: linux-x64 - script: - - | - if [ -z "${JAVA_HOME}" ] || [ ! -x "${JAVA_HOME}/bin/java" ]; then - export JAVA_HOME=~/.sdkman/candidates/java/current - fi - source .gitlab/scripts/includes.sh - # -Dddprof.debugStaticLibstdcxx=true: diagnostic-only (ConfigurationPresets.kt), - # statically links libstdc++/libgcc into the debug .so the same way release - # already does. Without it, the debug .so needs a GLIBCXX newer than EL7's - # stock gcc 4.8.5 provides -- confirmed by the UnsatisfiedLinkError this - # diagnostic build previously hit ("GLIBCXX_3.4.20 not found"). - ./gradlew -Pddprof_version="$(get_version)" -Pskip-cpp-tests -Dddprof.debugStaticLibstdcxx=true \ - :ddprof-lib:assembleDebugJar --no-build-cache --stacktrace --info --no-watch-fs --no-daemon - mkdir -p libs - cp -r ddprof-lib/build/native/debug/META-INF/native-libs/* libs/ - -functional:x64-el7-debug-diag: - extends: .functional_job - needs: - - job: prepare:start - artifacts: true - - job: build:x64-debug-diag - artifacts: true - rules: - - when: on_success - variables: - TARGET: linux-x64 - TEST_JDK: "8" - TEST_CONFIG: "Debug" - TESTS_FILTER: "*NativeSocket*" -# --- end TEMPORARY diagnostic jobs --------------------------------------- - # Builds the chaos reliability harness once per pipeline so the per-cell # reliability jobs can pull it as an artifact instead of compiling inline. # Schedule-only because reliability cells are schedule-only. diff --git a/.gitlab/scripts/functional-tests.sh b/.gitlab/scripts/functional-tests.sh index 5bb6f6eb4b..3ad233a191 100755 --- a/.gitlab/scripts/functional-tests.sh +++ b/.gitlab/scripts/functional-tests.sh @@ -68,11 +68,6 @@ function onexit { trap onexit EXIT -GRADLE_EXTRA_ARGS=() -if [ -n "${TESTS_FILTER:-}" ]; then - GRADLE_EXTRA_ARGS+=("-Ptests=${TESTS_FILTER}") -fi - ./gradlew -Pddprof_version="$(get_version)" -Pskip-native=ddprof-lib,malloc-shim -Pwith-libs="$(pwd)/libs" -PCI \ - -PtestMaxHeap=1536m "${GRADLE_EXTRA_ARGS[@]}" \ + -PtestMaxHeap=1536m \ ":ddprof-test:test${TEST_CONFIG}" --max-workers=1 --build-cache --stacktrace --info --no-watch-fs --no-daemon diff --git a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/config/ConfigurationPresets.kt b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/config/ConfigurationPresets.kt index 6b4f8a55fb..ea4a9c7c62 100644 --- a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/config/ConfigurationPresets.kt +++ b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/config/ConfigurationPresets.kt @@ -167,32 +167,7 @@ object ConfigurationPresets { // LibraryPatcher) is still executing wrapper code inside it, causing a // SIGSEGV with no hs_err. nodelete pins the mapping for the process's // lifetime no matter how many times the host dlcloses it. - // - // TEMPORARY DIAGNOSTIC: -Dddprof.debugStaticLibstdcxx=true statically - // links libstdc++/libgcc the same way configureRelease always does, so - // a debug build can run on a host whose system libstdc++ doesn't carry - // a new enough GLIBCXX (debug builds normally link dynamically and - // don't need this). --gc-sections/--exclude-libs,ALL come along too: - // -static-libstdc++ transitively pulls in libstdc++.a's cow-string-inst.o - // (legacy ABI string instantiations), which references - // std::random_device::_M_init -> getentropy@GLIBC_2.25 -- unreachable - // dead code that configureRelease's --gc-sections already strips, but - // debug's linkerArgs never had that flag at all. Remove all of this - // once the EL7-functional-job NativeSocket* investigation (PR #805) - // concludes. - val debugStaticLibstdcxx = - System.getProperty("ddprof.debugStaticLibstdcxx") == "true" - config.linkerArgs.set( - commonLinuxLinkerArgs() + listOf("-Wl,-z,nodelete") + - if (debugStaticLibstdcxx) { - listOf( - "-static-libstdc++", "-static-libgcc", - "-Wl,--exclude-libs,ALL", "-Wl,--gc-sections" - ) - } else { - emptyList() - } - ) + config.linkerArgs.set(commonLinuxLinkerArgs() + listOf("-Wl,-z,nodelete")) } Platform.MACOS -> { config.compilerArgs.set( From 49f6f07e38ecc3758560965f7c852a547107689b Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Mon, 21 Sep 2026 14:39:16 +0200 Subject: [PATCH 14/17] docs: comments describe current state, not what changed "(rebuilt with gcc-c++ added, see el7/Dockerfile)" and "restoring the runtime coverage build:x64 lost when it moved to AlmaLinux 8 (PR #790)" tell a reader what changed relative to old code, not why the current code is the way it is -- and the -std=gnu99 comment named the exact source construct that motivated it, which goes stale the moment that code changes. State the current rationale only. Co-Authored-By: Claude Sonnet 5 --- .gitlab/build-deploy/.gitlab-ci.yml | 5 ++--- ddprof-test-native/build.gradle.kts | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitlab/build-deploy/.gitlab-ci.yml b/.gitlab/build-deploy/.gitlab-ci.yml index 3a926988c1..d9a803bd17 100644 --- a/.gitlab/build-deploy/.gitlab-ci.yml +++ b/.gitlab/build-deploy/.gitlab-ci.yml @@ -9,7 +9,7 @@ variables: BUILD_IMAGE_X64_GLIBC: registry.ddbuild.io/ci/async-profiler-build:v137281788-x64-glibc-base@sha256:270a9101716a0865071182e0ef0e40e98f874535b90722949b33a4a8998fe08d # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 BUILD_IMAGE_ARM64_GLIBC: registry.ddbuild.io/ci/async-profiler-build:v137281788-arm64-glibc-base@sha256:511d051d37ed99b2ca9cd3af797aa9de63e4b4b952af1e738b2cea913bbcc057 - # Generated by pipeline 138438605 (rebuilt with gcc-c++ added, see el7/Dockerfile) + # Generated by pipeline 138438605 BUILD_IMAGE_X64_EL7: registry.ddbuild.io/ci/async-profiler-build:v138438605-x64-el7-base@sha256:2f4d2852979d7b190dcb997bbc833eb795f2f0db9905300ec239516480e8599d # Generated by https://gitlab.ddbuild.io/DataDog/java-profiler/-/jobs/2040944172 BUILD_IMAGE_X64_MUSL: registry.ddbuild.io/ci/async-profiler-build:v137281788-x64-musl-base@sha256:fd3803695771de3eabf44e4953c0474273f9dbb97d88c22e99ac507b88572481 @@ -134,8 +134,7 @@ stresstest:x64: - job: build:x64 artifacts: true variables: - # Oracle Linux 7 (glibc 2.17) — the artifact's actual floor, restoring the - # runtime coverage build:x64 lost when it moved to AlmaLinux 8 (PR #790). + # Oracle Linux 7 (glibc 2.17): the shipped artifact's actual glibc floor. RUNTIME_IMAGE: ${BUILD_IMAGE_X64_EL7} TARGET: linux-x64 diff --git a/ddprof-test-native/build.gradle.kts b/ddprof-test-native/build.gradle.kts index 25e57c901f..bbe49f9c13 100644 --- a/ddprof-test-native/build.gradle.kts +++ b/ddprof-test-native/build.gradle.kts @@ -23,8 +23,7 @@ simpleNativeLib { // Note: No optimization (-O0) to prevent inlining of static functions like do_primes() // which need to be visible in stack traces for profiler testing // - // -std=gnu99: nativealloc.c uses a C99 for-loop-scoped declaration - // (`for (jint i = ...)`). Most Linux gcc/clang builds default to a C99+ + // This code requires C99. Most Linux gcc/clang builds default to a C99+ // dialect already, but EL7's stock gcc 4.8.5 still defaults to gnu89. compilerArgs.set( when (PlatformUtils.currentPlatform) { From 924d6689be883a072e87f7f0ecf95eadbf660421 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Tue, 22 Sep 2026 16:12:37 +0200 Subject: [PATCH 15/17] fix: pre-review cleanup - comment history archeology, skip-native consistency - .gitlab-ci.yml: drop "unchanged from before" -- describes the diff against the file's prior state, not the current mechanism. - ddprof-lib/build.gradle.kts: its own skip-native check still used bare hasProperty("skip-native"), not PlatformUtils.isNativeSkipped(). Both agree today (every caller either omits the property, uses it bare, or lists "ddprof-lib" whenever it's meant to be skipped), so this isn't a behavior change -- confirmed locally: assembleDebugJar still runs only copyExternalLibs under -Pskip-native=ddprof-lib,malloc-shim, and still depends on the real compile/link without it. But a future -Pskip-native= would silently skip ddprof-lib's own build too under the old bare check, contradicting isNativeSkipped()'s own doc comment. Fixes the one call site the new scoped semantics didn't reach. Co-Authored-By: Claude Sonnet 5 --- .gitlab/build-deploy/.gitlab-ci.yml | 2 +- ddprof-lib/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/build-deploy/.gitlab-ci.yml b/.gitlab/build-deploy/.gitlab-ci.yml index d9a803bd17..825ed56577 100644 --- a/.gitlab/build-deploy/.gitlab-ci.yml +++ b/.gitlab/build-deploy/.gitlab-ci.yml @@ -64,7 +64,7 @@ variables: # artifact was built in (BUILD_IMAGE): stresstest:x64 runs on Oracle Linux 7 # to exercise the shipped binary's actual glibc floor, while consuming the # same artifact build:x64 produced in the AlmaLinux 8 image. Other stresstest - # jobs set RUNTIME_IMAGE to their own BUILD_IMAGE, unchanged from before. + # jobs set RUNTIME_IMAGE to their own BUILD_IMAGE. image: ${RUNTIME_IMAGE} script: - .gitlab/scripts/stresstests.sh diff --git a/ddprof-lib/build.gradle.kts b/ddprof-lib/build.gradle.kts index ef26671dda..a70ed25243 100644 --- a/ddprof-lib/build.gradle.kts +++ b/ddprof-lib/build.gradle.kts @@ -101,7 +101,7 @@ afterEvaluate { description = "Assemble the $name build of the library" dependsOn(copyExternalLibs) - if (!project.hasProperty("skip-native")) { + if (!PlatformUtils.isNativeSkipped(project)) { dependsOn(copyTask) } From b7970ee8bbb70d82695de929f6240dcadf4769d0 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Tue, 22 Sep 2026 16:54:18 +0200 Subject: [PATCH 16/17] ci: cache the JDK-under-test tarball across functional job runs Flagged in review: functional-tests.sh's .jdk-cache/ was never in any cache paths -- .cache-config/.cache-config-pull only cover .gradle/caches/, .gradle/wrapper/, .m2/repository/ -- so every run re-downloaded the JDK tarball from Adoptium. Gives .functional_job its own two-entry cache instead of extending .cache-config-pull: the JDK tarball's natural cache key is the major version (TEST_JDK), not the branch/commit the Gradle cache is keyed on, and it doesn't change per-branch the way the Gradle cache's gradle-wrapper.properties hash does, so it gets pull-push with a static, ref-independent key while the Gradle entry stays pull-only exactly as before. Co-Authored-By: Claude Sonnet 5 --- .gitlab/build-deploy/.gitlab-ci.yml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/.gitlab/build-deploy/.gitlab-ci.yml b/.gitlab/build-deploy/.gitlab-ci.yml index 825ed56577..6a6455ae02 100644 --- a/.gitlab/build-deploy/.gitlab-ci.yml +++ b/.gitlab/build-deploy/.gitlab-ci.yml @@ -184,7 +184,6 @@ stresstest:arm64-musl: .functional_job: extends: - .retry-config - - .cache-config-pull stage: stresstest needs: - job: prepare:start @@ -199,6 +198,29 @@ stresstest:arm64-musl: image: ${BUILD_IMAGE_X64_EL7} variables: TARGET: linux-x64 + # Two independent cache entries rather than extending .cache-config-pull: + # the JDK-under-test tarball (functional-tests.sh's JDK_CACHE_DIR) has + # nothing to do with the Gradle/Maven cache's key or lifetime. It doesn't + # vary by branch or commit -- Adoptium's "latest" build for a given major + # version is the same tarball everywhere -- and without its own entry here + # it was never cached at all, so every run re-downloaded it from Adoptium. + cache: + - key: + files: + - gradle/wrapper/gradle-wrapper.properties + prefix: build-v2-${CI_COMMIT_REF_SLUG} + fallback_keys: + - build-v2-${CI_DEFAULT_BRANCH} + - build-v2-main + paths: + - .gradle/caches/ + - .gradle/wrapper/ + - .m2/repository/ + policy: pull + - key: jdk-cache-v1-${TEST_JDK} + paths: + - .jdk-cache/ + policy: pull-push script: - .gitlab/scripts/functional-tests.sh artifacts: From cb4d5a1179f75201a8b7de56293147ad10cd865d Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Tue, 22 Sep 2026 16:59:31 +0200 Subject: [PATCH 17/17] fix: use isNativeSkipped() everywhere skip-native is checked Flagged in review: only ddprof-lib/build.gradle.kts and SimpleNativeLibPlugin.kt went through PlatformUtils.isNativeSkipped() after the earlier fix; GtestPlugin.kt, GtestTaskBuilder.kt, FuzzTargetsPlugin.kt and ddprof-lib/benchmarks/build.gradle.kts still used the bare hasProperty("skip-native") check, so -Pskip-native= would silently skip gtest/fuzz/benchmarks too, contradicting the scoped semantics everywhere else now documents. GtestPlugin.kt/GtestTaskBuilder.kt are applied directly to ddprof-lib (project.name == "ddprof-lib" there already), so those are a direct swap. FuzzTargetsPlugin.kt and benchmarks/build.gradle.kts are applied to the :ddprof-lib:fuzz and :ddprof-lib:benchmarks *subprojects* (project.name == "fuzz"/"benchmarks") -- fuzzing and benchmarking are part of ddprof-lib's native surface, not something a caller names on its own, so those go through project.parent's identity instead of their own. Verified locally: -Pskip-native=ddprof-lib,malloc-shim still skips :ddprof-lib:benchmarks:compileBenchmark (SKIPPED, not executed), and it still compiles normally without the flag -- matching the old bare check's behavior for every current caller, while now correctly generalizing for a caller that doesn't name ddprof-lib. Co-Authored-By: Claude Sonnet 5 --- .../datadoghq/native/fuzz/FuzzTargetsPlugin.kt | 18 ++++++++++++------ .../com/datadoghq/native/gtest/GtestPlugin.kt | 4 ++-- .../datadoghq/native/gtest/GtestTaskBuilder.kt | 2 +- ddprof-lib/benchmarks/build.gradle.kts | 10 ++++++++-- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/fuzz/FuzzTargetsPlugin.kt b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/fuzz/FuzzTargetsPlugin.kt index 48dcca114c..7f9627bcd5 100644 --- a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/fuzz/FuzzTargetsPlugin.kt +++ b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/fuzz/FuzzTargetsPlugin.kt @@ -54,13 +54,19 @@ class FuzzTargetsPlugin : Plugin { private fun configureFuzzTargets(project: Project, extension: FuzzTargetsExtension) { val hasFuzzer = PlatformUtils.hasFuzzer() + // This plugin is applied to the :ddprof-lib:fuzz subproject, whose own + // name ("fuzz") is not what a caller means by -Pskip-native=ddprof-lib + // -- fuzzing is part of ddprof-lib's native surface, not a project a + // caller names on its own, so the check goes through the parent + // project's identity instead of this one's. + val nativeSkipped = PlatformUtils.isNativeSkipped(project.parent ?: project) // Master fuzz task val fuzzAll = project.tasks.register("fuzz") { onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && - !project.hasProperty("skip-native") && + !nativeSkipped && !project.hasProperty("skip-fuzz") } group = "verification" @@ -75,7 +81,7 @@ class FuzzTargetsPlugin : Plugin { // Build-only aggregate: compiles and links all targets without running them val buildFuzz = project.tasks.register("buildFuzz") { - onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && !project.hasProperty("skip-native") && !project.hasProperty("skip-fuzz") } + onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && !nativeSkipped && !project.hasProperty("skip-fuzz") } group = "build" description = "Build all fuzz targets without running them" } @@ -113,7 +119,7 @@ class FuzzTargetsPlugin : Plugin { // instead of recompiling the whole profiler per target. val sharedObjDir = project.file("${project.layout.buildDirectory.get()}/obj/fuzz/_profiler") val compileProfilerTask = project.tasks.register("compileFuzzProfilerSources", NativeCompileTask::class.java) { - onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && !project.hasProperty("skip-native") && !project.hasProperty("skip-fuzz") } + onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && !nativeSkipped && !project.hasProperty("skip-fuzz") } group = "build" description = "Compile the profiler sources shared by all fuzz targets" @@ -142,7 +148,7 @@ class FuzzTargetsPlugin : Plugin { // Compile task - only compiles this target's own fuzz driver; profiler // sources come from the shared compileFuzzProfilerSources task. val compileTask = project.tasks.register("compileFuzz_$fuzzName", NativeCompileTask::class.java) { - onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && !project.hasProperty("skip-native") && !project.hasProperty("skip-fuzz") } + onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && !nativeSkipped && !project.hasProperty("skip-fuzz") } group = "build" description = "Compile the fuzz target $fuzzName" @@ -155,7 +161,7 @@ class FuzzTargetsPlugin : Plugin { // Link task val linkTask = project.tasks.register("linkFuzz_$fuzzName", NativeLinkExecutableTask::class.java) { - onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && !project.hasProperty("skip-native") && !project.hasProperty("skip-fuzz") } + onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && !nativeSkipped && !project.hasProperty("skip-fuzz") } dependsOn(compileProfilerTask, compileTask) group = "build" description = "Link the fuzz target $fuzzName" @@ -171,7 +177,7 @@ class FuzzTargetsPlugin : Plugin { // Execute task val executeTask = project.tasks.register("fuzz_$fuzzName", Exec::class.java) { - onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && !project.hasProperty("skip-native") && !project.hasProperty("skip-fuzz") } + onlyIf { hasFuzzer && !project.hasProperty("skip-tests") && !nativeSkipped && !project.hasProperty("skip-fuzz") } dependsOn(linkTask) group = "verification" description = "Run the fuzz target $fuzzName for $duration seconds" diff --git a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/gtest/GtestPlugin.kt b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/gtest/GtestPlugin.kt index d2196cf8db..8aed352c48 100644 --- a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/gtest/GtestPlugin.kt +++ b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/gtest/GtestPlugin.kt @@ -113,7 +113,7 @@ class GtestPlugin : Plugin { onlyIf { hasGtest && - !project.hasProperty("skip-native") && + !PlatformUtils.isNativeSkipped(project) && !project.hasProperty("skip-gtest") && PlatformUtils.currentPlatform == Platform.LINUX && extension.nativeLibsSourceDir.isPresent && @@ -171,7 +171,7 @@ class GtestPlugin : Plugin { onlyIf { hasGtest && !project.hasProperty("skip-tests") && - !project.hasProperty("skip-native") && + !PlatformUtils.isNativeSkipped(project) && !project.hasProperty("skip-gtest") } } diff --git a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/gtest/GtestTaskBuilder.kt b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/gtest/GtestTaskBuilder.kt index 341146a49d..3a0ea225cc 100644 --- a/build-logic/conventions/src/main/kotlin/com/datadoghq/native/gtest/GtestTaskBuilder.kt +++ b/build-logic/conventions/src/main/kotlin/com/datadoghq/native/gtest/GtestTaskBuilder.kt @@ -223,7 +223,7 @@ class GtestTaskBuilder( fun skipConditions(): Boolean { return project.hasProperty("skip-tests") || - project.hasProperty("skip-native") || + PlatformUtils.isNativeSkipped(project) || project.hasProperty("skip-gtest") } diff --git a/ddprof-lib/benchmarks/build.gradle.kts b/ddprof-lib/benchmarks/build.gradle.kts index 3d40f7e4de..09e87ab960 100644 --- a/ddprof-lib/benchmarks/build.gradle.kts +++ b/ddprof-lib/benchmarks/build.gradle.kts @@ -23,10 +23,16 @@ val shouldBuild = PlatformUtils.currentPlatform == Platform.MACOS || if (shouldBuild) { val compiler = PlatformUtils.findCompiler(project) + // This is the :ddprof-lib:benchmarks subproject, whose own name + // ("benchmarks") is not what a caller means by -Pskip-native=ddprof-lib -- + // benchmarking is part of ddprof-lib's native surface, not a project a + // caller names on its own, so the check goes through the parent project's + // identity instead of this one's. + val nativeSkipped = PlatformUtils.isNativeSkipped(project.parent ?: project) // Compile task val compileTask = tasks.register("compileBenchmark") { - onlyIf { shouldBuild && !project.hasProperty("skip-native") } + onlyIf { shouldBuild && !nativeSkipped } group = "build" description = "Compile the unwinding failures benchmark" @@ -40,7 +46,7 @@ if (shouldBuild) { // Link task val binary = file("${layout.buildDirectory.get()}/bin/$benchmarkName") val linkTask = tasks.register("linkBenchmark") { - onlyIf { shouldBuild && !project.hasProperty("skip-native") } + onlyIf { shouldBuild && !nativeSkipped } dependsOn(compileTask) group = "build" description = "Link the unwinding failures benchmark"