[√]leak tracer的stack address始终无法被addr2line识别

简介: [√]leak tracer的stack address始终无法被addr2line识别

感谢文章:blog.csdn.net/tq08g2z/art…

使用适配过Android的leak tracer,不要使用官方的。我自己写的测试demo

注意

尽量将leak tracer编译到要检测内存泄露模块的动态库中,不要单独将leak tracer编译为一个so动态库,否则会导致addr2line无法正确识别出地址符号。

LeakTracer使用教程

在Android平台上检测内存泄露,最终选择使用leak tracer。

通过leak traker,收集到leak结果如下:

# LeakTracer report diff_utc_mono=1685323259.020343
leak, time=1562403.055277, stack=0x7921948b54 0x7921948de4 0x7921c80e00 0x7923f99460 0x792433eee0, size=10485760, data=..................................................
leak, time=1562403.055280, stack=0x7921948b54 0x7921948de4 0x7921c83df4 0x7921c81dc8 0x7921c839e0, size=8, data=....y...

使用addr2line还原调试符号

很明显,我们看到stack都是符号地址,需要通过addr2line工具还原详细的信息

llvm-addr2line.exe -C -f -e libjni.so 0x7921948b54

建议使用ndk版本对应的addr2line,不过我发现其他版本的也可以,比如我使用的是:

ndk\23.1.7779620\toolchains\llvm\prebuilt\windows-x86_64\bin\llvm-addr2line.exe

so文件的路径:

app\build\intermediates\ndkBuild\debug\obj\local\arm64-v8a\*.so

至于使用哪个so,要看__builtin_frame_address函数所在的动态库模块

  • 如果libleaktracer是一个单独的so动态库,那么就应该使用libleaktracer.so(一般都是这种)
  • 如果libleaktracer被以静态库的方式引入到另外一个动态库,就应该使用target.so

addr2line显示??::

检查方向:

  • 确认so库的路径,以及是否携带调试符号信息

image.png

  • 确认使用的是项目编译sdk的addr2line
  • addr2line的地址参数,是否和so混用,so里面必须有该地址才能被正常识别。
  • 检查你的地址

检查你的地址

这个也是本篇文章我遇到的,0x7921948de4这种非常大的地址,一看就有问题。

每个进程都有自己独立的进程地址空间。该进程地址空间被划分为一系列连续的虚拟地址空间,每个虚拟地址对应着唯一的物理地址。

在 x86 架构的计算机中,操作系统会为每个进程分配一个虚拟地址空间,该空间从 0x00000000 到 0xFFFFFFFF(或者更少),共 4GB 的大小。

如果要使用 addr2line 工具查询动态链接库(DLL)中某个函数的源代码位置信息,通常需要将查询地址减去该 DLL 的基地址。

这是因为在 Windows 平台上,每个 DLL 都有一个基地址,用于确定该 DLL 中所有函数和变量在虚拟地址空间中的位置,以保证不同 DLL 之间的地址不会重叠冲突。

如果直接使用官方的源码,是没有处理基地址的问题,如果leak tracer以动态库的方式引入到项目,那么stakc地址是有问题的,导致你无论怎么试错,都无法得到正确的调试符号信息。

而处理这个基地址,一个非常重要的函数就是dladdr

leak traer所使用到的函数

__builtin_frame_address

void* __builtin_frame_address(unsigned int level);

GCC 内建函数之一,在 C/C++ 中使用时可以获取当前函数的堆栈帧指针(Frame Pointer)。

其中,level 参数表示向上返回堆栈帧的层级数。

如果 level 大于当前函数的堆栈帧层数,返回 NULL

有些linux系统返回的内存地址就是VMA地址

dladdr

获得指定地址所在的共享库信息,函数原型如下:

int dladdr(
    const void *addr, // 要查询的地址
    Dl_info *info     // 用于存储查询结果的结构体
);

Dl_info 结构体定义如下:

typedef struct {
    const char* dli_fname; /* 共享库文件名 */
    void* dli_fbase; /* 基地址 */
    const char* dli_sname; /* 符号名 */
    void* dli_saddr; /* 符号地址 */
} Dl_info;

dladdr 函数的返回值是非零表示查询成功,否则表示查询失败。如果查询成功,info 参数中会填充该地址所在的共享库文件名、基地址、符号名称和符号地址等信息。

示例结果:

dli_fbase: 0x791e321000, 
dli_fname:/data/app/~~M4EQtyRf9F8ogdMdo1pJEg==/com.example.jni-gHJ1rvzAUolWe7FDtjUucA==/base.apk!/lib/arm64-v8a/libjni.so, 
dli_saddr:0x791e33eb94, 
dli_sname:_Z12test_addressv

_Unwind_Backtrace

在 Android NDK 中,您可以使用 _Unwind_Backtrace 函数获取当前线程的函数调用栈信息。

目录
相关文章
Flutter之运行提示Could not update files on device: Connection closed before full header was received
Flutter之运行提示Could not update files on device: Connection closed before full header was received
681 0
|
6月前
|
编译器 Go 开发工具
JetBrains GoLand 以debug运行Go程序时出现could not launch process: decoding dwarf section info at offset 0x0: too short报错之保姆级别解决方案
JetBrains GoLand 以debug运行Go程序时出现could not launch process: decoding dwarf section info at offset 0x0: too short报错之保姆级别解决方案
60 0
|
8月前
|
Web App开发 缓存
mySPA set delivery mode 之后,Chrome network 里观察不到cart 请求了
mySPA set delivery mode 之后,Chrome network 里观察不到cart 请求了
50 0
|
编解码 并行计算
wrf--运行real.exe时报错:“Could not find level above ground“ error
在修改wrf初始场资料时,如果做了带通滤波处理,会发现在运行real.exe时报错:“Could not find level above ground” error 。
wrf--运行real.exe时报错:“Could not find level above ground“ error
|
Java C语言 C++
JNI ERROR (app bug): local reference table overflow (max=512)
JNI ERROR (app bug): local reference table overflow (max=512)
267 0
JNI ERROR (app bug): local reference table overflow (max=512)
|
开发者
Stack Overflow 宣布 :将于 3 月 31 日中断 Jobs、Developer Story 等功能
Stack Overflow 宣布 :将于 3 月 31 日中断 Jobs、Developer Story 等功能
109 0
Stack Overflow 宣布 :将于 3 月 31 日中断 Jobs、Developer Story 等功能
|
Android开发
AVD Pixel_2_API_30 is already running. lf that is not the case, delete the files at
AVD Pixel_2_API_30 is already running. lf that is not the case, delete the files at
794 0
AVD Pixel_2_API_30 is already running. lf that is not the case, delete the files at
|
Android开发
【错误记录】Tinker 热修复示例运行报错 ( patch receive fail: /storage/emulated/0/patch_signed_7zip.apk, code: -2)
【错误记录】Tinker 热修复示例运行报错 ( patch receive fail: /storage/emulated/0/patch_signed_7zip.apk, code: -2)
399 0
【错误记录】Tinker 热修复示例运行报错 ( patch receive fail: /storage/emulated/0/patch_signed_7zip.apk, code: -2)
CPS fact debug - Continuation-pass style
Created by Wang, Jerry, last modified on Dec 24, 2015
161 0
CPS fact debug - Continuation-pass style
|
Web App开发
Reuse library debug in Chrome - phase3 exchange drop down list
Reuse library debug in Chrome - phase3 exchange drop down list
88 0
Reuse library debug in Chrome - phase3 exchange drop down list