I have a simple reproducer. Eliminating cppunit from enquires:
#include <cstdlib>
#include <cstdarg>
#include <fstream>
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <vector>
namespace
{
void appendArgv(
std::vector< char * > &argv,
va_list *ap
)
{
char *arg = 0;
do
{
arg = va_arg(*ap, char *);
argv.push_back(arg);
}
while (arg != 0);
}
void wrapexecl(const char *path, const char *arg0, ...)
{
std::vector< char * > argv;
va_list ap;
va_start(ap, arg0);
appendArgv(argv, &ap);
va_end(ap);
static const char* funName = "execl()";
execve(path, &*argv.begin(), ::environ);
}
void testExeclGood1()
{
std::cerr.flush();// prevent double write on error
pid_t p;
if (0 == (p = ::fork()))
{// we are the child
try
{
::wrapexecl("/bin/true", "true", NULL);// should not return or throw
}
catch (const std::exception &e)
{
std::cerr << e.what() << std::endl;
std::exit(1);
}
catch (...)
{
std::exit(1);
}
std::exit(2);
}
else
{// we are the parent
int status = 0;
::waitpid(p, &status, 0);
}
};
}
int main (int argc, const char* argv[])
{
testExeclGood1();
return 0;
}
gcc -x c++ -std=c++17 -O0 -g3 -fprofile-arcs -ftest-coverage -o breaksonar breaksonar.cpp -lstdc++ &&
gdb ./target/sonar/build-wrapper-linux-x86/build-wrapper-linux-x86-64 <<EOF
run --out-dir bw-debug ./breaksonar
where
q
EOF
[Detaching after fork from child process 2428097]
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
Program received signal SIGABRT, Aborted.
0x00007ffff7a4237f in raise () from /usr/lib64/libc.so.6
(gdb) #0 0x00007ffff7a4237f in raise () from /usr/lib64/libc.so.6
#1 0x00007ffff7a2cdb5 in abort () from /usr/lib64/libc.so.6
#2 0x00005555555cf08e in __gnu_cxx::__verbose_terminate_handler() [clone .cold] ()
#3 0x00005555555ddc5c in __cxxabiv1::__terminate(void (*)()) ()
#4 0x00005555555ddcc7 in std::terminate() ()
#5 0x00005555555dde29 in __cxa_throw ()
#6 0x00005555555d050b in std::__throw_logic_error(char const*) ()
#7 0x00005555555d6bec in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) ()
#8 0x00005555555d6aec in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char const*>(char const*, char const*, std::__false_type) ()
#9 0x00005555555d6983 in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*) ()
#10 0x00005555555d6565 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&) ()
#11 0x00005555555d373a in bwrapper::handleCapture(std::basic_ofstream<char, std::char_traits<char> >&, Capture&) ()
#12 0x00005555555d3ce7 in bwrapper::collectCaptures(int) ()
#13 0x00005555555d5ac0 in bwrapper::work(int, char* const*, char* const*) ()
#14 0x00005555555d1c95 in main ()
(gdb) A debugging session is active.
Inferior 1 [process 2428091] will be killed.