'Why does interrupting a simple C++ program under Valgrind results in segmentation fault?
Consider the following program:
#include <iostream>
int main() { std::cout << "Hello, World!\n"; }
I compile it with on Ubuntu 20.04 (Focal Fossa) with g++ a.cpp -o a and run under Valgrind with valgrind ./a. Valgrind takes few moments to spin up and completes successfully.
However, if I press Ctrl + C (presumably sending SIGINT) right after the Valgrind has started, but the program did not execute yet, I frequently get SIGSEGV and Segmentation fault message, like so:
valgrind ./a
==11071== Memcheck, a memory error detector
==11071== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11071== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==11071== Command: ./a
==11071==
^C==11071==
==11071== Process terminating with default action of signal 2 (SIGINT)
==11071== at 0x401EF56: __open_nocancel (open64_nocancel.c:45)
==11071== by 0x40083BA: open_verify.constprop.0 (dl-load.c:1536)
==11071== by 0x4008C15: open_path (dl-load.c:1827)
==11071== by 0x400A7A2: _dl_map_object (dl-load.c:2067)
==11071== by 0x400F504: openaux (dl-deps.c:64)
==11071== by 0x401DCA9: _dl_catch_exception (dl-error-skeleton.c:208)
==11071== by 0x400F952: _dl_map_object_deps (dl-deps.c:248)
==11071== by 0x4004063: dl_main (rtld.c:1805)
==11071== by 0x401CC3A: _dl_sysdep_start (dl-sysdep.c:252)
==11071== by 0x400204B: _dl_start_final (rtld.c:449)
==11071== by 0x400204B: _dl_start (rtld.c:539)
==11071== by 0x4001107: ??? (in /usr/lib/x86_64-linux-gnu/ld-2.31.so)
==11071== Jump to the invalid address stated on the next line
==11071== at 0x1030: ???
==11071== by 0x40083BA: open_verify.constprop.0 (dl-load.c:1536)
==11071== by 0x4008C15: open_path (dl-load.c:1827)
==11071== by 0x400A7A2: _dl_map_object (dl-load.c:2067)
==11071== by 0x400F504: openaux (dl-deps.c:64)
==11071== by 0x401DCA9: _dl_catch_exception (dl-error-skeleton.c:208)
==11071== by 0x400F952: _dl_map_object_deps (dl-deps.c:248)
==11071== by 0x4004063: dl_main (rtld.c:1805)
==11071== by 0x401CC3A: _dl_sysdep_start (dl-sysdep.c:252)
==11071== by 0x400204B: _dl_start_final (rtld.c:449)
==11071== by 0x400204B: _dl_start (rtld.c:539)
==11071== by 0x4001107: ??? (in /usr/lib/x86_64-linux-gnu/ld-2.31.so)
==11071== Address 0x1030 is not stack'd, malloc'd or (recently) free'd
==11071==
==11071==
==11071== Process terminating with default action of signal 11 (SIGSEGV)
==11071== Bad permissions for mapped region at address 0x1030
==11071== at 0x1030: ???
==11071== by 0x40083BA: open_verify.constprop.0 (dl-load.c:1536)
==11071== by 0x4008C15: open_path (dl-load.c:1827)
==11071== by 0x400A7A2: _dl_map_object (dl-load.c:2067)
==11071== by 0x400F504: openaux (dl-deps.c:64)
==11071== by 0x401DCA9: _dl_catch_exception (dl-error-skeleton.c:208)
==11071== by 0x400F952: _dl_map_object_deps (dl-deps.c:248)
==11071== by 0x4004063: dl_main (rtld.c:1805)
==11071== by 0x401CC3A: _dl_sysdep_start (dl-sysdep.c:252)
==11071== by 0x400204B: _dl_start_final (rtld.c:449)
==11071== by 0x400204B: _dl_start (rtld.c:539)
==11071== by 0x4001107: ??? (in /usr/lib/x86_64-linux-gnu/ld-2.31.so)
==11071==
==11071== HEAP SUMMARY:
==11071== in use at exit: 0 bytes in 0 blocks
==11071== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==11071==
==11071== All heap blocks were freed -- no leaks are possible
==11071==
==11071== For lists of detected and suppressed errors, rerun with: -s
==11071== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault
More rare occasion: everything gets handled just fine, SIGINT is propagated:
valgrind ./a
==11070== Memcheck, a memory error detector
==11070== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11070== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==11070== Command: ./a
==11070==
^C==11070==
==11070== Process terminating with default action of signal 2 (SIGINT)
==11070== at 0x4B480A5: write (write.c:26)
==11070== by 0x4AC8EBC: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1181)
==11070== by 0x4ACA980: new_do_write (fileops.c:449)
==11070== by 0x4ACA980: _IO_new_do_write (fileops.c:426)
==11070== by 0x4ACA980: _IO_do_write@@GLIBC_2.2.5 (fileops.c:423)
==11070== by 0x4ACAEC2: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:784)
==11070== by 0x4ACC053: _IO_default_xsputn (genops.c:399)
==11070== by 0x4ACC053: _IO_default_xsputn (genops.c:370)
==11070== by 0x4AC9729: _IO_new_file_xsputn (fileops.c:1265)
==11070== by 0x4AC9729: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
==11070== by 0x4ABD3F0: fwrite (iofwrite.c:39)
==11070== by 0x498B823: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==11070== by 0x498BBDB: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==11070== by 0x1091A3: main (in /home/yeputons/a)
Hello World
==11070==
==11070== HEAP SUMMARY:
==11070== in use at exit: 0 bytes in 0 blocks
==11070== total heap usage: 2 allocs, 2 frees, 73,728 bytes allocated
==11070==
==11070== All heap blocks were freed -- no leaks are possible
==11070==
==11070== For lists of detected and suppressed errors, rerun with: -s
==11070== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I use the default Valgrind from Ubuntu 20.04: valgrind-3.15.0. The behavior happens with all compilers that I have installed: g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, g++-10 (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0, Ubuntu clang version 12.0.0-3ubuntu1~20.04.5, as well as Ubuntu clang version 12.0.0-3ubuntu1~20.04.5 with -stdlib=libc++. I've tested these inside WSL 2, but the same behavior happens on a Linux VPS.
Why does this program crash on Ctrl + C when run in Valgrind? Is there some hidden signal unsafety, presumably in some initialization code?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
