c++ segmentation fault using condition_variable with the -static linkage flag

180 views Asked by At

I compiled and linked this simple program using g++ in a Raspberry Pi 4 running on the ARMv8-A.

compiler: g++ -Wall -O0 -g3 -std=c++11 -c Main.cpp

linker: g++ -static -o "bugTest.elf" ./Main.o

Compiler version:

g++ (Debian 10.2.1-6) 10.2.1 20210110

Copyright (C) 2020 Free Software Foundation, Inc.

#include <condition_variable>
#include <iostream>

struct TempX
{
    std::condition_variable cvx;
};

int main()
{
    TempX *x = new TempX;
    std::cout << "0 done" << std::endl;
    delete x;

    std::cout << "1 done test" << std::endl;

    return 0;

}

I got segmentation fault using the cross compiler aarch64-linux-gnu-g++ (or SIGABRT using the g++ compiler on the Raspberry Pi 4) at the line delete x;

Program received signal SIGABRT, Aborted.
0x00000000004a9810 in raise ()
(gdb) where
#0  0x00000000004a9810 in raise ()
#1  0x0000000000400b78 in abort ()
#2  0x0000000000482178 in __gnu_cxx::__verbose_terminate_handler() ()
#3  0x0000000000480e6c in __cxxabiv1::__terminate(void (*)()) ()
#4  0x0000000000480ed0 in std::terminate() ()
#5  0x000000000040b790 in std::condition_variable::wait(std::unique_lock<std::mutex>&) ()
#6  0x0000000000401454 in TempX::~TempX (this=0x58a040,
    __in_chrg=<optimized out>) at Main.cpp:4
#7  0x0000000000401364 in main () at Main.cpp:14

But I didn't get any error if I linked it without using the -static flag.

I got the same error with the -static flag using either the compiler g++ on the Raspberry Pi 4 directly or using a cross compiler aarch64-linux-gnu-g++.

Could anyone explain why?

1

There are 1 answers

0
alien On

Answer and Update: Thanks to multiple people for the prompt answers. There is a bug in the glibc where the condition variable does not work well with the "-static" flag. This bug has been around for more than 10 years.

See bug reports and discussions here: https://bbs.archlinux.org/viewtopic.php?id=274171

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58909

The solution available is either not use the "-static" flag in the linker, or use some unused pthread_cond_xxx() functions.

For me, using an unused pthread_cond_destroy() solved the problem with just one warning about using nullptr in the non-null expected argument.

#include <pthread.h>
void pthread_cond_bug() {
        pthread_cond_signal((pthread_cond_t *) nullptr);
        pthread_cond_init((pthread_cond_t *) nullptr,
                          (const pthread_condattr_t *) nullptr);
        pthread_cond_destroy((pthread_cond_t *) nullptr);
        pthread_cond_timedwait((pthread_cond_t *) nullptr, (pthread_mutex_t *)
                               nullptr, (const struct timespec *) nullptr);
        pthread_cond_wait((pthread_cond_t *) nullptr, (pthread_mutex_t *) nullptr);
}