Lsan backtrace出现unknow module解决方案

目录

背景

复现问题

泄漏发生在编译所需动态库中

泄漏发生在自定义加载的动态库中

出现 unknow module的原因

unknow module的解决方案

maps

maps解释

具体解决步骤

小结


背景

之前在做项目过程中,用Lsan定位 memleak backtrace的时候出现 <unknown module>的情况,这个时候就不能用找到对应的 symbols so,从而用 llvm-addr2line去解析对应的代码行数。不方便找到对应的泄露点。

复现问题

泄漏发生在编译所需动态库中

泄漏发生在编译所需动态库中,这种情况可以直接编译后运行就能发现,测试代码如下。

// myadd.h

extern "C" int add(int a, int b);

//myadd.cpp

#include "myadd.h"

extern "C" int add(int a, int b)
{
    int* p = new int(); // 内存泄漏的位置
    return a + b;
}

// test.cpp

/*
#include "myadd.h"
#include <dlfcn.h>
#include <iostream>

typedef int (*FUNC)(int a,int b);

int main() {
    void* handle = dlopen("./libmyadd.so", RTLD_LAZY);
    FUNC myadd = (FUNC)dlsym(handle,"add");

    int nVal = 0;
    std::cin >> nVal;
    std::cout << "519 + 1 = " << myadd(519, 1) << ", input:" << nVal << std::endl;

    dlclose(handle);
    return 0;
}
*/

#include "myadd.h"
#include <iostream>

int main()
{
    std::cout << "519 + 1 = " << add(519, 1) << std::endl;
    return 0;
}

编译运行、输出:

g++ -shared -fPIC -o libmyadd.so myadd.cpp

g++ test.cpp -L. -lmyadd -o test -Wl,-rpath=. -fsanitize=leak

输出backtrace:

wj@wj:~/WORKING_DIRECTORY/Learning/asan_learning/unknow module$ ./test

519 + 1 = 520

=================================================================

==305684==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 4 byte(s) in 1 object(s) allocated from:

#0 0x7fdef1f203c1 in operator new(unsigned long) ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:229

#1 0x7fdef1f0c134 in add (libmyadd.so+0x1134)

#2 0x5560487c421a in main (/home/wj/WORKING_DIRECTORY/Learning/asan_learning/unknow module/test+0x121a)

#3 0x7fdef19f1082 in __libc_start_main ../csu/libc-start.c:308

SUMMARY: LeakSanitizer: 4 byte(s) leaked in 1 allocation(s).

也可以直接显示出内存泄漏的位置,内存泄漏在 libmyadd.so 动态库中的 add 函数中

泄漏发生在自定义加载的动态库中

这种情况要想精确定位问题就麻烦一些了,下面是用来测试的代码。

// myadd.h

extern "C" int add(int a, int b);

//myadd.cpp

      
#include "myadd.h"

extern "C" int add(int a, int b)
{
    int* p = new int(); // 内存泄漏的位置
    return a + b;
}

// test.cpp
 

// test.cpp


#include "myadd.h"
#include <dlfcn.h>
#include <iostream>

typedef int (*FUNC)(int a,int b);

int main() {
    void* handle = dlopen("./libmyadd.so", RTLD_LAZY);
    FUNC myadd = (FUNC)dlsym(handle,"add");

    int nVal = 0;
    std::cin >> nVal;
    std::cout << "519 + 1 = " << myadd(519, 1) << ", input:" << nVal << std::endl;

    dlclose(handle);
    return 0;
}

编译、运行、输出:

g++ -shared -fPIC -o libmyadd.so myadd.cpp -g

g++ test.cpp -ldl -o test -Wl,-rpath=. -g -fsanitize=leak

wj@wj:~/WORKING_DIRECTORY/Learning/asan_learning/unknow module$ ./test

618

519 + 1 = 520, input:618

=================================================================

==307055==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 4 byte(s) in 1 object(s) allocated from:

#0 0x7f464c0ca3c1 in operator new(unsigned long) ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:229

#1 0x7f464bb1b134 (<unknown module>)

#2 0x555ef90ae2f0 in main /home/wj/WORKING_DIRECTORY/Learning/asan_learning/unknow module/test.cpp:16

#3 0x7f464bb9a082 in __libc_start_main ../csu/libc-start.c:308

SUMMARY: LeakSanitizer: 4 byte(s) leaked in 1 allocation(s).

从上面的backtrace 来看,泄漏点发生在<unknown module>,这一行,但是定位不到具体的泄漏信息,就比较麻烦,找不到真正泄漏点,出现 unknown module 的这种情况还挺多 。

出现 unknow module的原因

当使用 dlopen 的方式加载的动态库时,产生的内存泄漏常显示为 (<unknown module>),那是因为 lsan 在程序退出时分析内存泄漏情况,而这时自定义加载的动态库往往已经手动调用 dlclose 关闭了,这时就会显示成 #1 0x7f464bb1b134 (<unknown module>) 的情况。

unknow module的解决方案

maps

针对于出现 (<unknown module>) 的这种情况,可以通过查

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值