execl 内存泄露跟踪

遇到了嵌入式linux下面系统级内存泄露问题。跟踪问题日志。
平台:ARM9
内核:2.6.22

问题:execl造成系统内存减少,通过cat /proc/memoinfo 发现少的内存并且都移往slab中去了
测试代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>

int main()
{
    int i = 0;
    int pid = 0;

    for (i=0; i<1000; i++)
    {
        pid = fork();
        if (pid < 0)
        {
            printf("fork() fail!\n");
            continue;
        }
        else if (pid == 0) //child
        {
            //system("ls");
            execl("/bin/ls", "ls", "", NULL);
            printf("execl() here!\n");
            exit(0);
        }
        else
        {
            waitpid(pid, 0, 0);
            printf("[%d] exited!", pid);
        }

        printf("%d\n", i);
       
    }

    return 0;
}

20091010:在PC上ubuntu 9.04上测试这个程序发现没有内存减少的现象。在ARM9上发现,每次执行1000次左右,导致有300k左右的内存减少。可能与内核版本(ubuntu 9.04是2.6.30的kernel版本)有关系,通过google或百度并没有发现有这样的问题。估计是配置内核导致的问题。下一步将通过cat /proc/slabinfo 来研究内存多出来的部分的来源。

20091011:通过1000此调用之后,通过cat /proc/slabinfo对比发现,变化最大的是
name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
size-256             120    120    256   15    1 : tunables  120   60    0 : slabdata      8      8      0
size-256            1120   1125    256   15    1 : tunables  120   60    0 : slabdata     75     75      0
计算,pagesperslab为1,即一个page中有一个slab,(75-8)×4K = 268k左右。为了排除其他部分造成的内存泄露。做了一个测试,频繁的进行1000次malloc和free,发现size-256项也无特别变化。可以初步判断,应该是size-256块slab中出现了内存没有释放的行为。下一步动作,研究源代码do_execve部分来看分配192~256k的内存的嫌疑函数以及是否在退出后被释放。

20091012:为了排除slab本身有bug的情况,将内核分配机制改为slub,结果,依然在执行1000次之后少出300k的内存空间。在slub.c中,static struct kmem_cache *get_slab(size_t size, gfp_t flags)函数中插入log,这里是分配的必经之路。当分配的大小在128~256之间时,log出分配的size大小。执行测试程序,发现
_DEBUG: get slab size = 192
_DEBUG: get slab size = 208
就是说有分配192和208的需求在。
而简单的ls,或pwd都会打印这个出来,本人据此推断,分析进行shell命令也会有内存泄露问题。手动ls100次,果不其然,大概有52k的内存泄露,平均起来就是2个256的空间没有收回。
对log的出处一直跟踪(callstack),发现最终锁定在load_elf_binary这个函数中,仔细看了code,发现log不是很规范,与同事交流了,原来被touch过。立即找到kmalloc和kfree的地方,看哪个kfree有没有漏掉,果然发现漏洞。去http://lxr.linux.no对比2.6.22历史版本,发现同事的修改有个地方忘记free了,兴奋之余,赶紧改过来,测试5000次。结果正常。原来这个添加的code是同事用来调试用的,忘记砍掉了。我说呢,内核应该没有这样明显的错误的,google也无任何关于此的问题。经过此次跟踪后,对内核内存分配更加理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值