本帖最后由 古月不傲 于 2021-1-13 01:00 编辑
[C++] 纯文本查看 复制代码 #include <iostream>
#include <string>
#include <cxxabi.h>
#include <execinfo.h>
void bb();
void cc();
// 输出函数回朔过程,并以C函数名的风格显示
std::string stackTrace(bool demangle)
{
std::string stack;
const int max_frames = 250;
void *frame[max_frames];
// 第一个参数,返回的回朔地址缓存区
// 第二个参数,要容纳多少个地址
// 返回值,栈帧编号,表示第几个函数
int nptrs = backtrace(frame, max_frames);
// 第一个参数,已经接收到的回朔地址缓存区
// 第二个参数,接收到的栈帧编号
char** strings = backtrace_symbols(frame, nptrs);
if (strings)
{
size_t len = 256;
// 分配内存
char* demangled = demangle ? static_cast<char*>(::malloc(len)) : nullptr;
// 解析每个地址成字符串
for (int i = 1; i < nptrs; ++i) // skipping the 0-th, which is this function
{
if (demangle)
{
char* left_par = nullptr;
char* plus = nullptr;
// 解析每个字符 找到( + 号的位置
for (char* p = strings[i]; *p; ++p)
{
if (*p == '(')
left_par = p;
else if (*p == '+')
plus = p;
}
// ( && +
if (left_par && plus)
{
*plus = '\0'; // 将函数名后面的 +号先清0 以便截取函数名
int status = 0;
// 将函数名翻译成C语言风格
char* ret = abi::__cxa_demangle(left_par+1, demangled, &len, &status);
*plus = '+'; // 重新设置 +号
if (status == 0)
{
demangled = ret; // ret could be realloc()
// 追加到statck strings.start -- "(+1"
stack.append(strings[i], left_par+1);
// 追加函数名称
stack.append(demangled);
// 追加函数名称之后的部分,一直到\0
stack.append(plus);
// 添加换行
stack.push_back('\n');
continue;
}
}
}
// Fallback to mangled names
stack.append(strings[i]);
stack.push_back('\n');
}
free(demangled);
free(strings);
}
return stack;
}
void a()
{
bb();
}
void dd()
{
printf("%s\n", stackTrace(true).c_str());
}
void bb()
{
int size = 200;
void *buf[200]{};
int c = backtrace(buf, 200);
char **str = backtrace_symbols(buf, c);
for (int i = 0; i < c; i++)
printf("%s\n", str[i]);
free(str);
cc();
}
void cc()
{
printf("%s\n", stackTrace(true).c_str());
dd();
}
int main()
{
a();
return 0;
}
编译时加上: -rdynamic |