名称空间中的堆栈跟踪和函数
stacktrace and functions in namespaces
我正在尝试在执行我的(c++)程序的某个点上进行反向跟踪。
对于,我使用了backtrace和backtrace_symbols。像这样:
std::string stacktrace( unsigned int frames_to_skip )
{
std::string str;
void* stack_addrs[50];
int trace_size = backtrace( stack_addrs, 50 );
char** stack_strings = backtrace_symbols( stack_addrs, trace_size );
str += "[bt] backtrace:n";
// skip frames_to_skip stack frames
for( int i = frames_to_skip; i < trace_size; ++i )
{
char tmp[4096];
sprintf( tmp, "[bt] #%d %sn", i-frames_to_skip, stack_strings[i] );
str += tmp;
}
free( stack_strings );
return str;
}
它工作,但一些函数名称丢失。例子:
[bt] #0 /path/to/executable() [0x43e1b5]
[bt] #1 /path/to/executable() [0x43e0cd]
[bt] #2 /path/to/executable() [0x43df51]
[bt] #3 /path/to/executable() [0x43dd44]
[bt] #4 /path/to/executable() [0x43db50]
[bt] #5 /path/to/executable() [0x43d847]
[bt] #6 /path/to/executable() [0x43d216]
[bt] #7 /path/to/executable() [0x43c1e1]
[bt] #8 /path/to/executable() [0x43b293]
[bt] #9 /path/to/executable(_Z29SomeRN5other8symbolE+0x2c) [0x43a6ca]
[bt] #10 /path/to/executable(_Z11SomeIN5_8symbolEPFvRS1_EEvRKT_RKT0_+0x77) [0x441716]
...
函数0到8有一个共同点:它们都位于命名空间中…
我试着把函数9放在一个匿名命名空间中(没有任何其他修改),它从回溯中消失了……现在看起来像这样:
[bt] #0 /path/to/executable() [0x43e1b5]
[bt] #1 /path/to/executable() [0x43e0cd]
[bt] #2 /path/to/executable() [0x43df51]
[bt] #3 /path/to/executable() [0x43dd44]
[bt] #4 /path/to/executable() [0x43db50]
[bt] #5 /path/to/executable() [0x43d847]
[bt] #6 /path/to/executable() [0x43d216]
[bt] #7 /path/to/executable() [0x43c1e1]
[bt] #8 /path/to/executable() [0x43b293]
[bt] #9 /path/to/executable() [0x43a6ca]
[bt] #10 /path/to/executable(_Z11SomeIN5_8symbolEPFvRS1_EEvRKT_RKT0_+0x77) [0x441716]
...
有什么办法可以解决这个问题吗?
注。g++的版本:g++ (GCC) 4.6.0 20110530 (Red Hat 4.6.0-9)
edit修正了Code Monkey注释后回溯的最大深度
edit2添加了函数的完整代码
edit3代码用- 0 -g3编译,用-rdynamic
您的问题可能是您正在使用的函数。"backtrace(..
"中的"max_depth
"设置为"16
"。这可能太低了。无论如何……
这篇关于使用GCC进行c++堆栈跟踪的博文解释了应该如何执行堆栈跟踪。总之,
#include <execinfo.h>
void print_trace(FILE *out, const char *file, int line)
{
const size_t max_depth = 100;
size_t stack_depth;
void *stack_addrs[max_depth];
char **stack_strings;
stack_depth = backtrace(stack_addrs, max_depth);
stack_strings = backtrace_symbols(stack_addrs, stack_depth);
fprintf(out, "Call stack from %s:%d:n", file, line);
for (size_t i = 1; i < stack_depth; i++) {
fprintf(out, " %sn", stack_strings[i]);
}
free(stack_strings); // malloc()ed by backtrace_symbols
fflush(out);
}
GCC还提供对c++名称(de)编辑器的访问。有一些了解内存所有权和接口的一些非常复杂的细节使用堆栈跟踪输出需要一些字符串解析,但是它归结起来就是用下面的代码替换上面的内部循环:
#include <cxxabi.h>
...
for (size_t i = 1; i < stack.depth; i++) {
size_t sz = 200; // just a guess, template names will go much wider
char *function = static_cast(malloc(sz));
char *begin = 0, *end = 0;
// find the parentheses and address offset surrounding the mangled name
for (char *j = stack.strings[i]; *j; ++j) {
if (*j == '(') {
begin = j;
}
else if (*j == '+') {
end = j;
}
}
if (begin && end) {
*begin++ = '';
*end = '';
// found our mangled name, now in [begin, end)
int status;
char *ret = abi::__cxa_demangle(begin, function, &sz, &status);
if (ret) {
// return value may be a realloc() of the input
function = ret;
}
else {
// demangling failed, just pretend it's a C function with no args
std::strncpy(function, begin, sz);
std::strncat(function, "()", sz);
function[sz-1] = '';
}
fprintf(out, " %s:%sn", stack.strings[i], function);
}
else
{
// didn't find the mangled name, just print the whole line
fprintf(out, " %sn", stack.strings[i]);
}
free(function);
}
在这个网站上有更多的信息(我不想逐字复制),但看看这段代码和上面的网站应该让你在正确的轨道上。
你可以尝试在你的链接中添加-rdynamic吗?
http://www.linuxforums.org/forum/programming-scripting/35192-backtrace_symbols-no-symbols.html backtrace
列出了调用帧,这些调用帧对应于机器码call
指令,而不是源级函数调用。
区别在于内联,优化编译器通常可以避免对源代码中的每个逻辑函数调用使用call
指令。
相关文章:
- 提升堆栈跟踪不显示函数名称和行号
- 跟踪递归函数时出现问题
- VC++ 堆栈跟踪不会解析生产环境中的函数名称
- 在遵循 OpenCV 3.4.0 AKAZE 和 ORB 平面跟踪教程时找不到 Points() 函数
- 英特尔针脚跟踪特定函数调用
- 跟踪简单递归函数
- 用于打印函数进入和退出跟踪的宏
- 调试:跟踪(和diffing)同一程序的两个版本的函数调用树
- C++/CLI中重复的析构函数调用和跟踪句柄
- GDB 回溯跟踪不显示带有 cmake 的函数名称
- 如何将 etrace 与动态库结合使用,以按时间顺序跟踪 C++ 中的函数调用
- 在C++中跟踪递归阶乘函数
- 我无法跟踪函数的错误
- 如何跟踪递归函数的调用堆栈使用情况
- C++错误:调用"跟踪::跟踪(字符,字符)"没有匹配函数
- 复制构造函数并通过跟踪对象移动语义
- 如何最好地运行类成员函数并在 main 中跟踪其进度
- 是否有任何标准的Visual Studio 2008插件可用于跟踪/记录C++项目的构造函数和析构函数调用
- C堆栈跟踪中缺少函数调用
- c++中跟踪函数调用的方法