有没有办法让GDB在到达堆栈顶部时停止在命名符号处?我问,因为在下图所示的堆栈帧之后,程序似乎执行了几个函数(太多不能逐步执行)而没有符号信息,只有地址,然后崩溃可执行文件。如果有任何方法在堆栈顶部推送或弹出任何带有任何文本名称的函数时自动停止,而不仅仅是一个地址,我很感激被告知。
上下文是当我的信号处理程序在BOOST_CHECK_THROW
内抛出异常时,我正在诊断在调试测试和发布测试模式下发生的崩溃。信号由std::raise(SIGFPE)
触发,尽管所提出的信号类型似乎并不重要。在非测试模式下不会发生崩溃,即使我使用一些复杂的技巧来让程序发出信号并多次抛出。
//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
调试测试构建命令:
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"
调试构建命令:
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"
发布测试构建命令:
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"
发布构建命令:
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"
发布和调试输出完全相同:
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
发布测试和调试测试输出完全相同:
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.