C++ 跟踪断言失败时如何知道调用方函数

C++ 跟踪断言失败时如何知道调用方函数,c++,function,C++,Function,我的问题与此和其他一些问题有关。我想知道调用方函数的名称,因为在断言失败时,我不知道哪个函数将垃圾值传递给被调用方。一种方法是检查所有可以调用此函数的函数,但这非常麻烦 即使依赖于平台,您能否提出更好的解决方案?我正在使用g++4.6。提前感谢。您在glibc中有功能。它可以允许您使用调用者函数或方法进行完整跟踪 如果您只需要呼叫者,则在gcc中也有以下内容: __builtin_frame_address(int level); 使用level==1可以调用调用方函数。有关如何使用它的更多详

我的问题与此和其他一些问题有关。我想知道调用方函数的名称,因为在断言失败时,我不知道哪个函数将垃圾值传递给被调用方。一种方法是检查所有可以调用此函数的函数,但这非常麻烦

即使依赖于平台,您能否提出更好的解决方案?我正在使用g++4.6。提前感谢。

您在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;
}
#包括
#包括
#包括
/*获取回溯并将其打印到标准输出*/
无效的
打印跟踪(无效)
{
void*数组[10];
大小;
字符**字符串;
尺寸i;
大小=回溯(数组,10);
字符串=回溯符号(数组、大小);
printf(“获得%zd堆栈帧。\n”,大小);
对于(i=0;i
请参见
backtrace()

e、 g

见:


您不能在调试器中运行程序以查看堆栈跟踪吗?有许多用例无法执行此操作。我发现还可以方便地发出
回溯
本身(原始指针)的结果。然后,您可以使用
addr2line
命令行实用程序将其转换为实际的源文件名和行号。非常感谢。但是如何获得函数的名称呢?这似乎只打印了一些地址。请原谅我的无知。在字符串[i]中,您有函数名,并且通过另一个链接的dlinfo,它甚至可以向您显示更多信息
#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