linrrzqqq opened a new pull request, #63191:
URL: https://github.com/apache/doris/pull/63191
Related PR: #62489
Problem Summary:
```cpp
static const std::string no_message = "";
return ok() ? no_message : state_->msg;
```
In the clang-built Doris BE binary, this inline static `std::string` is
emitted as a weak/COMDAT object and placed in `.data.rel.ro`.
```bash
$ readelf -sW "$BIN" | c++filt | grep 'Status::message.*no_message'
105229: 000000007d6958e0 32 OBJECT WEAK DEFAULT 28
arrow::Status::message[abi:cxx11]() const::no_message[abi:cxx11]
$ readelf -SW doris/output/be/lib/doris_be | grep '\[ *28\]'
[28] .data.rel.ro PROGBITS 000000007d0f7720 7d0f6720 7e4208 00
WA 0 0 32
```
After relocation, RELRO makes this section read-only. However, C++
function-local statics are lazily initialized on first execution, so the first
call to `Status::message()` tries to construct `no_message` at runtime. The
`std::string` constructor writes to the object storage in `.data.rel.ro`, which
triggers `SIGSEGV invalid permissions for mapped object` like:
*FromStatus(arrow::Status)*
```text
*** Query id: 0-0 ***
*** is nereids: 0 ***
*** tablet id: 0 ***
*** Aborted at 1778559900 (unix time) try "date -d @1778559900" if you are
using GNU date ***
*** Current BE git commitID: f02e9e680c8 ***
*** SIGSEGV invalid permissions for mapped object (@0xaaaaf1ecbf28) received
by PID 3634450 (TID 3636517 OR 0xfffa35fe97c0) from PID 18446744073473408808;
stack trace: ***
0# doris::signal::(anonymous namespace)::FailureSignalHandler(int,
siginfo_t*, void*) at /root/selectdb-core/be/src/common/signal_handler.h:421
1# PosixSignals::chained_handler(int, siginfo_t*, void*) [clone .part.0] in
/opt/jdk/lib/server/libjvm.so
2# JVM_handle_linux_signal in /opt/jdk/lib/server/libjvm.so
3# 0x0000FFFFAE091830 in linux-vdso.so.1
4# std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >::basic_string<std::allocator<char> >(char const*,
std::allocator<char> const&) at
/root/toolchain/ldb-toolchain-v0.21/bin/../lib/gcc/aarch64-linux-gnu/13/../../../../include/c++/13/bits/basic_string.h:632
5# arrow::flight::internal::TransportStatus::FromStatus(arrow::Status
const&) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
6# arrow::flight::transport::grpc::ToGrpcStatus(arrow::Status const&,
grpc::ServerContext*) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
7# arrow::flight::transport::grpc::(anonymous
namespace)::GrpcServiceHandler::DoGet(grpc::ServerContext*,
arrow::flight::protocol::Ticket const*,
grpc::ServerWriter<arrow::flight::protocol::FlightData>*) in
/opt/selectdb/4.1.3.2026042721/be/lib/doris_be
8# grpc::Status
grpc::internal::CatchingFunctionHandler<grpc::internal::ServerStreamingHandler<arrow::flight::protocol::FlightService::Service,
arrow::flight::protocol::Ticket,
arrow::flight::protocol::FlightData>::RunHandler(grpc::internal::MethodHandler::HandlerParameter
const&)::{lambda()#1}>(grpc::internal::ServerStreamingHandler<arrow::flight::protocol::FlightService::Service,
arrow::flight::protocol::Ticket,
arrow::flight::protocol::FlightData>::RunHandler(grpc::internal::MethodHandler::HandlerParameter
const&)::{lambda()#1}&&) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
9#
grpc::internal::ServerStreamingHandler<arrow::flight::protocol::FlightService::Service,
arrow::flight::protocol::Ticket,
arrow::flight::protocol::FlightData>::RunHandler(grpc::internal::MethodHandler::HandlerParameter
const&) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
10# grpc::Server::SyncRequest::ContinueRunAfterInterception() in
/opt/selectdb/4.1.3.2026042721/be/lib/doris_be
11#
grpc::Server::SyncRequest::Run(std::shared_ptr<grpc::Server::GlobalCallbacks>
const&, bool) in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
12# grpc::ThreadManager::MainWorkLoop() in
/opt/selectdb/4.1.3.2026042721/be/lib/doris_be
13#
grpc::ThreadManager::WorkerThread::WorkerThread(grpc::ThreadManager*)::$_0::__invoke(void*)
in /opt/selectdb/4.1.3.2026042721/be/lib/doris_be
14# grpc_core::(anonymous
namespace)::ThreadInternalsPosix::ThreadInternalsPosix(char const*, void
(*)(void*), void*, bool*, grpc_core::Thread::Options
const&)::{lambda(void*)#1}::__invoke(void*) in
/opt/selectdb/4.1.3.2026042721/be/lib/doris_be
15# start_thread in /lib64/libc.so.6
16# thread_start in /lib64/libc.so.6
```
*ToStatus()*
```text
*** SIGSEGV invalid permissions for mapped object (@0x56448ff1ef38) received
by PID 66637 (TID 67372 OR 0x7f2687017640) from PID 18446744071829581624; stack
trace: ***
0# doris::signal::(anonymous namespace)::FailureSignalHandler(int,
siginfo_t*, void*) at ../src/common/signal_handler.h:417
1# PosixSignals::chained_handler(int, siginfo*, void*) [clone .part.0] in
/usr/lib/jvm/java-17-openjdk-amd64/lib/server/libjvm.so
2# JVM_handle_linux_signal in
/usr/lib/jvm/java-17-openjdk-amd64/lib/server/libjvm.so
3# 0x00007F2836CE7520 in /lib/x86_64-linux-gnu/libc.so.6
4# std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >::basic_string<std::allocator<char> >(char const*,
std::allocator<char> const&) at
/usr/local/ldb-toolchain-v0.26/bin/../lib/gcc/x86_64-pc-linux-gnu/15/include/g++-v15/bits/basic_string.h:707
5# arrow::Status::WithDetail(std::shared_ptr<arrow::StatusDetail>) const in
/mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
6# arrow::flight::internal::TransportStatus::ToStatus() const in
/mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
7# arrow::flight::transport::grpc::FromGrpcStatus(grpc::Status const&,
grpc::ClientContext*) in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
8# arrow::flight::transport::grpc::(anonymous
namespace)::GrpcClientInterceptorAdapter::Intercept(grpc::experimental::InterceptorBatchMethods*)
in /mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
9# grpc::internal::InterceptorBatchMethodsImpl::RunInterceptors() in
/mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
10# grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata,
grpc::internal::CallOpClientRecvStatus, grpc::internal::CallNoOp<3>,
grpc::internal::CallNoOp<4>, grpc::internal::CallNoOp<5>,
grpc::internal::CallNoOp<6> >::FinalizeResult(void**, bool*) in
/mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
11# grpc::ClientReaderWriter<arrow::flight::protocol::FlightData,
arrow::flight::protocol::FlightData>::Finish() in
/mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
12# arrow::flight::transport::grpc::(anonymous
namespace)::FinishableDataStream<grpc::ClientReaderWriter<arrow::flight::protocol::FlightData,
arrow::flight::protocol::FlightData>,
arrow::flight::internal::FlightData>::DoFinish() in
/mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
13# arrow::flight::transport::grpc::(anonymous
namespace)::WritableDataStream<grpc::ClientReaderWriter<arrow::flight::protocol::FlightData,
arrow::flight::protocol::FlightData>,
arrow::flight::internal::FlightData>::DoFinish() in
/mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
14# arrow::flight::internal::ClientDataStream::Finish(arrow::Status) in
/mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
15# arrow::flight::ClientStreamReader::Next() in
/mnt/disk1/PERFORMANCE_ENV/be/lib/doris_be
16# doris::PythonClient::read_batch(std::shared_ptr<arrow::RecordBatch>*) at
./be/build_RELEASE/../src/udf/python/python_client.cpp:136
17# doris::PythonUDFClient::evaluate(arrow::RecordBatch const&,
std::shared_ptr<arrow::RecordBatch>*) at
./be/build_RELEASE/../src/udf/python/python_udf_client.cpp:36
```
### fix
Move the empty message/detail sentinels out of the header inline path and
make non-OK statuses return `state_->msg` directly. This avoids touching the
empty OK-message sentinel on error paths and prevents the inline weak/COMDAT
`std::string` object from being lazily constructed from a read-only mapping.
--
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]