morningman opened a new pull request, #68595:
URL: https://github.com/apache/doris/pull/68595
### What problem does this PR solve?
Issue Number: N/A
Problem Summary:
**Context.** On macOS the only entry point for the BE unit tests is
`run-be-ut.sh`, and it defaults to `BUILD_TYPE_UT=ASAN`. Since macOS 26.4
that
default cannot start a single process: every binary linked against llvm.org's
`libclang_rt.asan_osx_dynamic` deadlocks during runtime initialisation,
before
`main()`. The same toolchain is what `env.sh` installs on macOS (`llvm@20`),
so a
developer who follows the documented setup gets a build that hangs instead
of a
build that fails.
**1. The problem, and what it cost**
*The deadlock.* `sample` on the stalled process shows the whole chain:
```
__malloc_init (libsystem_malloc) <- early libSystem
init calls malloc_default_zone()
`- wrap_malloc_default_zone (asan runtime)
`- AsanInitFromRtl -> AsanInitInternal -> InitializeShadowMemory
`- MemoryRangeIsAvailable -> MemoryMappingLayout::Next ->
get_dyld_hdr()
`- dyld_shared_cache_iterate_text_swift <- macOS 26.4
reimplemented this in Swift
`- _Block_copy -> malloc
`- __sanitizer_mz_malloc (asan's own malloc)
`- AsanInitFromRtl() <- re-enters init
`- StaticSpinMutex::LockSlow <- spins on the
lock it already holds
```
This is an OS-side change, not a Doris one, and it is not "ASAN does not
work on
macOS 26" — Apple's own clang sanitizer runtime runs fine on the same host.
Only
llvm.org's compiler-rt is affected. Upstream fixed it by weak-importing
`_dyld_get_dyld_header` and using it when present instead of walking the
shared
cache (llvm/llvm-project#182943, main `2e7d07a`; backport #188913,
release/22.x
`7b6514c`). **The fix shipped only in 22.1.8.** 20.1.8 is the last 20.x
release
and 21.1.8 the last 21.x, so there is no version of `llvm@20` that can ever
be
made to work.
*Why it looks like a hang and not an error.* `be/CMakeLists.txt` reaches
`storage/index/ann` unconditionally, whose `cmake-protect` target
`add_subdirectory()`s `contrib/openblas`. OpenBLAS runs an instrumented
`getarch`
probe from its **configure** step
(`contrib/openblas/cmake/prebuild.cmake:1513`,
`execute_process(COMMAND .../getarch 0 ...)`), and `execute_process` has no
timeout. So every ASAN build stops at `-- Running getarch` and never moves
again, at ~90% CPU, with no diagnostic. `run-be-ut.sh` on macOS was therefore
unusable at its default setting, and the failure mode gives the developer
nothing to act on.
*The second obstacle, once the toolchain is bumped.* clang 22 added
`-Wc2y-extensions` and folds it into `-Wpedantic`. `__COUNTER__` only reached
the C standard in C23, and `be/src/runtime/runtime_profile.h:73-85` uses it
to
give two `SCOPED_TIMER` / `SCOPED_RAW_TIMER` expansions on the same line
distinct names — so a clang 22 build of any TU that includes that header
fails
under `-Werror`. Three representative unity TUs were enough to hit it; it is
not
confined to one module.
*Two latent defects clang 22 then surfaced.* The bump is not a pure version
change: clang 22's stricter diagnostics stop the build on two pre-existing
bugs,
and both are worth fixing on their own merits.
| # | Site | Diagnostic | What is actually wrong |
|---|---|---|---|
| 1 | `be/src/load/group_commit/wal/wal_dirs_info.cpp:98` |
`-Wunused-result` | `LOG(INFO) << "… err: {}", e.what();` — the `,` is the
comma operator, not an argument separator, so the statement is `(LOG(INFO) <<
"…{}") , (e.what())`. The `{}` is never substituted and `e.what()` is evaluated
and discarded: **the error message has never been logged**, only the literal
`{}`. A repo-wide scan for the same shape finds exactly this one site
(`cloud/src/common/logging.h` matches only inside macro definitions and is not
a bug). |
| 2 | `common/cpp/sync_point.cpp:208,210` | `-Wthread-safety-analysis` | The
function holds `std::unique_lock lock(mutex_)` and then releases it with a raw
`mutex_.unlock()` / `mutex_.lock()` pair around the callback, bypassing the
lock's ownership tracking. If the callback throws, the re-lock is skipped while
`~unique_lock` still believes it owns the mutex, so the destructor unlocks a
mutex that is not held (UB) and `num_callbacks_running_` is never decremented.
Using `lock.unlock()` / `lock.lock()` keeps the callback running unlocked — the
intent — while leaving the ownership state correct on every path. |
**2. What this PR does, and why it helps**
- `env.sh`: the macOS `CELLARS` list moves from `llvm@20` to `llvm@22`, with
a
comment recording that 22.1.8 is the floor and why. `env.sh` is what puts
the
toolchain on `PATH` and what derives `DORIS_CLANG_HOME`, so this is the
single
line that decides which clang a macOS developer builds with.
- `be/CMakeLists.txt`: add `-Wno-c2y-extensions` to the clang suppression
block
that already sits **after** `-Wpedantic` (`-Wno-pass-failed` and friends).
The
position matters: a `-Wno-` placed before `-Wpedantic` is silently
re-enabled
by it, which is why passing the flag through `EXTRA_CXX_FLAGS` does not
work —
that variable lands near the front of the command line. clang 20 accepts
the
unknown `-Wno-` without a diagnostic, so no version guard is needed and
Linux/older clang are unaffected.
- `.github/workflows/be-ut-mac.yml`: install `llvm@22` so the workflow's
toolchain matches `env.sh`.
- `be/src/load/group_commit/wal/wal_dirs_info.cpp` and
`common/cpp/sync_point.cpp`: the two fixes from the table above — one line
each,
the smallest change that removes the defect rather than a suppression. No
`-Wno-unused-result` / `-Wno-thread-safety-analysis` is added: those
diagnostics are pointing at real bugs and should keep firing.
- `.github/workflows/build-thirdparty.yml` (both macOS jobs): same bump. This
one is not cosmetic — `thirdparty/build-thirdparty.sh:55` sources
`env.sh`, so
once `env.sh` names `llvm@22` a runner that still installs `llvm@20` would
put
a non-existent directory on `PATH` and fall through to `/usr/bin/clang`,
i.e.
Apple clang. Installing `llvm@22` keeps the job on the intended compiler.
**Consequence worth naming:** because `build-thirdparty.sh` reads `env.sh`,
the
macOS thirdparty prebuilt (`doris-thirdparty-prebuilt-darwin-arm64.tar.xz`)
is
built with clang 22 from the next run of that workflow onward. That is the
intended outcome — the prebuilt and the BE that links it should come from the
same toolchain — but it is a published artifact change, not a private one.
**3. The classes, and how they call each other**
```
env.sh CELLARS := llvm@22
|- generates custom_env_mac.sh, which prepends $HOMEBREW/opt/llvm@22/bin
to PATH
|- DORIS_CLANG_HOME := dirname($(command -v clang))/.. -> CC / CXX /
ASAN_SYMBOLIZER_PATH
'- is sourced by:
|- run-be-ut.sh -> cmake -DCMAKE_BUILD_TYPE=ASAN_UT
|- thirdparty/build-thirdparty.sh:55 -> the macOS prebuilt job
'- .github/workflows/be-ut-mac.yml -> brew install llvm@22
be/CMakeLists.txt if (COMPILER_CLANG)
|- add_compile_options(-Wpedantic ...) <- enables the c2y group
'- add_compile_options(-Wno-pass-failed
-Wno-c2y-extensions) <- added here; must stay
after the line above
|
be/src/runtime/runtime_profile.h:73-85
'- MACRO_CONCAT(SCOPED_TIMER, __COUNTER__) <- the only __COUNTER__ use
in be/src, be/test
|
be/src/storage/index/ann/cmake-protect/CMakeLists.txt:48
'- add_subdirectory(contrib/openblas)
'- cmake/prebuild.cmake:1513 execute_process(getarch) <- where the
hang surfaced
```
### Release note
None
### Check List (For Author)
- Test: Manual test on macOS 26.5.1 (arm64, dyld-1378).
- `clang -fsanitize=address` hello world exits 0 with llvm@22 and still
deadlocks with llvm@20 on the same host.
- `sh run-be-ut.sh` with no environment overrides now selects
`Clang-22.1.8`
and clears the `-- Running getarch` point that previously hung forever:
zero FAILED targets, `doris_be_test` links.
- `sh run-be-ut.sh --run --filter=FormatRoundTest.*` starts the ASAN
binary
and passes 8 tests.
- `build-support/check-build-hygiene.sh` passes.
- Regression test / unit test: N/A (toolchain and flag change).
- Behavior changed: Yes — macOS builds now use LLVM 22 instead of LLVM 20,
and
because `thirdparty/build-thirdparty.sh` sources `env.sh`, the macOS
thirdparty
prebuilt is built with clang 22 from the next run of that workflow onward.
- Does this need documentation: No
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]