C++ 调用堆栈溢出时如何打印调用堆栈?
捕获信号时,我使用以下代码打印调用堆栈。但它似乎不适用于堆栈溢出错误。经过一些实验,我发现这个问题可能是由调用C++ 调用堆栈溢出时如何打印调用堆栈?,c++,c,debugging,stack-overflow,C++,C,Debugging,Stack Overflow,捕获信号时,我使用以下代码打印调用堆栈。但它似乎不适用于堆栈溢出错误。经过一些实验,我发现这个问题可能是由调用backtrace引起的。我怎样才能修好它 #include <stdlib.h> #include <stdio.h> #include <execinfo.h> #include <signal.h> void signal_handler(int sig) { printf("signal: %d\n", sig); vo
backtrace
引起的。我怎样才能修好它
#include <stdlib.h>
#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
void signal_handler(int sig)
{
printf("signal: %d\n", sig);
void* dump_array[256];
int num = backtrace(dump_array, 256);
if (num)
{
printf("backtrace rank = %d\n", num);
char** symbols = backtrace_symbols(dump_array, num);
if (symbols)
{
for (int i = 0; i < num; i++)
printf("%s\n", symbols[i]);
free(symbols);
}
}
exit(-1);
}
void func()
{
func();
}
int main(void)
{
stack_t ss = {};
ss.ss_size = SIGSTKSZ;
if (!(ss.ss_sp = malloc(SIGSTKSZ)))
{
perror("malloc");
exit(-1);
}
if (sigaltstack(&ss, NULL) == -1)
{
perror("sigaltstack");
exit(-1);
}
struct sigaction act = {};
act.sa_handler = signal_handler;
act.sa_flags = SA_ONSTACK;
sigfillset(&act.sa_mask);
if (sigaction(SIGSEGV, &act, NULL) == -1)
perror("sigaction");
*(int*)123 = 456; // works
//func(); // doesn't work
return 0;
}
#包括
#包括
#包括
#包括
无效信号处理器(int sig)
{
printf(“信号:%d\n”,sig);
void*dump_数组[256];
int num=回溯(转储数组,256);
if(num)
{
printf(“回溯秩=%d\n”,num);
字符**符号=回溯符号(转储数组,num);
if(符号)
{
for(int i=0;i
处理程序捕获的堆栈溢出的常用解决方案是使用特定于编译器的代码在循环中执行回溯。换句话说,没有函数调用包括printf(“信号:%d\n”,sig)代码>
预防措施限制了回溯的数量
signal\u handler()。也许第一次使用静态int
标志
void signal_handler(int sig) {
static int first_time = 0;
if (first_time == 0) {
first_time++;
for (int i = 0; i<max; i++) {
... // gather back trace data
}
}
... // save exit into some place
exit -1;
}
void信号处理器(int-sig){
静态int首次_时间=0;
如果(第一次=0){
第一次++;
对于(int i=0;i当堆栈溢出时,任何函数都很难正常工作,因为大多数函数都使用局部变量,没有任何堆栈空间,这些局部变量就没有安全的位置!但我使用了sigaltstack
来设置信号处理程序的堆栈。@MartinJames伟大的头脑和inte的想法一样表面问题。