如何打印堆栈

2023-04-11 15:05:14

一、打印堆栈可以方便问题定位,找到具体的函数调用流程。

二、打印堆栈的方法

2.1、用户态

#include <stdio.h>
#include <stdlib.h> 
#include <stddef.h> 
#include <execinfo.h> 

#define DUMP_DEPTH	20

void dump(void) 
{ 
	int 	i 		= 0;
	size_t 	size	= 0;
	char **strings 	= NULL;
    void *buffer[DUMP_DEPTH] = {0};

    size = backtrace(buffer, DUMP_DEPTH);
    printf("get %zd stack frames\n", size);
    strings = backtrace_symbols(buffer, size);
    if (strings == NULL)
    {
        printf("backtrace_symbols error.");
        exit(-1);
    }

    for (i = 0; i < size; i++)
    {
        printf("%s\n", strings[i]);
    }
	
    free(strings);
    strings = NULL;
	
    exit(0);
}

void func_c()
{
	dump();
}

void func_b()
{
	func_c();
}

void func_a()
{
	func_b();
}

int main(int argc, const char *argv[])
{
	func_a();
	
	return 0;
}

运行结果

看不到具体的函数名调用关系,不用紧,可以使用addr2line解析出函数名,具体参考

https://blog.csdn.net/sydyh43/article/details/119487171 的4.2部分

PS:应用层coredump实现方式,创建SIGSEGV信号对应信号处理函数为dump,如:

signal(SIGSEGV, dump)

2.2、内核态

#include <linux/stacktrace.h>

#define BKTRACE_DEPTH        20

void print_stack(void)
{
	unsigned long backtrace[BKTRACE_DEPTH];
	struct stack_trace trace;

	memset(&trace, 0, sizeof(trace));
	memset(backtrace, 0, BKTRACE_DEPTH * sizeof(unsigned long));
	trace.max_entries = BKTRACE_DEPTH;
	trace.entries = backtrace;

//	save_stack_trace_tsk(ptask, &trace);	//指定task = pstak
	save_stack_trace(&trace);				//默认的task是current

	print_stack_trace(&trace, 0);
}

上面的实现方式堆栈深度可以按自己需求设置,其中默认堆栈深度,使用方法更方便。直接在需要的函数内插入下面的代码

dump_stack();
  • 作者:sydyh43
  • 原文链接:https://blog.csdn.net/sydyh43/article/details/119707079
    更新时间:2023-04-11 15:05:14