c++ - Eclipse GDB se rompe cuando la función/símbolo con nombre llega a la parte superior de la pila
mingw-w64 boost-test (0)
¿Hay alguna manera de hacer que GDB se detenga en los símbolos nombrados cuando alcanzan la parte superior de la pila? Lo pregunto porque después del marco de pila que se muestra en la imagen siguiente, el programa parece ejecutar varias funciones (demasiadas para pasar) sin información de símbolos, solo direcciones, y luego bloquear el ejecutable. Si hay alguna manera de detenerse automáticamente cuando la parte superior de la pila empuja o aparece en cualquier función con cualquier nombre de texto, en lugar de solo una dirección, agradecería que me lo dijeran.
El contexto es que estoy diagnosticando un bloqueo que ocurre tanto en la prueba de depuración como en los modos de prueba de lanzamiento cuando mi manejador de señal arroja una excepción dentro de BOOST_CHECK_THROW
. La señal se activa con std::raise(SIGFPE)
, aunque el tipo de señal no parece importar. El bloqueo no ocurre en modos que no son de prueba, incluso si uso algunos trucos complicados para permitir que el programa señale y arroje varias veces.
//common includes
#include <chrono> // s
#include <csetjmp> // jmp_buf, longjmp, setjmp
#include <csignal> // raise, signal
#include <cstdlib> // set_terminate
#include <iostream> // cout
#include <stdexcept> // exception, runtime_error
#include <string> // string, to_string
#include <thread> // sleep_for
namespace {
void sig_handler(int sig){
std::signal(sig,SIG_DFL);
std::signal(sig,sig_handler);
throw std::runtime_error(std::string("Caught signal: ") +
std::to_string(sig) + "/n");
}
void install_sig_handler(){std::signal(SIGFPE,sig_handler);} //add signals here
struct sig{sig(){install_sig_handler();}};
} //anonymous namespace
#ifndef TEST //non-test build functions, global setup, and main
std::jmp_buf buffer;
volatile int count(0);
void oops(volatile int& count){ // can return before signal is handled
std::cout<<"oops(int&) call number "<< ++count <<"; about to raise SIGFPE: "
<<SIGFPE<<"/n";
std::raise(SIGFPE);
}
void uncaught_exception_handler(){
static bool tried_throw = false;
try {if(!tried_throw++) throw;} // get access to active exception
catch(std::exception const& err){std::cerr<<err.what();} // print error content
catch(...){std::cerr<<"Non-standard exception thrown./n";}
//std::_Exit(1) // don''t exit; demonstrate signal throw repeatability instead
tried_throw=false;
std::longjmp(buffer,count); // return to main
}
int main(int /*argc*/,char */*argv*/[]){
//CRANE::Process::get_instance(argv[0]).execute();
sig my_sig; //install_sig_handler() is ok instead
std::set_terminate(&uncaught_exception_handler);
if (setjmp(buffer)<10) oops(count);
return 0;
}
#else // test configuration
void testable_oops(){ // unlikely to return before signal is handled
std::cout<<"testable_oops() about to raise SIGFPE: "<<SIGFPE<<"/n";
std::raise(SIGFPE);
using namespace std::chrono_literals;
std::this_thread::sleep_for(2s);
}
#define BOOST_TEST_MODULE CRANETest
#include <boost/test/included/unit_test.hpp>
BOOST_GLOBAL_FIXTURE(sig);
BOOST_AUTO_TEST_SUITE(ProcessTest)
BOOST_AUTO_TEST_CASE(RegularException){
BOOST_CHECK_THROW(throw std::runtime_error("blah"),std::exception);
}
BOOST_AUTO_TEST_CASE(SignalConvertedToException) {
BOOST_CHECK_THROW(testable_oops(),std::exception);
}
BOOST_AUTO_TEST_SUITE_END()
#endif
Debug test build commands:
g++ -std=c++1z -DTEST "-IC://boost//boost_1_61_0" -O0 -Og -g3 -pedantic -pedantic-errors -Wall -Wextra -Werror -c -fmessage-length=0 "-isystemC://boost//boost_1_61_0" -o "src//temp.o" "..//src//temp.cpp"
g++ -o temp.exe "src//temp.o"
Comandos de compilación de depuración:
g++ -std=c++1z "-IC://boost//boost_1_61_0" -O0 -Og -g3 -pedantic -pedantic-errors -Wall -Wextra -Werror -c -fmessage-length=0 "-isystemC://boost//boost_1_61_0" -o "src//temp.o" "..//src//temp.cpp"
g++ -o temp.exe "src//temp.o"
Lanzar comandos de compilación de prueba:
g++ -std=c++1z -DTEST "-IC://boost//boost_1_61_0" -O3 -pedantic -pedantic-errors -Wall -Wextra -Werror -c -fmessage-length=0 "-isystemC://boost//boost_1_61_0" -o "src//temp.o" "..//src//temp.cpp"
g++ -o temp.exe "src//temp.o"
Liberar comandos de compilación:
g++ -std=c++1z "-IC://boost//boost_1_61_0" -O3 -pedantic -pedantic-errors -Wall -Wextra -Werror -c -fmessage-length=0 "-isystemC://boost//boost_1_61_0" -o "src//temp.o" "..//src//temp.cpp"
g++ -o temp.exe "src//temp.o"
La versión y la salida de depuración son idénticas:
C:/Users/chris.chiasson/Files/temp>./Debug/temp.exe
oops(int&) call number 1; about to raise SIGFPE: 8
Caught signal: 8
oops(int&) call number 2; about to raise SIGFPE: 8
Caught signal: 8
oops(int&) call number 3; about to raise SIGFPE: 8
Caught signal: 8
oops(int&) call number 4; about to raise SIGFPE: 8
Caught signal: 8
oops(int&) call number 5; about to raise SIGFPE: 8
Caught signal: 8
oops(int&) call number 6; about to raise SIGFPE: 8
Caught signal: 8
oops(int&) call number 7; about to raise SIGFPE: 8
Caught signal: 8
oops(int&) call number 8; about to raise SIGFPE: 8
Caught signal: 8
oops(int&) call number 9; about to raise SIGFPE: 8
Caught signal: 8
oops(int&) call number 10; about to raise SIGFPE: 8
Caught signal: 8
Las pruebas de liberación y las salidas de prueba de depuración son idénticas:
C:/Users/chris.chiasson/Files/temp>"./Release Test/temp.exe"
Running 2 test cases...
testable_oops() about to raise SIGFPE: 8
terminate called after throwing an instance of ''std::runtime_error''
what(): Caught signal: 8
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application''s support team for more information.