Skip to content

perf(build): eager symbol binding (-z,now,-z,relro) for faster init#1273

Draft
duncanista wants to merge 1 commit into
jordan.gonzalez/cold-start-instrumentation/featurefrom
jordan.gonzalez/eager-binding/feature
Draft

perf(build): eager symbol binding (-z,now,-z,relro) for faster init#1273
duncanista wants to merge 1 commit into
jordan.gonzalez/cold-start-instrumentation/featurefrom
jordan.gonzalez/eager-binding/feature

Conversation

@duncanista

Copy link
Copy Markdown
Contributor

Jira: none yet — add before marking ready.

⚠️ DRAFT — stacked on #1271 (jordan.gonzalez/cold-start-instrumentation/feature). Review/merge that first; this PR's base will retarget once #1271 lands.

Overview

Appends two link args to the clang-linker RUSTFLAGS in both compile Dockerfiles (images/Dockerfile.bottlecap.compile and images/Dockerfile.bottlecap.alpine.compile):

-Clink-arg=-Wl,-z,now -Clink-arg=-Wl,-z,relro

Mechanism. The published layers are dynamically-linked glibc binaries. By default the dynamic linker resolves imported symbols lazily, on first call, via the PLT/GOT — so the first invocation of each external function pays a one-time resolution stall, and many of those stalls land on the cold-start INIT path. -z now forces eager binding: every dynamic symbol is resolved at load time, moving that resolution work off the INIT path. -z relro then marks the GOT read-only after relocation, which is a standard hardening that pairs with full eager binding (full RELRO).

Scope. This is a no-op for the static musl build: that binary statically links its dependencies, so there is no lazy PLT resolution of dynamic symbols to eliminate. In the alpine Dockerfile the edited export RUSTFLAGS=... already lives inside the existing if [ "${PLATFORM}" = "x86_64" ] clang-linker branch, so behavior there is unchanged beyond the added (inert) flags. The flags only have a runtime effect on the dynamically-linked glibc layers.

Dockerfile-only change — no Rust source changes.

Testing

  • Inspected the resulting RUSTFLAGS string in both Dockerfiles to confirm the two args are appended cleanly after the existing -lclang_rt.builtins-$(uname -m) flag, preserving the surrounding shell quoting and command substitution.
  • NOT docker-built locally — CI will validate the image build. Functional/cold-start impact to be confirmed via layer build + INIT-duration measurement once CI produces an artifact.

Append -Clink-arg=-Wl,-z,now -Clink-arg=-Wl,-z,relro to the clang-linker RUSTFLAGS in both compile Dockerfiles. Eager (now) binding resolves all dynamic symbols at load time instead of lazily via the PLT, moving resolution stalls off the Lambda INIT path; relro hardens the GOT. This only affects the dynamically-linked glibc layers; it is a no-op on the static musl build.
@datadog-prod-us1-3

datadog-prod-us1-3 Bot commented Jun 24, 2026

Copy link
Copy Markdown

Pipelines

Fix all issues with BitsAI

⚠️ Warnings

🚦 5 Pipeline jobs failed

DataDog/datadog-lambda-extension | integration-suite: [on-demand]   View in Datadog   GitLab

DataDog/datadog-lambda-extension | e2e-test-status (amd64)   View in Datadog   GitLab

DataDog/datadog-lambda-extension | e2e-test-status (amd64, fips)   View in Datadog   GitLab

View all 5 failed jobs.

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 3748a14 | Docs | Datadog PR Page | Give us feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant