在工作的过程中,发现在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: |
|
|
|
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; i
pthread_create(&th[i], NULL, thread_run, NULL);
}
for(i=0; i
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;
}
执行结果:
达到目的了。