这不简单。确切的解决方案在很大程度上取决于操作系统和执行环境。
打印堆栈通常并不难,但查找符号可能非常棘手,因为这通常意味着读取调试符号。
另一种方法是使用侵入式方法并向每个函数添加一些“我在哪里”类型的代码(大概是“仅用于调试构建”):
#ifdef DEBUG
struct StackEntry
{
const char *file;
const char *func;
int line;
StackEntry(const char *f, const char *fn, int ln) : file(f), func(fn), line(ln) {}
};
std::stack<StackEntry> call_stack;
class FuncEntry
{
public:
FuncEntry(const char *file, const char *func, int line)
{
StackEntry se(file, func, line);
call_stack.push_back(se);
}
~FuncEntry()
{
call_stack.pop_back();
}
void DumpStack()
{
for(sp : call_stack)
{
cout << sp->file << ":" << sp->line << ": " << sp->func << "\n";
}
}
};
#define FUNC() FuncEntry(__FILE__, __func__, __LINE__);
#else
#define FUNC()
#endif
void somefunction()
{
FUNC();
... more code here.
}
我过去使用过这种技术,但我只是输入了这段代码,它可能无法编译,但我认为它已经足够清晰了。一个主要的好处是您不必将它放在每个功能中 - 只是“重要的”。[您甚至可以FUNC
根据不同的调试级别启用或禁用不同类型的宏]。