第1章 背景

网关Linux系统版本上线后,由于代码中assert判断,导致系统出core。而core文件不像预期中的不带pid,每个core文件后都带有pid,大约1分钟一个core文件,每个文件4G多,导致磁盘空间满,业务出现异常。

登陆现网查看

1.1 系统版本

[mcpp@localhost ~]$ uname -a

Linux localhost.localdomain 2.6.18-238.el5 #1 SMP Sun Dec 19 14:22:44 EST 2010 x86_64 x86_64 x86_64 GNU/Linux

1.2 系统配置

[mcpp@localhost ~]$ sysctl -a|grep kernel.core_uses_pid

kernel.core_uses_pid = 0 //(次配置标识core文件是否带pid,此处表示不带)

1.3 用户配置

[mcpp@localhost ~]$ ulimit -a

core file size          (blocks, -c) unlimited //(此处不限制core文件大小)

data seg size           (kbytes, -d) unlimited

scheduling priority             (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 16109

max locked memory       (kbytes, -l) 32

max memory size         (kbytes, -m) unlimited

open files                      (-n) 65535

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200

real-time priority              (-r) 0

stack size              (kbytes, -s) 10240

cpu time               (seconds, -t) unlimited

max user processes              (-u) 16109

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited

第2章 测试验证

对于操作系统中关于core文件部分的修改,通过现网查看应该是没有问题,所以怀疑是RELH5.6版本配置core文件不带pid功能失效。测试程序如下:

2.1 一级进程单线程

#include <stdlib.h>

int main()

{

        abort();

        return 0;

}

编译:gcc -m64 -o pidTest pidTest.c

运行:pidTest

结果:出现core文件(不带pid)

-rw------- 1 g-yang g-yang 176128 01-05 17:25 core

2.2 一级进程多线程

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

#include <pthread.h>

#define NUM     3

void *thread_run()

{

        printf("hello, I am thread[%llu]\n", pthread_self());

        sleep(1);

        abort();

        return NULL;

}

int thread_pool_run()

{

        int             i;

        pthread_t       th[NUM];

 

        for(i=0; i<NUM; i++){

                printf("thread create\n");

                pthread_create(&th[i], NULL, thread_run, NULL);

        }

        for(i=0; i<NUM; i++){

                pthread_join(th[i], NULL);

                printf("thread exit\n");

        }

        return 0;

}

int main()

{

        int     stat;

        stat = thread_pool_run();

        pause();

        return 0;

}

编译:gcc -m64 -Wall -lpthread -o multiTest12 multiTest12.c

运行:multiTest12

结果:出现core.2178文件(带pid)

-rw------- 1 g-yang g-yang 31817728 01-05 17:25 core.2178

2.3 二级进程单线程

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

int main()

{

        int     stat;

        pid_t   pid;

        if((pid = fork()) < 0){

                printf("fork error\n");

        }else if(pid == 0){

                abort();

        }

        pause();

        return 0;

}

编译:gcc -m64 -Wall -lpthread -o multiTest2 multiTest2.c

运行:multiTest2

结果:出现core文件(不带pid)

-rw------- 1 g-yang g-yang 208896 01-05 17:25 core

2.4 二级进程多线程

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

#include <pthread.h>

#define NUM     3

void *thread_run()

{

        sleep(1);

        abort();

        return NULL;

}

int thread_pool_run()

{

        int             i;

        pthread_t       th[NUM];

 

        for(i=0; i<NUM; i++){

                pthread_create(&th[i], NULL, thread_run, NULL);

        }

        for(i=0; i<NUM; i++){

                pthread_join(th[i], NULL);

        }

        return 0;

}

int main()

{

        int     stat;

        pid_t   pid;

        if((pid = fork()) < 0){

                printf("fork error\n");

        }else if(pid == 0){

                stat = thread_pool_run();

                exit(stat);

        }

        pause();

        return 0;

}

编译:gcc -m64 -Wall -lpthread -o multiTest22 multiTest22.c

运行:multiTest22

结果:出现core.1677文件(带pid)

-rw------- 1 g-yang g-yang 31817728 01-05 17:25 core.1677

2.5 三级进程单线程

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

int main()

{

        pid_t   pid;

 

        if((pid = fork()) < 0){

                printf("fork1 error\n");

        }else if(pid == 0){

                printf("fork1 successful\n");

                if((pid = fork()) < 0){

                        printf("fork2 error\n");

                }else if(pid == 0){

                        printf("fork2 successful\n");

                        abort();

                }

                pause();

        }

        pause();

        return 0;

}

编译:gcc -m64 -Wall -lpthread -o multiTest3 multiTest3.c

运行:multiTest3

结果:出现core文件(不带pid)

-rw------- 1 g-yang g-yang 208896 01-05 17:25 core

2.6 三级进程多线程

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

#include <pthread.h>

#define NUM     3

void *thread_run()

{

        printf("hello, I am thread[%llu]\n", pthread_self());

        sleep(1);

        abort();

        return NULL;

}

int thread_pool_run()

{

        int             i;

        pthread_t       th[NUM];

 

        for(i=0; i<NUM; i++){

                printf("thread create\n");

                pthread_create(&th[i], NULL, thread_run, NULL);

        }

        for(i=0; i<NUM; i++){

                pthread_join(th[i], NULL);

        }

        return 0;

}

 

int main()

{

        int     stat;

        pid_t   pid;

        if((pid = fork()) < 0){

                printf("fork1 error\n");

        }else if(pid == 0){

                printf("fork1 successful\n");

                if((pid = fork()) < 0){

                        printf("fork2 error\n");

                }else if(pid == 0){

                        printf("fork2 successful\n");

                        stat = thread_pool_run();

                        exit(stat);

                }

                pause();

        }

        pause();

        return 0;

}

编译:gcc -m64 -Wall -lpthread -o multiTest32 multiTest32.c

运行:multiTest32

结果:出现core.2618文件(带pid)

-rw------- 1 g-yang g-yang 10833920 01-05 17:25 core.2618

2.7 测试结论

RELH5.6版本系统配置core文件不带pid功能kernel.core_uses_pid=0

1) 对单线程有效(无论是几级进程);

2) 对多线程失效(无论是几级进程)。

第3章  RELH技术支持答复

我查过了代码并做了测试,发现在 RHEL5.6 中对于多线程的进程(即多个任务共享同一个内存空间的情况),  core_uses_pid=0 是不起左右的。

内核总是会在产生的 core 文件名中加上 pid.     这个问题在 RHEL 5.7 及最新的内核中还是这样.    在 RHEL 6.1 中就不一样了, RHEL6.1 内核中不把多线程任务做特殊处理.

我不太明白,为什么你们非要 不使用 core.pid ?  想要控制 core 文件的数量吗? 

控制 core 文件的数量可以有很多方法的,  比如用 inotify() 写一个程序监控目录,当core 文件数量超出时,删除多余的文件.

另外一个方法是我们可以用 kprobes 写一个内核模块,截取内核的  format_corename() 函数,改写其产生的 corename, 去掉.pid 部分。

第4章 解决方法

4.1 不产生core文件

在.bashrc脚本里将下面的设置注释掉

#ulimit -c unlimited

并确定core file size大小为0

-bash-3.2$  ulimit -a

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

scheduling priority             (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 28852

max locked memory       (kbytes, -l) 32

max memory size         (kbytes, -m) unlimited

open files                      (-n) 1024

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200

real-time priority              (-r) 0

stack size              (kbytes, -s) 10240

cpu time               (seconds, -t) unlimited

max user processes              (-u) 28852

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited

 

互通现网出core以后,将磁盘空间占满,临时解决方法就是不产生core文件。

优点:

1) 方法简单,避免产出大量core文件将磁盘占满。

缺点:

1)不利于查找异常问题。

4.2 core文件统一改名

在用户根目录创建定时任务,每分钟执行一次,将根目录下所有文件夹里的core文件mv到指定的 目录并改名为core,脚本如下:

#!/bin/bash

find . -name "core.*" > bug.lst

while read line

do

mv $line ./temp/core

done<bug.lst

 

优点:

1)保留了部分异常信息。

缺点:

1) 浪费系统资源,不断的产生core文件,大约1分钟1个,互通一般为4G多。

4.3 core文件目录指向限制磁盘

单独划分一个磁盘分区,用于存放core文件,将所有core文件指向新划分的磁盘空间,以root用户修改系统参数如下:

-bash-3.2$  vi /etc/sysctl.conf

新增如下一行

kernel.core_pattern = /home/g-yang/temp/

优点:

1)保留了部分异常信息。

缺点:

1)方式太土,不建议使用。
Logo

更多推荐