solaris memory leak

本文介绍如何使用libumem和mdb工具检测Solaris系统中应用程序的内存泄漏问题,并通过示例程序展示了具体的检测步骤和方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(content come from : http://developers.sun.com.cn/blog/judy/entry/200703091)

Solaris中如何检测内存泄漏(一) 在Solaris中如何监测应用程序和核心代码(驱动程序)是否存在内存泄漏?
内存泄漏(Memory Leak)通常是由应用程序没有释放其在堆(heap)上分配的内存而造成的。
对于由应用程序引起的内存泄漏,我们可以借助libumem来方便地进行调试。libumem是一个运行在用户模式的内存分配程序库。并已包含在 Solaris 9及以后的Solaris版本中。
对于内核代码,则可以利用Solaris调试工具mdb提供的"::findleaks"命令来进行检测。

一 利用libumem检测应用程序的内存泄漏

本文将以一个示例简单说明使用libumem的步骤。示例程序memleak.c如下:

/* memleak.c */
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    char *p;
    p = malloc(50);
    p = malloc(100);
    while (1) {
        sleep(1);
    }
}

这个程序存在明显的内存泄漏。先用gcc编译该程序
$ /usr/sfw/bin/gcc -o memleak memleak.c

使能libumem,检测内存泄漏
$ export LD_PRELOAD=libumem.so
$ export UMEM_DEBUG=default
$ export UMEM_LOGGING=transaction
$ ./memleak &
[1] 1121
$ gcore 1121
gcore: core.1121 dumped
$ mdb core.1121
Loading modules: [ libumem.so.1 libc.so.1 ld.so.1 ]
> ::findleaks            -> 检测应用程序中发现的内存泄漏
CACHE LEAKED BUFCTL CALLER
0807c610 1 08088080 main+0x26
------------------------------------------------------------------------
Total 1 buffer, 64 bytes
> 08088080::bufctl_audit -> 打印最后对该内存进行操作的调用栈
ADDR    BUFADDR TIMESTAMP   THREAD
CACHE   LASTLOG CONTENTS
8088080 8086f80 2b73ee921ea 1
807c610 806b000 0
         libumem.so.1`umem_cache_alloc_debug+0x14f
         libumem.so.1`umem_cache_alloc+0x180
         libumem.so.1`umem_alloc+0xcc
         libumem.so.1`malloc+0x27
         main+0x26
         _start+0x80

进一步检查内存分配日志如下。就可以看出内存泄漏的原因是应用程序调用了两次malloc(),但没有调用free()。
> ::umalog

T-0.000000000 addr=8089f80 umem_alloc_112
         libumem.so.1`umem_cache_alloc_debug+0x14f
         libumem.so.1`umem_cache_alloc+0x180
         libumem.so.1`umem_alloc+0xcc
         libumem.so.1`malloc+0x27
         main+0x36
         _start+0x80

T-0.000052036 addr=8086f80 umem_alloc_64
         libumem.so.1`umem_cache_alloc_debug+0x14f
         libumem.so.1`umem_cache_alloc+0x180
         libumem.so.1`umem_alloc+0xcc
         libumem.so.1`malloc+0x27
         main+0x26
         _start+0x80
除了检测内存泄漏外,libumem还可用于检测内存异常,如内存越界访问。简单修改memleak.c,在第8行
         p = malloc(50);
后加入如下语句:
         memset(p, 60, 0);

重新编译、运行memleak,并生成core文件。
$ mdb core.1168
Loading modules: [ libumem.so.1 libc.so.1 ld.so.1 ]
> ::umem_verify         -> 检测是否存在内存异常
Cache Name Addr    Cache Integrity
umem_magazine_1    8077010 clean
umem_magazine_3    8077210 clean
umem_magazine_7    8077410 clean
umem_magazine_15   8077610 clean
umem_magazine_31   8077810 clean
umem_magazine_47   8077a10 clean
umem_magazine_63   8077c10 clean
umem_magazine_95   8077e10 clean
umem_magazine_143  8079010 clean
umem_slab_cache    8079210 clean
umem_bufctl_cache  8079410 clean
umem_bufctl_audit_cache 8079610 clean
umem_alloc_8       8079810 clean
umem_alloc_16      8079a10 clean
umem_alloc_24      8079c10 clean
umem_alloc_32      8079e10 clean
umem_alloc_40      807c010 clean
umem_alloc_48      807c210 clean
umem_alloc_56      807c410 clean
umem_alloc_64      807c610 1 corrupt buffer -> 发现内存异常
umem_alloc_80      807c810 clean
umem_alloc_96      807ca10 clean
> 807c610::umem_verify
Summary for cache 'umem_alloc_64'
buffer 8086f80 (allocated) has a corrupt redzone size encoding
> 8086f80::whatis       -> 找到bufctl指针
8086f80 is 8086f80+0, bufctl 8088080 allocated from umem_alloc_64
> 8088080::bufctl_audit -> 打印调用栈以确定异常所在的内存块
ADDR BUFADDR TIMESTAMP THREAD
CACHE LASTLOG CONTENTS
8088080 8086f80 422098b4141 1
807c610 806b000 0
         libumem.so.1`umem_cache_alloc_debug+0x14f
         libumem.so.1`umem_cache_alloc+0x180
         libumem.so.1`umem_alloc+0xcc
         libumem.so.1`malloc+0x27
         main+0x26
         _start+0x80
> 8086f80/20X           -> 打印buffer内容
0x8086f80: 3a 3a10bfc6 0       0
           0  0        0       0
           0  0        0       0
           0  0        0       0
           0  38df     8088080 a918486d
可以看出内存中有60个字节被设成了0,而该内存实际上只分配了50个有效字节。并且由于内存越界访问,redzone的标志字节“feedface”也被覆盖了。

(content come from : http://developers.sun.com.cn/blog/judy/entry/200703091)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值