Skip to content

Commit 5190d19

Browse files
committed
Ressurect helper-rust integration coverage (mostly)
1 parent 0909436 commit 5190d19

19 files changed

Lines changed: 619 additions & 141 deletions

File tree

.gitlab/generate-appsec.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,65 @@
263263
- appsec/tests/integration/build/*.tar.gz
264264
- .gradle-home/wrapper/dists/
265265

266+
"helper-rust integration coverage":
267+
stage: test
268+
image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/docker:29.4.0-noble
269+
tags: [ "docker-in-docker:amd64" ]
270+
interruptible: true
271+
rules:
272+
- if: $CI_COMMIT_BRANCH == "master"
273+
interruptible: false
274+
- when: on_success
275+
variables:
276+
KUBERNETES_CPU_REQUEST: 8
277+
KUBERNETES_MEMORY_REQUEST: 24Gi
278+
KUBERNETES_MEMORY_LIMIT: 30Gi
279+
ARCH: amd64
280+
GRADLE_USER_HOME: "$CI_PROJECT_DIR/.gradle-home"
281+
before_script:
282+
<?php echo $ecrLoginSnippet, "\n"; ?>
283+
<?php dockerhub_login() ?>
284+
script:
285+
- apt update && apt install -y openjdk-17-jre
286+
- |
287+
cd appsec/tests/integration
288+
CACHE_PATH=build/php-appsec-volume-caches-${ARCH}.tar.gz
289+
if [ -f "$CACHE_PATH" ]; then
290+
echo "Loading cache from $CACHE_PATH"
291+
TERM=dumb ./gradlew loadCaches --info
292+
fi
293+
294+
TERM=dumb ./gradlew buildPortableLibdatadogPhp \
295+
--info -Pbuildscan --scan -PuseHelperRustCoverage
296+
TERM=dumb ./gradlew test8.3-release-ssi test8.4-release-zts-ssi \
297+
--info -Pbuildscan --scan -PcheckCoreDumps -PuseHelperRustCoverage
298+
TERM=dumb ./gradlew saveCaches --info
299+
- |
300+
cd "$CI_PROJECT_DIR"
301+
DD_COVERAGE_FLAGS=helper-rust-integration-8.3-release-ssi \
302+
.gitlab/upload-code-coverage-to-datadog.sh \
303+
appsec/tests/integration/build/reports/coverage/8.3-release-ssi/helper-rust-integration.lcov
304+
DD_COVERAGE_FLAGS=helper-rust-integration-8.4-release-zts-ssi \
305+
.gitlab/upload-code-coverage-to-datadog.sh \
306+
appsec/tests/integration/build/reports/coverage/8.4-release-zts-ssi/helper-rust-integration.lcov
307+
after_script:
308+
- mkdir -p "${CI_PROJECT_DIR}/artifacts"
309+
- find appsec/tests/integration/build/test-results -name "*.xml" -exec cp --parents '{}' "${CI_PROJECT_DIR}/artifacts/" \; || true
310+
- cp -r appsec/tests/integration/build/test-logs "${CI_PROJECT_DIR}/artifacts/" 2>/dev/null || true
311+
- .gitlab/silent-upload-junit-to-datadog.sh "test.source.file:appsec/"
312+
artifacts:
313+
reports:
314+
junit: "artifacts/**/test-results/**/TEST-*.xml"
315+
paths:
316+
- "artifacts/"
317+
- appsec/tests/integration/build/reports/coverage/*/helper-rust-integration.lcov
318+
when: always
319+
cache:
320+
- key: "appsec int test cache"
321+
paths:
322+
- appsec/tests/integration/build/*.tar.gz
323+
- .gradle-home/wrapper/dists/
324+
266325
"appsec code coverage":
267326
stage: test
268327
extends: .appsec_test

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

appsec/helper-rust/build.rs

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,16 @@ use std::path::PathBuf;
44
fn main() {
55
println!("cargo::rustc-check-cfg=cfg(tokio_unstable)");
66

7-
let target = env::var("TARGET").expect("TARGET environment variable not set");
87
let has_coverage = env::var("CARGO_FEATURE_COVERAGE").is_ok();
98

10-
// When building with coverage instrumentation, compile coverage initialization code
11-
// that configures LLVM profiling runtime at library load time
9+
// When building with coverage instrumentation, compile the code used by
10+
// the sidecar entrypoint to initialize the LLVM profiling runtime.
1211
if has_coverage {
13-
let out_dir = env::var("OUT_DIR").expect("OUT_DIR not set");
14-
1512
cc::Build::new()
1613
.file("coverage_init.c")
1714
.define("COVERAGE_BUILD", None)
1815
.compile("coverage_init");
1916

20-
// On aarch64, the LLVM profiler runtime requires outline-atomic functions
21-
// that aren't available in older glibc versions
22-
let needs_outline_atomics = target.contains("aarch64");
23-
if needs_outline_atomics {
24-
cc::Build::new()
25-
.file("outline_atomics.c")
26-
.compile("outline_atomics");
27-
println!("cargo::rerun-if-changed=outline_atomics.c");
28-
}
29-
30-
// Force the linker to include coverage_init.a and outline_atomics.a in their
31-
// entirety, even though nothing in Rust references their symbols directly.
32-
// coverage_init.c has constructor/destructor functions for flushing coverage.
33-
// outline_atomics.c provides atomic helpers needed by the profiler runtime.
34-
println!("cargo::rustc-link-arg=-Wl,--whole-archive");
35-
println!("cargo::rustc-link-arg={}/libcoverage_init.a", out_dir);
36-
if needs_outline_atomics {
37-
println!("cargo::rustc-link-arg={}/liboutline_atomics.a", out_dir);
38-
}
39-
println!("cargo::rustc-link-arg=-Wl,--no-whole-archive");
40-
4117
println!("cargo::rerun-if-changed=coverage_init.c");
4218
}
4319

appsec/helper-rust/coverage_init.c

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// LLVM coverage profiling initialization for helper-rust
22
//
3-
// This module sets up the LLVM profiling environment when the helper is
4-
// loaded by sidecar. It reinitializes the LLVM profiling runtime to use
5-
// the correct output path.
3+
// The embedded sidecar calls this module explicitly from its entrypoint. It
4+
// reinitializes the LLVM profiling runtime to use the correct output path.
65
//
76
// Coverage data is flushed when the process receives SIGUSR1, as well as
87
// at normal process exit via atexit handler.
@@ -21,6 +20,7 @@
2120

2221
// LLVM profiling runtime API (from compiler-rt/lib/profile/)
2322
extern void __llvm_profile_initialize_file(void);
23+
extern void __llvm_profile_set_filename(const char *);
2424
extern int __llvm_profile_write_file(void);
2525
extern const char *__llvm_profile_get_filename(void);
2626

@@ -82,21 +82,20 @@ static void coverage_signal_handler(int signo) {
8282
coverage_log("__llvm_profile_write_file() returned %d", ret);
8383
}
8484

85-
__attribute__((constructor))
86-
static void coverage_init(void) {
87-
coverage_log("coverage_init() constructor called");
85+
void ddappsec_helper_coverage_init(void) {
86+
coverage_log("ddappsec_helper_coverage_init() called");
8887

89-
const char *env_profile = getenv("LLVM_PROFILE_FILE");
90-
coverage_log("LLVM_PROFILE_FILE env = %s", env_profile ? env_profile : "(null)");
88+
const char *profile_path = getenv("_DD_HELPER_RUST_COVERAGE_FILE");
89+
if (!profile_path) {
90+
profile_path = "/helper-rust/coverage/helper-%h-%p-%m.profraw";
91+
}
92+
coverage_log("Helper coverage profile = %s", profile_path);
9193

9294
const char *filename_before = __llvm_profile_get_filename();
9395
coverage_log("Profile filename BEFORE reinit: %s",
9496
filename_before ? filename_before : "(null)");
9597

96-
const char *profile_path = "/helper-rust/coverage/helper-%p-%m.profraw";
97-
coverage_log("Setting LLVM_PROFILE_FILE to: %s", profile_path);
98-
setenv("LLVM_PROFILE_FILE", profile_path, 1);
99-
98+
__llvm_profile_set_filename(profile_path);
10099
coverage_log("Calling __llvm_profile_initialize_file()");
101100
__llvm_profile_initialize_file();
102101

@@ -110,17 +109,7 @@ static void coverage_init(void) {
110109
atexit(coverage_atexit);
111110
coverage_log("Registered atexit handler");
112111

113-
coverage_log("coverage_init() completed");
114-
}
115-
116-
__attribute__((destructor))
117-
static void coverage_fini(void) {
118-
coverage_log("coverage_fini() destructor called");
119-
coverage_flush();
120-
if (log_fd >= 0 && log_fd != STDERR_FILENO) {
121-
close(log_fd);
122-
log_fd = -1;
123-
}
112+
coverage_log("ddappsec_helper_coverage_init() completed");
124113
}
125114

126115
#endif // COVERAGE_BUILD

appsec/helper-rust/outline_atomics.c

Lines changed: 0 additions & 42 deletions
This file was deleted.

appsec/helper-rust/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ use datadog_sidecar::service::telemetry::InProcessTelemetryClientFactory;
1717

1818
pub use client::{on_disconnect, on_message, MessageResponse};
1919

20+
#[cfg(feature = "coverage")]
21+
pub fn initialize_coverage() {
22+
unsafe extern "C" {
23+
fn ddappsec_helper_coverage_init();
24+
}
25+
26+
unsafe {
27+
ddappsec_helper_coverage_init();
28+
}
29+
}
30+
2031
pub struct AppSecHelper {
2132
cancel_token: CancellationToken,
2233
client_task_tracker: TaskTracker,

0 commit comments

Comments
 (0)