gpt4 book ai didi

c - Ubuntu 20.04 之后可以使用 addr2line 吗?

转载 作者:行者123 更新时间:2023-12-05 06:51:21 24 4
gpt4 key购买 nike

最近,我试图在 gcc 使用标志 -finstrument-functions 编译后使用 addr2line。示例代码可在 link 中找到而我的结果完全不同。 (得到不好的结果:??:0)

预期结果是:

$ ./readtracelog.sh main trace.out
Enter main at 2010-10-06T15:35:53+0200, called from ?? (??:0)
Enter foo at 2010-10-06T15:35:53+0200, called from main (main.c:9)
Exit foo at 2010-10-06T15:35:53+0200
Exit main at 2010-10-06T15:35:53+0200

我的结果是:

Enter ?? at 2021-02-13T15:35:56+08:00, called from ?? (??:0)
Enter ?? at 2021-02-13T15:35:56+08:00, called from ?? (??:0)
Exit ?? at 2021-02-13T15:35:56+08:00
Exit ?? at 2021-02-13T15:35:56+08:00

完整代码如下:

主.c:

#include <stdio.h>

void foo() {
printf("foo\n");
}

int main() {

foo();

return 0;
}

跟踪.c:

#include <stdio.h>
#include <time.h>

static FILE *fp_trace;

void
__attribute__ ((constructor))
trace_begin (void)
{
fp_trace = fopen("trace.out", "w");
}

void
__attribute__ ((destructor))
trace_end (void)
{
if(fp_trace != NULL) {
fclose(fp_trace);
}
}

void
__cyg_profile_func_enter (void *func, void *caller)
{
if(fp_trace != NULL) {
fprintf(fp_trace, "e %p %p %lu\n", func, caller, time(NULL) );
}
}

void
__cyg_profile_func_exit (void *func, void *caller)
{
if(fp_trace != NULL) {
fprintf(fp_trace, "x %p %p %lu\n", func, caller, time(NULL));
}
}

构建:

$ gcc -finstrument-functions -g -c -o main.o main.c
$ gcc -c -o trace.o trace.c
$ gcc main.o trace.o -o main
$ ./main
foo
$ cat trace.out
e 0x400679 0x394281c40b 1286372153
e 0x400648 0x40069a 1286372153
x 0x400648 0x40069a 1286372153
x 0x400679 0x394281c40b 1286372153

使用脚本:

#!/bin/sh
if test ! -f "$1"
then
echo "Error: executable $1 does not exist."
exit 1
fi
if test ! -f "$2"
then
echo "Error: trace log $2 does not exist."
exit 1
fi
EXECUTABLE="$1"
TRACELOG="$2"
while read LINETYPE FADDR CADDR CTIME; do
FNAME="$(addr2line -f -e ${EXECUTABLE} ${FADDR}|head -1)"
CDATE="$(date -Iseconds -d @${CTIME})"
if test "${LINETYPE}" = "e"
then
CNAME="$(addr2line -f -e ${EXECUTABLE} ${CADDR}|head -1)"
CLINE="$(addr2line -s -e ${EXECUTABLE} ${CADDR})"
echo "Enter ${FNAME} at ${CDATE}, called from ${CNAME} (${CLINE})"
fi
if test "${LINETYPE}" = "x"
then
echo "Exit ${FNAME} at ${CDATE}"
fi
done < "${TRACELOG}"

我的内核版本是 5.9.12-050912-genericgcc 版本是 9.3.0

最佳答案

addr2line 没有出现问题。相反,我们需要将绝对地址转换为相对地址。以下是需要更改为的代码:

__cyg_profile_func_enter (void *func,  void *caller)
{
if(fp_trace != NULL) {
Dl_info a, b;
struct link_map* link_mapa;
struct link_map* link_mapb;
dladdr1((void*)func,&a,(void**)&link_mapa,RTLD_DL_LINKMAP);
dladdr1((void*)caller,&b,(void**)&link_mapb,RTLD_DL_LINKMAP);
fprintf(fp_trace, "e %p %p %lu\n", func-link_mapa->l_addr, caller-link_mapb->l_addr, time(NULL) );
}
}

关于c - Ubuntu 20.04 之后可以使用 addr2line 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66182747/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com