Embedded LLD: Native sanitizer linking (OpenBSD) #5430
Closed
SeanTAllen
started this conversation in
ponyc
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
This continues the native sanitizer work from #5399/#5409 (Linux) and #5424/#5426 (FreeBSD). That work moved native sanitizer linking off the legacy
system()compiler driver and onto embedded LLD, one platform at a time. The Phase 7 progress note on #4941 lists native sanitizer on the BSDs as one of the things still dropping to the legacy linker, three platforms wearing one description. FreeBSD was the first. OpenBSD was supposed to be next, the same shape with different driver output to validate.It isn't the same shape. OpenBSD doesn't have the sanitizer runtimes at all.
What's actually on the system
The whole mechanism from the Linux and FreeBSD work rests on one thing: when ponyc is built with sanitizers, the instrumented
libponyrtreferences__asan_*/ubsan symbols, and embedded LLD has no-fsanitize=to pull the runtime in, so we capture the runtime link fragment from the compiler driver at build time and splice it into the embedded link. That only works if the runtime is there to capture.On OpenBSD 7.8 (base clang 19.1.7),
/usr/lib/clang/19/libships exactly two compiler-rt archives:libclang_rt.profile.aandlibclang_rt.ubsan_minimal.a. That's it. No asan. No tsan. No standalone ubsan.So ponyc's three sanitizer
use=options fail, each at a different spot:address_sanitizerandthread_sanitizernever get far enough to link anything. Base clang rejects-fsanitize=addressand-fsanitize=threadoutright, with "unsupported option for target amd64-unknown-openbsd7.8", so the instrumentedlibponyrtwon't even compile.undefined_behavior_sanitizercompiles. The driver accepts-fsanitize=undefinedand emits a link line naminglibclang_rt.ubsan_standalone.a. That file isn't on disk. The link dies withcannot open .../libclang_rt.ubsan_standalone.a: No such file or directory.The one sanitizer runtime OpenBSD does ship is the minimal UBSan runtime, reached with
-fsanitize-minimal-runtime. It works: it caught a signed overflow in a test program and aborted. But it's the terse production-hardening runtime, a one-line message and a SIGABRT, not the developer-facing diagnostics the sanitizer CI exists to provide, and ponyc doesn't wire it up. It doesn't change the picture.This was never a linker problem. Embedded LLD, the captured fragment, the splice, none of it is the obstacle. There's no runtime on the system to link. The legacy compiler-driver path that OpenBSD falls back to today can't produce a working sanitizer ponyc either, for the same reason.
While I was in there
Since the real question was "what builds on OpenBSD," I checked every
use=option, not just the sanitizers. Two more don't work, for the same shape of reason:coveragelinks-fprofile-instr-generate -fcoverage-mapping. The shippedlibclang_rt.profile.ais incomplete: it references__llvm_profile_begin_bitmap/__llvm_profile_end_bitmapand nothing defines them, so a coverage build fails to link.valgrindhas no OpenBSD port. The runtime includes<valgrind/valgrind.h>underUSE_VALGRIND, and that header isn't there, so the build fails to compile.use=dtracewas already rejected on OpenBSD by itswhich dtracecheck; OpenBSD has no DTrace, and itsbtraceis a different tracer with no USDT probes. The remaining eightuse=options are internal runtime#ifdeftoggles with no external dependency, and the default OpenBSD build is green in tier-3 CI, so they're fine.What I did instead
There's no native sanitizer linking to enable here, so this isn't an implement-it change. Every one of those failures is the same bad experience: you ask for a build option, the build runs for a while, and then it dies deep in a compile or link with a message about a missing runtime or header that never mentions OpenBSD or says the option is unsupported.
use=dtracealready does the right thing by failing fast at configure with a clear error. The fix is to make the rest behave the same way.ponyc#5429 rejects
address_sanitizer,thread_sanitizer,undefined_behavior_sanitizer,coverage, andvalgrindatgmake configureon OpenBSD, each with a one-line error that says what's missing and points at BUILD.md. The error fires at make-parse time, beforegmake libs, so you find out immediately. A tier-3 OpenBSD CI step asserts each option is rejected for the documented reason, so a typo in the OS string can't quietly bring the confusing failure back. BUILD.md grows an "Unsupported build options" section, and ponylang-website#1352 documents the same on the custom-ponyc-builds and building-ponyc-from-source pages.What this means for Phase 7
Phase 7 is the removal of the legacy
system()linker, and it can't happen while live code routes through legacy for a working capability. The #4941 note had native sanitizer on OpenBSD down as one of those, same shape as FreeBSD, validate the driver output and open the gates.That premise was wrong, and it's wrong in a way that helps. There's no working OpenBSD sanitizer capability behind the legacy path, because you can't build a sanitizer ponyc on OpenBSD in the first place. Nothing to migrate, nothing to preserve. So OpenBSD native sanitizer linking comes off the Phase 7 blocker list and gets reclassified from "TODO" to "not applicable, the runtimes aren't there." DragonFly still needs its own look. macOS still needs its own look. OpenBSD is settled.
Design: #4941
All reactions