linux用户态程序堆栈打印 - backtrace

        很久之前写的测试代码,研究利用backtrace配合addr2line打印用户态进程堆栈信息(•̀⌄•́)

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <string.h>

#define EXCMD			"addr2line -p -f -e ./test "
#define TESTINT			18888
#define _PRT(x)			#x
#define PRT(x)			_PRT(x)

void myfunc3(void)
{
	int j, nptrs;
#define SIZE 100
	void *buffer[100];
	char **strings;
	FILE *fp;

	printf("### " PRT(TESTINT) " ###\n");
	nptrs = backtrace(buffer, SIZE);
	printf("backtrace() returned %d addresses\n", nptrs);

	/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
	 * would produce similar output to the following: */

	strings = backtrace_symbols(buffer, nptrs);
	if (strings == NULL) {
		perror("backtrace_symbols");
		exit(EXIT_FAILURE);
	}

	void *leftpos = NULL, *rightpos = NULL;
	char cmd[512] = EXCMD, line[1024] = {0};
	for (j = 0; j < nptrs; j++){
		if (NULL == (void *)memmem(strings[j], strlen(strings[j]), "libc.so.6", strlen("libc.so.6"))){
			leftpos = memchr(strings[j], '[', strlen(strings[j]));
			rightpos = memchr(leftpos, ']', strlen(strings[j]) - ((char *)leftpos - strings[j]));
			strncat(cmd, (char *)(leftpos+1), (char *)rightpos-(char *)leftpos-1);
//			snprintf(cmd+strlen(cmd), rightpos-leftpos, leftpos+1);
			fp = popen(cmd, "r");
			while (fgets(line, 1024, fp) != NULL){
				printf("level: %d,  %s", j, line);
			}
			pclose(fp);
			strcpy(cmd, EXCMD);
		}
		else{
			printf("level: %d,  %s\n", j, strings[j]);
		}
	}

	free(strings);
#undef SIZE

	return;
}

static void myfunc2(void)
{
	myfunc3();
}

void myfunc(int ncalls)
{
	if (ncalls > 1)
		myfunc(ncalls - 1);
	else
		myfunc2();
}

int main(int argc, char *argv[])
{
	if (argc != 2) {
		fprintf(stderr, "%s num-calls\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	myfunc(atoi(argv[1]));
//	exit(EXIT_SUCCESS);

	return 0;
}

        addr2line可以将函数地址转换成易读的文件名、函数名和源代码行数等信息便于定位,EXCMD中定义的test即测试程序的名称,更好的方法是直接解析/proc/self/comm来获取当前进程的可执行文件名称。函数功能也很简单,堆栈打印实现在myfunc3函数中,就不做展开了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值