Skip to content

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

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions