Pmap查看内存泄露

Pmap可以查看堆地址信息(程序中new/malloc出来的空间),然后gdb调试查看堆较大的内存块数据信息。(本次测试只是使用了这个功能,是否还有其他牛逼的功能不知道)

  1. 编写测试代码

#include <iostream>

#include <string>

#include <stdio.h>

 

class mem_test

{

public:

mem_test()

{

        m_buffer = new char[1000*2000];

        printf("memory test address: %p\n", m_buffer);

        memcpy(m_buffer, "xiagaodedaqiqiu", 20);

}

private:

char *m_buffer;

};

 

void mem_leak()

{

char *buffer = new char[1024*1024];

printf("memory leak function address: %p\n", buffer);

memcpy(buffer, "wqb5", 5);

}

 

int main()

{

mem_leak();

mem_test *ptr = NULL;

for(int i = 0; i < 20; i++)

 {

ptr = new mem_test;

delete ptr;

}       

 

while(1)

{

}

return 0;

}

  1. 编译生成文件后执行,输出信息如下

$ ./a.out

memory leak function address: 0x7fdfc426a010

memory test address: 0x7fdfc3382010

memory test address: 0x7fdfc3199010

memory test address: 0x7fdfc2fb0010

memory test address: 0x7fdfc2dc7010

memory test address: 0x7fdfc2bde010

memory test address: 0x7fdfc29f5010

memory test address: 0x7fdfc280c010

memory test address: 0x7fdfc2623010

memory test address: 0x7fdfc243a010

memory test address: 0x7fdfc2251010

memory test address: 0x7fdfc2068010

memory test address: 0x7fdfc1e7f010

memory test address: 0x7fdfc1c96010

memory test address: 0x7fdfc1aad010

memory test address: 0x7fdfc18c4010

memory test address: 0x7fdfc16db010

memory test address: 0x7fdfc14f2010

memory test address: 0x7fdfc1309010

memory test address: 0x7fdfc1120010

memory test address: 0x7fdfc0f37010

  1. 以此执行下面的命令
    1. ps -ef|grep a.out    7972 15451 90 14:23 pts/1  00:00:07 ./a.out找到程序的进程号
    2. gdb attach 7972
    3. 进入程序之后执行c,然后ctrl +C回到命令输入状态
    4. shell pmap 7972查看当前程序所有堆地址信息

0000000000400000      4K r-x-- a.out

0000000000600000      4K rw--- a.out

0000000001f2d000    132K rw---   [ anon ]

00007fdfc0f37000  39120K rw---   [ anon ]

00007fdfc356b000   1804K r-x-- libc-2.17.so

00007fdfc372e000   2044K ----- libc-2.17.so

00007fdfc392d000     16K r---- libc-2.17.so

00007fdfc3931000      8K rw--- libc-2.17.so

00007fdfc3933000     20K rw---   [ anon ]

00007fdfc3938000     84K r-x-- libgcc_s-4.8.5-20150702.so.1

00007fdfc394d000   2044K ----- libgcc_s-4.8.5-20150702.so.1

00007fdfc3b4c000      4K r---- libgcc_s-4.8.5-20150702.so.1

00007fdfc3b4d000      4K rw--- libgcc_s-4.8.5-20150702.so.1

00007fdfc3b4e000   1028K r-x-- libm-2.17.so

00007fdfc3c4f000   2044K ----- libm-2.17.so

00007fdfc3e4e000      4K r---- libm-2.17.so

00007fdfc3e4f000      4K rw--- libm-2.17.so

00007fdfc3e50000    932K r-x-- libstdc++.so.6.0.19

00007fdfc3f39000   2044K ----- libstdc++.so.6.0.19

00007fdfc4138000     32K r---- libstdc++.so.6.0.19

00007fdfc4140000      8K rw--- libstdc++.so.6.0.19

00007fdfc4142000     84K rw---   [ anon ]

00007fdfc4157000    136K r-x-- ld-2.17.so

00007fdfc426a000   1048K rw---   [ anon ]

00007fdfc4376000      8K rw---   [ anon ]

00007fdfc4378000      4K r---- ld-2.17.so

00007fdfc4379000      4K rw--- ld-2.17.so

00007fdfc437a000      4K rw---   [ anon ]

00007fff3a1bb000    132K rw---   [ stack ]

00007fff3a1e0000      8K r-x--   [ anon ]

ffffffffff600000      4K r-x--   [ anon ]

       从上面的输出信息可以到有一块大概400k左右的内存块地址,和程序中创建的地址差不多大小(1000*2000*20)

1、x/20s 0x00007fdfc0f37000

0x7fdfc0f37000:     ""

0x7fdfc0f37001:     ""

0x7fdfc0f37002:     ""

0x7fdfc0f37003:     ""

0x7fdfc0f37004:     ""

0x7fdfc0f37005:     ""

0x7fdfc0f37006:     ""

0x7fdfc0f37007:     ""

0x7fdfc0f37008:     "\002\220\036"

0x7fdfc0f3700c:      ""

0x7fdfc0f3700d:     ""

0x7fdfc0f3700e:     ""

0x7fdfc0f3700f:      ""

0x7fdfc0f37010:     "xiagaodedaqiqiu"

0x7fdfc0f37020:     ""

0x7fdfc0f37021:     ""

0x7fdfc0f37022:     ""

0x7fdfc0f37023:     ""

0x7fdfc0f37024:     ""

       从输出信息可以看到在pmap输出的地址偏差16字节出有用户创建的堆地址

2、x/20s 0x00007fdfc0f37000+1000

(gdb) x/20s 0x00007fdfc0f37000+1000

0x7fdfc0f373e8:     ""

0x7fdfc0f373e9:     ""

0x7fdfc0f373ea:     ""

0x7fdfc0f373eb:     ""

              发现其他创建的19个堆地址并不是连续的,所有通过地址+1000并不能找到下一个用户创建的堆地址,相反执行-1000的话直接报错(不知为何),0x7fdfc0f37010地址和日志最后一行打印的地址也是对应的。

       同样的方式从代码实现可以知道我们还泄露了一个1024*1024字节的内存块,从pmap输出信息可以知道:

00007fdfc426a000   1048K rw---   [ anon ]

       猜测这个就是用户创建的内存空间,然后同样的方式找到内存空间的信息

       (gdb) x/20s 0x00007fdfc426a000

0x7fdfc426a000:     ""

0x7fdfc426a001:     ""

0x7fdfc426a002:     ""

0x7fdfc426a003:     ""

0x7fdfc426a004:     ""

0x7fdfc426a005:     ""

0x7fdfc426a006:     ""

0x7fdfc426a007:     ""

0x7fdfc426a008:     "\002\020\020"

0x7fdfc426a00c:     ""

0x7fdfc426a00d:    ""

0x7fdfc426a00e:     ""

0x7fdfc426a00f:     ""

0x7fdfc426a010:     "wqb5"

0x7fdfc426a015:     ""

0x7fdfc426a016:     ""

0x7fdfc426a017:     ""

0x7fdfc426a018:     ""

0x7fdfc426a019:     ""

同样在偏移16字节出有用户创建的内存空间,和日志打印对比也是对应的。

       通过以上方式可以处理部分内存泄露的问题,关键主要有两点,1、能通过pmap找到内存卡地址,这里由于很明显程序创建了一个20个20k大小的空间未释放,然后pmap输出了一个大小差不多400k的快地址,那么很容易对应到泄露源地址。2、找到地址之后,能通过地址的数据内容对应到代码中的数据结构,这里因为程序中将buffer初始化了“xiagaodaqiqiu”这个字符串也是很容易就找到了

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值