输出函数调用过程
本帖最后由 古月不傲 于 2021-1-13 01:00 编辑#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;
// 第一个参数,返回的回朔地址缓存区
// 第二个参数,要容纳多少个地址
// 返回值,栈帧编号,表示第几个函数
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; *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()
// 追加到statckstrings.start -- "(+1"
stack.append(strings, left_par+1);
// 追加函数名称
stack.append(demangled);
// 追加函数名称之后的部分,一直到\0
stack.append(plus);
// 添加换行
stack.push_back('\n');
continue;
}
}
}
// Fallback to mangled names
stack.append(strings);
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{};
int c = backtrace(buf, 200);
char **str = backtrace_symbols(buf, c);
for (int i = 0; i < c; i++)
printf("%s\n", str);
free(str);
cc();
}
void cc()
{
printf("%s\n", stackTrace(true).c_str());
dd();
}
int main()
{
a();
return 0;
}
编译时加上: -rdynamic 说个实话,我是把一本基础C的书看完了 为什么看不懂你的代码!看不我不适合编程 z1991627 发表于 2021-1-13 08:25
说个实话,我是把一本基础C的书看完了 为什么看不懂你的代码!看不我不适合编程
这个好像是c++我也不会? 本帖最后由 古月不傲 于 2021-1-13 12:46 编辑
z1991627 发表于 2021-1-13 08:25
说个实话,我是把一本基础C的书看完了 为什么看不懂你的代码!看不我不适合编程
这是muduo库的源码,主要用于异常回朔,看不懂可能是你没静下心,或者你的基础不够,还不能阅读第三方的源码。
这里面无非就用到了三个函数,加点指针的东西,静下心,一般都能看懂。
页:
[1]