Unix系统(包括linux以及Mac OS X)在程序异常终止后,可能会产生记录当前程序运行信息的core file。可以通过命令ulimit -c n设定core file的大小n KBytes,n为0表示不产生core file,命令行中的设定仅对当前shell有效,若要全局设定,可以在profile文件中写入上述命令。 core file的文件名在不同的系统中不尽相同。在linux系统中,在目录/proc/sys/kernel下的文件core_pattern、core_uses_pid规定了core file的文件名格式,core_uses_pid为1表示core file 文件名使用pid,为0则相反。
可以通过setrlimit()产生core file的大小,getrlimit()获取core file大小的系统设定。编程示范如下:
// Example of usage of getrlimit() and setrlimit()
// luojiahu 2015.8.15
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h> /* define struct rlimi_t, function getrlimit ... */
int main(void)
{
struct rlimit t;
long long softLimit = t.rlim_cur;
long long hardLimit = t.rlim_max;
printf("original value of struct rlimit\nsoft limit: %lld\nhard limit: %lld\n", softLimit, hardLimit);
int a = getrlimit(RLIMIT_CORE, &t); /* if get succed, it returns 0, else return -1 */
if( !a )
{
hardLimit = t.rlim_max;
softLimit = t.rlim_cur;
printf("current system setting of core file size:\nsoft limit: %lld\nhard limit: %lld\n", softLimit, hardLimit);
}
else
{
perror("get core file system setting failed!\n");
exit(EXIT_FAILURE);
}
printf("Now setting core file size to:\nsoft limit: 10*1024\nhard limit: 100*1024\n");
t.rlim_cur = 10*1024;
t.rlim_max = 100*1024;
setrlimit(RLIMIT_CORE, &t);
struct rlimit new_t;
a = getrlimit(RLIMIT_CORE, &new_t); /* if get succed, it returns 0, else return -1 */
if( !a )
{
hardLimit = new_t.rlim_max;
softLimit = new_t.rlim_cur;
printf("current system setting of core file size:\nsoft limit: %lld\nhard limit: %lld\n", softLimit, hardLimit);
}
else
{
exit(EXIT_FAILURE);
}
// while(1)
// {} /* do nothing */
return 0;
}
在程序中设定的core file size ,只对当前进程及其子进程有效。可以编写以下程序进行测试(系统设定不产生core file,即ulimit -Sc 0)。执行程序并执行任意其他程序,分别向对应的进程发送信号kill -s signal_number pid,观察是否产生core file。
// This program set core file size in the father process
// fork a child process and test whether a core file will
// generate when program ended unnormally
// luojiahu 2015.8.16
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/resource.h>
#include <string.h>
#define UNLIMITED 4294967295
void Zero(void* t)
{
if(t == NULL)
return ;
size_t size = sizeof(*t);
memset(t, 0 , size);
}
int main(void)
{
unsigned long hardLimit, softLimit;
struct rlimit coreFileSize;
Zero(&coreFileSize);
getrlimit(RLIMIT_CORE, &coreFileSize); /* get the system settings */
hardLimit = (unsigned long)coreFileSize.rlim_max;
softLimit = (unsigned long)coreFileSize.rlim_cur;
printf("core file system setting:\nsoft limit: %u\nhard limit: %u\n", softLimit, hardLimit);
printf("Set soft limit to 1000 KB, hard limit to unlimited:\n");
coreFileSize.rlim_cur = 1000*1024;
coreFileSize.rlim_max = UNLIMITED;
setrlimit(RLIMIT_CORE, &coreFileSize);
pid_t pid = fork();
if( pid < 0)
{
perror("fork faild!\n");
exit(EXIT_FAILURE);
}
else if( pid == 0)
{
printf("this is child process with pid: %d", getpid());
}
else
{
printf("this is parent process with pid %d", getpid());
}
while(1)
{} /* do nothing */
return 0;
}
以下是对softEtherVPN中函数UnixSetResourceLimit的测试
// This program test the funciont of softEtherVpN
// function void UnixSetResourceLimit(UINT id, UINT64 value)
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h>
#include <string.h>
#define UINT int
#define UINT64 long long
#define MIN(a, b) ( (a >= b) ? (b) : (a))
void Zero(void *addr, UINT size)
{
// Validate arguments
if (addr == NULL || size == 0)
{
return;
}
// KS
// KS_INC(KS_ZERO_COUNT);
memset(addr, 0, size);
}
void UnixSetResourceLimit(UINT id, UINT64 value)
{
struct rlimit t;
UINT64 hard_limit;
/*/ if (UnixIs64BitRlimSupported() == false)
{
if (value > (UINT64)4294967295ULL)
{
value = (UINT64)4294967295ULL;
}
}
*/
Zero(&t, sizeof(t));
getrlimit(id, &t);
hard_limit = (UINT64)t.rlim_max;
Zero(&t, sizeof(t));
t.rlim_cur = (rlim_t)MIN(value, hard_limit);
t.rlim_max = (rlim_t)hard_limit;
setrlimit(id, &t);
Zero(&t, sizeof(t));
t.rlim_cur = (rlim_t)value;
t.rlim_max = (rlim_t)value;
setrlimit(id, &t);
}
int main(void)
{
struct rlimit t;
getrlimit(RLIMIT_CORE, &t);
printf("core file size system setting:\nsoft limit: %lld\nhard limit: %lld\n", (long long)t.rlim_cur, (long long)t.rlim_max);
printf("Call functon UnixSetResourceLimit(0)\n");
UnixSetResourceLimit(RLIMIT_CORE, 0);
getrlimit(RLIMIT_CORE, &t);
printf("after funciont call core file size:\nsoft limit: %lld\nhard limit: %lld\n", (long long)t.rlim_cur, (long long)t.rlim_max);
return 0;
}
版权声明:本文为luojihu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。