Skip to content

Fix SIGSEGV during static initialization when /proc/self/io is missing (glog uninitialized) #3183

@jesson1

Description

@jesson1

Describe the bug
It appears that brpc is initializing global variables during startup and encounters a failure in accessing /proc/self/io. This triggers a call to glog to output a log message, but glog itself has not been initialized yet, leading to a SIGSEGV.

(gdb) bt
#0  0x00000055933de478 in google::LogMessage::Init(char const*, int, int, void (google::LogMessage::*)()) ()
#1  0x00000055933de9d4 in google::LogMessage::LogMessage(char const*, int, int, int, void (google::LogMessage::*)()) ()
#2  0x0000005592f1c6f0 in bvar::read_proc_io (s=s@entry=0x7fc9ae7448) at /usr/include/glog/logging.h:1381
#3  0x0000005592f1f2c8 in bvar::ProcIOReader::operator() (stat=0x7fc9ae7448, this=<optimized out>) at /brpc/src/bvar/default_variables.cpp:466
#4  bvar::CachedReader<bvar::ProcIO>::get_value<bvar::ProcIOReader> (fn=...) at /brpc/src/bvar/default_variables.cpp:154
#5  bvar::ProcIOReader::get_field<unsigned long, 0ul> () at /brpc/src/bvar/default_variables.cpp:471
#6  0x0000005592f1de60 in bvar::PassiveStatus<unsigned long>::get_value (this=<optimized out>) at /brpc/src/bvar/passive_status.h:140
#7  bvar::detail::ReducerSampler<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::take_sample (this=this@entry=0x7fac590080) at /brpc/src/bvar/detail/sampler.h:137
#8  0x0000005592f227a8 in bvar::detail::ReducerSampler<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::ReducerSampler (reducer=0x5593c55b38 <bvar::g_rchar>, this=0x7fac590080)
    at /brpc/src/bvar/detail/sampler.h:98
#9  bvar::PassiveStatus<unsigned long>::get_sampler (this=0x5593c55b38 <bvar::g_rchar>) at /brpc/src/bvar/passive_status.h:145
#10 bvar::detail::WindowBase<bvar::PassiveStatus<unsigned long>, (bvar::SeriesFrequency)1>::WindowBase (window_size=-1,
    var=0x5593c55b38 <bvar::g_rchar>, this=0x5593c55aa8 <bvar::g_io_read_second>) at /brpc/src/bvar/window.h:82
#11 bvar::PerSecond<bvar::PassiveStatus<unsigned long> >::PerSecond (this=0x5593c55aa8 <bvar::g_io_read_second>, name=...,
    var=0x5593c55b38 <bvar::g_rchar>) at /brpc/src/bvar/window.h:205
#12 0x0000005592cd6554 in __static_initialization_and_destruction_0 (__priority=65535, __initialize_p=1)
    at /brpc/src/bvar/default_variables.cpp:704
#13 0x00000055933ee1e0 in __libc_csu_init ()
#14 0x0000007fbc278d80 in __libc_start_main () from /lib/aarch64-linux-gnu/libc.so.6
#15 0x0000005592ce38c8 in _start ()

To Reproduce
compile env:

FROM debian:11

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential cmake git ca-certificates curl ccache \
    libgoogle-glog-dev libgflags-dev libprotobuf-dev \
    protobuf-compiler libssl-dev libevent-dev libc-ares-dev \
    libsnappy-dev libleveldb-dev libprotoc-dev \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/apache/brpc.git /brpc
RUN cd /brpc && git checkout 1.10.0 && mkdir build
RUN cd /brpc/build && cmake -DBUILD_UNIT_TESTS=OFF -DBUILD_SHARED_LIBS=OFF -DWITH_GLOG=ON .. && make -j$(nproc) && make install;

WORKDIR /workspace

CMD ["/bin/bash"]

my binary static linked with brpc and glog.

runtime env:

root@testhost:~/yjs$ ls /proc/self/io
ls: 无法访问 '/proc/self/io': 没有那个文件或目录

Expected behavior
brpc should handle the absence of /proc/self/io gracefully during the static initialization phase. It should avoid using glog (LOG macros) before main() starts, or use a safer logging fallback like fprintf(stderr, ...).

Versions
OS: Debian 11 (aarch64)
Compiler: GCC 10.2.1
brpc: 1.10.0
glog: 0.4.0
protobuf:

Additional context/screenshots
This is a classic "Static Initialization Order Fiasco". In a fully static link, the order of global object construction across different translation units is undefined. If bvar objects in brpc are constructed before glog is ready, any error-triggered logging will cause a crash.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions