关于core_uses_pid标志对多线程程序无用的调查


一、    案例的起因

在工作的过程中,发现在RHEL5.6系统下,运行进程,一旦应用线程,出core后,总会带着进程ID。即使在系统中设置core_uses_pid=0,也是不行的。

这样的话如果应用系统出现core文件,那么会是悲剧性的。磁盘空间被占满等情形都会出现的。

如何让我们的core_file的名字保持唯一或者有限个数呢?

二、资料的查询与分析

在网上“https://bugzilla.kernel.org”发现了这个bug的存在,简要信息如下:

Bug 6312 - core_uses_pid=0 not always honored

Status:

REJECTED WILL_NOT_FIX

Reported:

2006-03-30 15:10 by David M. Lee

Product:

Other

Modified:

2007-01-31 01:03 (History)

Component:

Other

Kernel Version:

2.6.15.2

Version:

2.5

Tree:

Mainline

Platform:

i386 Linux

Regression:

---

Importance:

P2 normal

 

 

Assigned To:

[email protected]

 

 

URL:

 

 

 

Depends on:

 

 

 

Blocks:

 

 

 

 

Show dependency tree / graph

 

 

 

详细信息参见:https://bugzilla.kernel.org/show_bug.cgi?id=6312

 

从该信息中获知,产生core文件时,名字是由函数format_corename来执行的。所以,针对内核源码“linux-2.6.27.62 和linux-3.2.7”做了分析。发现在3.2.7版本的内核中修复了改BUG。

经过对该函数的分析,发现我们之所以出现问题,就是由于参数nr_threads引起的,而这个参数的含义就是使用该资源的线程个数,该值是被内敛函数“zap_threads”来设置的。

而这段代码基本上是不可避免的都要走到的。我们如何跳过这段代码呢?如何让nr_threads不起作用呢?

       /*Backward compatibility with core_uses_pid:

        *

        * If core_pattern does not include a %p (as isthe default)

        * and core_uses_pid is set, then .%pid will beappended to

        * the filename. Do not do this for pipedcommands. */

       if(!ispipe && !pid_in_pattern

           && (core_uses_pid || nr_threads)) {

              rc= snprintf(out_ptr, out_end - out_ptr,

                           ".%d", task_tgid_vnr(current));

              if(rc > out_end - out_ptr)

                     gotoout;

              out_ptr+= rc;

       }

 

Fork为何会遵循core_uses_pid的设置呢?参见zap_threads中的解释。

        *fork:

        *    None of sub-threads can fork afterzap_process(leader). All

        *    processes which were created before thispoint should be

        *    visible to zap_threads() becausecopy_process() adds the new

        *    process to the tail of init_task.tasks list,and lock/unlock

        *    of ->siglock provides a memory barrier.

 

从函数实现中我们可以发现如下代码。

                            if (rc > out_end - out_ptr)

                                   goto out;

这个是表示的core文件名字的长度,那么最大长度CORENAME_MAX_SIZE是多大呢?

binfmts.h中定义:#defineCORENAME_MAX_SIZE 128

所以,我们采用边界值越界跳出上面那段让人头疼的代码。

测试的设置方法如下:设置文件名字长度core+123字符的形式定向到/proc/sys/kernel/core_pattern中。

[root@tcore]$echo"core123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123"> /proc/sys/kernel/core_pattern

测试程序:

#include
#include
#include
#include
#include


#define NUM 3


void *thread_run()
{
printf("hello, I am thread[%llu]\n", pthread_self());
sleep(3);
abort();
return NULL;
}


int thread_pool_run()
{
int i;
pthread_t th[NUM];


for(i=0; iprintf("thread create\n");
pthread_create(&th[i], NULL, thread_run, NULL);
}
for(i=0; ipthread_join(th[i], NULL);
printf("thread exit\n");
}
return 0;
}


int main()
{
int stat;
pid_t pid;


if((pid = fork()) < 0){
printf("fork error\n");
}else if(pid == 0){
printf("fork successful\n");
stat = thread_pool_run();
exit(stat);
}


pause();
return 0;
}

执行结果:

达到目的了。


你可能感兴趣的:(谈工作,Linux内核)