1

I needed to check the error code of std::system_error doing my project. But when I did that, I ended up with SIGSEGV.

foo.cpp :

#include <thread>
#include <iostream>
#include <system_error>

int main(void)
{
    std::thread t1;

    try
    {
        t1.join();
    }
    catch (const std::system_error& e)
    {
        std::cout << "System error\n";

        if (e.code() == std::errc::invalid_argument) // here in the operator==(), running into SIGSEGV 
        {
            std::cout << e.what() << "\n";
        }
        else
        {
            throw;
        }
    }

    return 0;
}

Makefile:

.PHONY: all clean

all: foo

SRCS := $(shell find . -name '*.cpp')
OBJS := $(SRCS:.cpp=.o)

foo: $(OBJS)
        gcc -o $@ $^ -lstdc++ -lpthread

%.o: %.cpp
        gcc -std=c++17 -Wall -c -g -O0 -pthread -o $@ $<

clean:
        rm -rf foo *.o

My gcc version:

$ gcc --version
gcc (GCC) 7.2.1 20170829 (Red Hat 7.2.1-1)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

When I was posting this question, StackOverflow suggested similar questions. One of them is How to portably compare std::system_error exceptions to std::errc values?. What is described in it seemed to be closely related to the problem I am going through. So I tested against gcc 8.3 which was in the list of problem fixed gcc versions.

Fixed on all active branches, so will be fixed in the 6.5, 7.4, 8.3 and 9.1 releases.

But it still appeared to have not been fixed, or it is just another problem:

$ gcc --version
gcc (GCC) 8.3.1 20190311 (Red Hat 8.3.1-3)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ make
gcc -std=c++17 -Wall -c -g -O0 -pthread -o foo.o foo.cpp
gcc -o foo foo.o -lstdc++ -lpthread

$ ./foo
System error
Segmentation fault (core dumped)

Any ideas to work around this problem and detect which error actually it is when the system_error occurs?


Edit: Adding backtrace information with gdb

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000003603269ca2 in std::error_category::equivalent(std::error_code const&, int) const () from /usr/lib64/libstdc++.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.x86_64 libgcc-4.4.7-17.el6.x86_64 libstdc++-4.4.7-17.el6.x86_64
(gdb) where
#0  0x0000003603269ca2 in std::error_category::equivalent(std::error_code const&, int) const () from /usr/lib64/libstdc++.so.6
#1  0x000000000040285f in std::operator== (__lhs=..., __rhs=...) at /opt/rh/devtoolset-7/root/usr/include/c++/7/system_error:299
#2  0x0000000000402628 in main () at foo.cpp:17
Young-hwi
  • 607
  • 7
  • 14
  • Since you are interested in detecting what the error is, why are you conditionally checking `e.what()` instead of outputting that before the `if`? (Maybe something like `std::cout << "System error: '" << e.what() << "'\n";`.) – JaMiT Sep 20 '19 at 05:35
  • Can you provide a backtrace? That would also answer the question whether it's the comparison or the call to `e.code()` that causes the segfault. Also, you could help yourself if you turned on diagnostics of the runtime library, which catches and reports a few cases of undefined behaviour. – Ulrich Eckhardt Sep 20 '19 at 05:54
  • 2
    Oh, there's one thing you may be doing wrong: You're using `gcc` to compile and link. Use `g++` instead. http://coliru.stacked-crooked.com/a/34662c9678a39e10 suggests it works. – Ulrich Eckhardt Sep 20 '19 at 06:05
  • Possible duplicate of [What is the difference between g++ and gcc?](https://stackoverflow.com/questions/172587/what-is-the-difference-between-g-and-gcc) – L. F. Sep 20 '19 at 06:30
  • @UlrichEckhardt It has nothing to do with the command I used. No matter if it's gcc or g++, the gnu compiler collection will correctly invoke appropriate compiler/linker. As far as I know, "gcc" is only a facet that invokes preprocessor, compiler or linker. And I actually tried to check if using `g++` instead of `gcc` makes the program not crash, which turns out that it still crashes. And as I showed the stack trace, it crashes in the middle of `operator==` which continues to call `std::error_category::equivalent` – Young-hwi Sep 24 '19 at 04:33
  • @UlrichEckhardt I checked out your link that show it works. May be it's the gcc version, I guess. Anyway, I have decided to not print out any information about the error by removing the `if()` statement. Thanks. – Young-hwi Sep 24 '19 at 05:01

1 Answers1

1

Seems that the difference between the gcc toolchain version that I used and the version by which the libstdc++ is built is the culprit.

C++ project compiled with modern compiler, but linked against outdated libstdc++

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

As to http://coliru.stacked-crooked.com/a/34662c9678a39e10 which shows a result that does not crash, I guess it had no problem because the library and the compiler versions match.

Young-hwi
  • 607
  • 7
  • 14