6

Is there a way to make GDB stop at named symbols when they reach the top of the stack? I ask because after the stack frame shown in the picture below, the program seems to execute several functions (too many to step through) without symbol information, just addresses, and then crash the executable. If there is any way to automatically stop when the top of stack pushes or pops to any function with any text name, rather than just an address, I'd appreciate being told.

The context is that I am diagnosing a crash that happens in both debug test and release test modes when my signal handler throws an exception inside a BOOST_CHECK_THROW. The signal is triggered by std::raise(SIGFPE), though the type of signal raised does not seem to matter. The crash does not occur in non-test modes, even if I use some complicated tricks to allow the program to signal and throw several times.

example stack trace

//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" 

Debug build commands:

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" 

Release test build commands:

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"

Release build commands:

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"

Release and debug output are identical:

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

Release test and debug test outputs are identical:

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.
Chris Chiasson
  • 547
  • 8
  • 17
  • 1
    I don't know if it will help but see http://stackoverflow.com/q/475283/492336 and http://stackoverflow.com/q/1476002/492336. Maybe you can adapt it to work for all source files in the program. – sashoalm Jun 06 '16 at 13:58

0 Answers0