apache / apache/doris

[bug](be) Undefined _Unwind_* symbols when building BE UT in UBSAN mode

Open
#64,239 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
15.9k
Forks
3.9k
Avg merge
2d 23h
Merged PRs (30d)
520

Description

### Search before asking

- [X] I had searched in the [issues](https://github.com/apache/doris/issues?q=is%3Aissue) and found no similar issues.

### Version

master

### What's Wrong?

When building BE unit tests in UBSAN mode, the linker reports undefined `_Unwind_*` symbols, causing the build to fail. The same issue also affects LSAN builds.

The root cause is that when using sanitizer link flags, the `_Unwind_*` family of symbols (from `libgcc_eh` / `libgcc_s`) are not being linked. These symbols are required by:

1. `libclang_rt.ubsan_standalone` (references `_Unwind_Backtrace`, `_Unwind_GetIP`)
2. `libprofiler.a` from gperftools (references `_Unwind_Backtrace`, `_Unwind_GetIP`)
3. `libglog.a` (references `_Unwind_GetIP`)
4. `libstdc++.a` (references `_Unwind_Resume`, `_Unwind_RaiseException`, `_Unwind_Resume_or_Rethrow`, `_Unwind_GetTextRelBase`, `_Unwind_GetRegionStart`, `_Unwind_GetDataRelBase`, `_Unwind_SetGR`, `_Unwind_SetIP`, `_Unwind_GetLanguageSpecificData`, `_Unwind_GetIPInfo`, `_Unwind_DeleteException`)

### Full Error Log

```
ld.lld: error: undefined symbol: _Unwind_Backtrace
>>> referenced by sanitizer_unwind_linux_libcdep.cpp.o:(__sanitizer::BufferedStackTrace::UnwindSlow(unsigned long, unsigned int)) in archive /var/local/ldb-toolchain/tmp/gentoo/llvm/bin/../../../../lib/clang/20/lib/linux/libclang_rt.ubsan_standalone-x86_64.a
>>> referenced by sanitizer_unwind_linux_libcdep.cpp.o:(__sanitizer::BufferedStackTrace::UnwindSlow(unsigned long, void*, unsigned int)) in archive /var/local/ldb-toolchain/tmp/gentoo/llvm/bin/../../../../lib/clang/20/lib/linux/libclang_rt.ubsan_standalone-x86_64.a
>>> referenced by stacktrace_libgcc-inl.h:100 (src/stacktrace_libgcc-inl.h:100)
>>> stacktrace.o:(GetStackTraceWithContext_libgcc(void**, int, int, void const*)) in archive /var/local/thirdparty/installed/gperftools/lib/libprofiler.a
>>> referenced 8 more times

ld.lld: error: undefined symbol: _Unwind_GetIP
>>> referenced by sanitizer_unwind_linux_libcdep.cpp.o:(__sanitizer::(anonymous namespace)::Unwind_Trace(_Unwind_Context*, void*)) in archive /var/local/ldb-toolchain/tmp/gentoo/llvm/bin/../../../../lib/clang/20/lib/linux/libclang_rt.ubsan_standalone-x86_64.a
>>> referenced by stacktrace_libgcc-inl.h:69 (src/stacktrace_libgcc-inl.h:69)
>>> stacktrace.o:(libgcc_backtrace_helper(_Unwind_Context*, void*)) in archive /var/local/thirdparty/installed/gperftools/lib/libprofiler.a
>>> referenced by utilities.cc.o:(.text+0x5a) in archive /var/local/thirdparty/installed/lib/libglog.a
>>> referenced 2 more times

ld.lld: error: undefined symbol: _Unwind_Resume
>>> referenced by task_worker_pool_test.cpp:38 (./be/ut_build_UBSAN/./be/test/agent/task_worker_pool_test.cpp:38)
>>> test/CMakeFiles/doris_be_test.dir/agent/task_worker_pool_test.cpp.o:(doris::TaskWorkerPoolTest_TaskWorkerPool_Test::TestBody())
>>> referenced by task_worker_pool_test.cpp:60 (./be/ut_build_UBSAN/./be/test/agent/task_worker_pool_test.cpp:60)
>>> test/CMakeFiles/doris_be_test.dir/agent/task_worker_pool_test.cpp.o:(doris::TaskWorkerPoolTest_PreSubmitCallback_Test::TestBody())
>>> referenced by task_worker_pool_test.cpp:85 (./be/ut_build_UBSAN/./be/test/agent/task_worker_pool_test.cpp:85)
>>> test/CMakeFiles/doris_be_test.dir/agent/task_worker_pool_test.cpp.o:(doris::TaskWorkerPoolTest_PreSubmitCallbackWithDedup_Test::TestBody())
>>> referenced 257716 more times

ld.lld: error: undefined symbol: _Unwind_RaiseException
>>> referenced by eh_throw.o:(__cxa_throw) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a
>>> referenced by eh_ptr.o:(std::rethrow_exception(std::__exception_ptr::exception_ptr)) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a

ld.lld: error: undefined symbol: _Unwind_Resume_or_Rethrow
>>> referenced by eh_throw.o:(__cxa_rethrow) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a

ld.lld: error: undefined symbol: _Unwind_GetTextRelBase
>>> referenced by eh_personality.o:(base_of_encoded_value(unsigned char, _Unwind_Context*)) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a

ld.lld: error: undefined symbol: _Unwind_GetRegionStart
>>> referenced by eh_personality.o:(base_of_encoded_value(unsigned char, _Unwind_Context*)) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a
>>> referenced by eh_personality.o:(parse_lsda_header(_Unwind_Context*, unsigned char const*, lsda_header_info*)) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a

ld.lld: error: undefined symbol: _Unwind_GetDataRelBase
>>> referenced by eh_personality.o:(base_of_encoded_value(unsigned char, _Unwind_Context*)) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a

ld.lld: error: undefined symbol: _Unwind_SetGR
>>> referenced by eh_personality.o:(__gxx_personality_v0) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a
>>> referenced by eh_personality.o:(__gxx_personality_v0) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a

ld.lld: error: undefined symbol: _Unwind_SetIP
>>> referenced by eh_personality.o:(__gxx_personality_v0) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a

ld.lld: error: undefined symbol: _Unwind_GetLanguageSpecificData
>>> referenced by eh_personality.o:(__gxx_personality_v0) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a

ld.lld: error: undefined symbol: _Unwind_GetIPInfo
>>> referenced by eh_personality.o:(__gxx_personality_v0) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a

ld.lld: error: undefined symbol: _Unwind_DeleteException
>>> referenced by eh_catch.o:(__cxa_end_catch) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a
>>> referenced by eh_catch.o:(__cxa_end_catch) in archive /var/local/ldb-toolchain/bin/../lib/gcc/x86_64-pc-linux-gnu/15/libstdc++.a
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
```

### What You Expected to Work

BE UT should build successfully in UBSAN mode without linker errors.

### How to Reproduce?

1. Build BE with UBSAN mode: `BUILD_TYPE=UBSAN ./build.sh --be --ut`
2. The linker will fail with undefined `_Unwind_*` symbol errors

### Anything Else?

The fix is to add `-lgcc_eh` to the sanitizer link flags for both GCC and Clang compilers. For GCC, `-lgcc_eh` provides the `_Unwind_*` symbols. For Clang with `-rtlib=compiler-rt`, the compiler-rt runtime does not include unwind support by default, so `-lgcc_eh` must also be explicitly linked.

This fix applies to both `be/CMakeLists.txt` and `cloud/CMakeLists.txt`.

### Are you willing to submit PR?

- [X] Yes I am willing to submit a PR!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.