Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know caller function when tracing assertion failure

Tags:

c++

function

My question is related to this SO post and some others alike. I wanted to know the name of caller function, since at the time of assertion failure, I don't know which function passed a garbage value to callee. One method is to put check in all the functions which could call this function, but that is very cumbersome.

Can you suggest a better solution, even though platform-dependent? I am using g++ 4.6. Thanks in advance.

like image 787
user984260 Avatar asked Mar 04 '12 14:03

user984260


2 Answers

See backtrace().

e.g.

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

Output:

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

See:

How to generate a stacktrace when my gcc C++ app crashes

like image 103
Manish Avatar answered Nov 15 '22 19:11

Manish


You have backtrace functions in glibc. It can allow you to have full trace, with the caller function or method.

If you only want the caller, there's also specific functions in gcc just for this :

__builtin_frame_address(int level);

With level == 1 you have the caller function. See this post for more detail about how to use it.

Here is the sample program which is in the documentation :

#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;
}
like image 38
Coren Avatar answered Nov 15 '22 19:11

Coren