简体   繁体   中英

How to print call stack when call stack overflows?

I use the following code to print call stack when catching a signal. But it seems that it doesn't work for stack overflow errors. After some experiments, I find this problem may be caused by the call of backtrace . How can I fix it?

#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;
}

A usual solution to handling stack-overflow caught by a handler is to use very compiler specific code to do backtracking in a loop . In other words, no function calls including printf("signal: %d\\n", sig); .

A precaution limits the amount of back-tracing.

A part of signal_handler() it to handle things differently it a re-entrant signal_handler() is detected. Perhaps use a static int first_time flag.

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;
}

In general, the answer is very compiler dependent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM