Как узнать функцию звонящего при прослеживании ошибки утверждения

Мой вопрос связан с этим сообщением SO и некоторыми другими . Я хотел знать имя функции звонящего, так как во время ошибки утверждения я не знаю, какая функция передала значение мусора для вызова. Один из способов - проверить все функции, которые могут вызвать эту функцию, но это очень громоздко.

Можете ли вы предложить лучшее решение, даже если оно зависит от платформы? Я использую g++ 4.6. Спасибо заранее.

Ответ 1

См. backtrace().

например.

#include <execinfo.h>
#include <stdio.h>

void bar() {
  void* callstack[128];
  int i, frames = backtrace(callstack, 128);
  char** strs = backtrace_symbols(callstack, frames);
  for (i = 0; i < frames; ++i) {
    printf("%s\n", strs[i]);
  }
  free(strs);
}

int foo() {
  bar();
  return 0;
}

int main() {
  foo();
  return 0;
}

Вывод:

0   a.out                               0x0000000100000e24 bar + 28
1   a.out                               0x0000000100000e81 foo + 14
2   a.out                               0x0000000100000e96 main + 14
3   a.out                               0x0000000100000e00 start + 52
4   ???                                 0x0000000000000001 0x0 + 1

См:

Как сгенерировать stacktrace при сбое моего приложения gcc С++

Ответ 2

У вас backtrace работает в glibc. Это может позволить вам иметь полную трассировку с функцией или методом вызывающего абонента.

Если вам нужен только вызывающий, конкретные функции в gcc только для этого:

__builtin_frame_address(int level);

С level == 1 у вас есть функция звонящего. См. этот пост для более подробной информации о том, как его использовать.

Вот пример программы, которая находится в документации:

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>

/* Obtain a backtrace and print it to stdout. */
void
print_trace (void)
{
  void *array[10];
  size_t size;
  char **strings;
  size_t i;

  size = backtrace (array, 10);
  strings = backtrace_symbols (array, size);

  printf ("Obtained %zd stack frames.\n", size);

  for (i = 0; i < size; i++)
     printf ("%s\n", strings[i]);

  free (strings);
}

/* A dummy function to make the backtrace more interesting. */
void
dummy_function (void)
{
  print_trace ();
}

int
main (void)
{
  dummy_function ();
  return 0;
}