• addr2line 回复“问号”问题的解决和一些发现


    我在尝试使用LTTng的prebuilt user space tracing helper来自动插入trace point来监控函数的进出。

    这一套东西的原理是利用gcc 的-finstrument-functions参数,在函数的进出口插入hook,动态链接到liblttng-ust-cyg-profile.so来提供被hook的代码用来发射event。

    在记录的trace log 的field里。是以地址的形式记录进出口位置。
    例如:

    [17:58:51.390638416] (+0.000000542) PC lttng_ust_cyg_profile:func_exit: { cpu_id = 9 }, { addr = 0x5609DC20A642, call_site = 0x5609DC20ACA6 }
    [17:58:51.390639034] (+0.000000618) PC lttng_ust_cyg_profile:func_entry: { cpu_id = 9 }, { addr = 0x5609DC20A1A4, call_site = 0x5609DC20ACB6 }
    [17:58:51.390639560] (+0.000000526) PC lttng_ust_cyg_profile:func_exit: { cpu_id = 9 }, { addr = 0x5609DC20A1A4, call_site = 0x5609DC20ACB6 }
    
    
    • 1
    • 2
    • 3
    • 4

    如果需要知道调用的是哪个函数,需要将地址翻译成符号名。用到addr2line

    下面出现了惊喜一幕:

    >>addr2line 0x5609DC20A1A4  -e tp_test -f -s -C
    回复:
    >>??
    >>??:0
    
    • 1
    • 2
    • 3
    • 4

    经过一番研究,发现需要添加几个编译链接参数,可解决问题:

    • -g
      编译时加-g,可以在文件中保留调试信息。

    *-rdynamic
    链接时 添加 - rdynamic 用来通知链接器将所有符号添加到动态符号表中。

    *-no-pie

    What version of addr2line do you use? – 
    ssbssa
     Dec 9, 2021 at 11:24
    @ssbssa I'm using addr2line 2.34. – 
    ChrisZZ
     Dec 9, 2021 at 11:36
    Now I see the problem, the newer executable has ASLR enabled, that's why the addresses are so high (0x55baa10213f1). So the debug information in the executable uses a different base address than the actual running executable. – 
    ssbssa
     Dec 9, 2021 at 12:04
    @ssbssa I'm now even more confused.. How can I disable ASLR temporarily for gcc? I tried gcc -fno-stack-protector -z execstack but not working. – 
    ChrisZZ
     Dec 9, 2021 at 12:45
    Try compiling with -no-pie. – 
    ssbssa
     Dec 9, 2021 at 13:43
    @ssbssa Thank you! Actually before asking this question I tried with adding -fno-pie but didn't work. Now with full command ` gcc -g -rdynamic -no-pie x.c` it works! – 
    ChrisZZ
     Dec 10, 2021 at 0:59
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    高版本的GCC 默认使用了ASLR,ASLR(Address space layout randomization)是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的。

    这个也许是问题的根源。

    在链接中加入-no-pie来关闭PIE,来解决问题。我这里在编译和链接都加上了-no-pie。因为只在编译处加上似乎没有解决问题。

    结果:

    [17:58:51.390636664] (+0.000000529) PC lttng_ust_cyg_profile:func_exit: { cpu_id = 9 }, { addr = 0x5609DC20B191, call_site = 0x5609DC20AB02 }
    [17:58:51.390637270] (+0.000000606) PC lttng_ust_cyg_profile:func_exit: { cpu_id = 9 }, { addr = 0x5609DC20AAD2, call_site = 0x5609DC20AC96 }
    [17:58:51.390637874] (+0.000000604) PC lttng_ust_cyg_profile:func_entry: { cpu_id = 9 }, { addr = 0x5609DC20A642, call_site = 0x5609DC20ACA6 }
    [17:58:51.390638416] (+0.000000542) PC lttng_ust_cyg_profile:func_exit: { cpu_id = 9 }, { addr = 0x5609DC20A642, call_site = 0x5609DC20ACA6 }
    [17:58:51.390639034] (+0.000000618) PC lttng_ust_cyg_profile:func_entry: { cpu_id = 9 }, { addr = 0x5609DC20A1A4, call_site = 0x5609DC20ACB6 }
    [17:58:51.390639560] (+0.000000526) PC lttng_ust_cyg_profile:func_exit: { cpu_id = 9 }, { addr = 0x5609DC20A1A4, call_site = 0x5609DC20ACB6 }
    [17:58:51.390653259] (+0.000013699) PC lttng_ust_cyg_profile:func_entry: { cpu_id = 0 }, { addr = 0x404BF8, call_site = 0x403E48 }
    [17:58:51.390654040] (+0.000000781) PC lttng_ust_cyg_profile:func_entry: { cpu_id = 0 }, { addr = 0x40480B, call_site = 0x404C30 }
    [17:58:51.390654617] (+0.000000577) PC lttng_ust_cyg_profile:func_entry: { cpu_id = 0 }, { addr = 0x404341, call_site = 0x40483F }
    [17:58:51.390655219] (+0.000000602) PC lttng_ust_cyg_profile:func_exit: { cpu_id = 0 }, { addr = 0x404341, call_site = 0x40483F }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    因为我的程序链接了so库,所以可能库里的地址仍为随机地址,但是本程序中已经变为了可以使用的地址。

    再尝试一次:

    $ addr2line 0x404190  -e tp_test -f -s -C
    std::chrono::duration<long, std::ratio<1l, 1000000000l> >::count() const
    chrono:346
    
    • 1
    • 2
    • 3

    最后说一下lttng相关的:

    Compile your application with compiler option -finstrument-functions.
    
    Launch your application by preloading liblttng-ust-cyg-profile-fast.so for fast function tracing:
    
    $ LD_PRELOAD=liblttng-ust-cyg-profile-fast.so my-app
    Launch your application by preloading liblttng-ust-cyg-profile.so for slower, more verbose function tracing:
    
    $ LD_PRELOAD=liblttng-ust-cyg-profile.so my-app
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    图像旋转、平移、缩放变换矩阵计算及案例
    Linux非阻塞等待示例
    强化游戏产业发展 新疆文化和旅游厅代表赴粤交流考察
    5-2Web应用程序漏洞扫描
    【kerberos】使用 curl 访问受 Kerberos HTTP SPNEGO 保护的 URL
    【linux命令讲解大全】014.Git:分布式版本控制系统的先驱和常用命令清单(三)
    【JavaEE&Spring】认识Spring
    利用API数据接口进行市场调研的详细指南
    【JDBC笔记】向数据表中插入Blob类型数据
    人脸活体检测技术的应用,有效避免人脸识别容易被攻击的缺陷
  • 原文地址:https://blog.csdn.net/kuno_y/article/details/125545762