core-dump현상 발생!
'어랏;; 그럴리가....'
회사로 복귀(밤 11시) 후 원인 분석. (참고로, 장비는 32-bit 인텔cpu이고, os는 linux이다.)
(gdb) where
#0 0x0050c402 in __kernel_vsyscall ()
#1 0x00df7d3b in write () from /lib/libc.so.6
#2 0x00d996d4 in _IO_new_file_write () from /lib/libc.so.6
#3 0x00d993a5 in new_do_write () from /lib/libc.so.6
#4 0x00d9967f in _IO_new_do_write () from /lib/libc.so.6
#5 0x00d99e56 in _IO_new_file_sync () from /lib/libc.so.6
#6 0x00d8eaac in fflush () from /lib/libc.so.6
#7 0x005a0b12 in TAP_Log (level=LOG_CRITICAL, filenm=0x8072faf "MIPH_blc.c", line=752,
str=0x807266c " -->[D] %d:%s[0x%04x] (CallId:0x%08x, DPC:0x%04x, CIC:0x%04x) sec=%ld, usec=%ld\n") at TAP_Log.c:332
#8 0x080582bf in BLC_DEQ (pInfo=0x95f8560, qidx=2) at MIPH_blc.c:750
#9 0x08058ca8 in BLC_Worker (p=0x95e9c18, args=0x95f8560) at MIPH_blc.c:158
#10 0x0023139b in wrapRtnThread (wrapArgs=0xbf802790) at Process.c:547
#11 0x0078343b in start_thread () from /lib/libpthread.so.0
#12 0x00e06fde in clone () from /lib/libc.so.6
#0 0x0050c402 in __kernel_vsyscall ()
#1 0x00df7d3b in write () from /lib/libc.so.6
#2 0x00d996d4 in _IO_new_file_write () from /lib/libc.so.6
#3 0x00d993a5 in new_do_write () from /lib/libc.so.6
#4 0x00d9967f in _IO_new_do_write () from /lib/libc.so.6
#5 0x00d99e56 in _IO_new_file_sync () from /lib/libc.so.6
#6 0x00d8eaac in fflush () from /lib/libc.so.6
#7 0x005a0b12 in TAP_Log (level=LOG_CRITICAL, filenm=0x8072faf "MIPH_blc.c", line=752,
str=0x807266c " -->[D] %d:%s[0x%04x] (CallId:0x%08x, DPC:0x%04x, CIC:0x%04x) sec=%ld, usec=%ld\n") at TAP_Log.c:332
#8 0x080582bf in BLC_DEQ (pInfo=0x95f8560, qidx=2) at MIPH_blc.c:750
#9 0x08058ca8 in BLC_Worker (p=0x95e9c18, args=0x95f8560) at MIPH_blc.c:158
#10 0x0023139b in wrapRtnThread (wrapArgs=0xbf802790) at Process.c:547
#11 0x0078343b in start_thread () from /lib/libpthread.so.0
#12 0x00e06fde in clone () from /lib/libc.so.6
로그에는 문제가 없어 보이는데.... fflush가 보이고, write 시스템 콜에서 멈춤이라...
-_-??? 어...이거 뭐야..
대충 로그에서 문제가 있고, 파일이 커서 발생했다고 예상/추측 하고 있지만,
확실히 하기 위해 원인을 찾았다. 아래와 같은 test.c를 작성했다.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/signal.h>
FILE *p;
void Exit(int signo)
{
if( p ) fclose(p);
exit(0);
}
{
if( p ) fclose(p);
exit(0);
}
void kkk(int signo)
{
printf("오.... 정말이네...\n");
if( p ) fclose(p);
exit(0);
}
{
printf("오.... 정말이네...\n");
if( p ) fclose(p);
exit(0);
}
int main(void)
{
signal(SIGKILL, Exit);
signal(SIGINT, Exit);
signal(SIGPIPE, Exit);
// signal(SIGXFSZ, kkk); (1)
// signal(SIGXFSZ, SIG_IGN); (2)
p = fopen("./log", "w+");
while(1) {
fputs("kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\n", p);
}
fputs("kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\n", p);
}
fclose(p);
return 0;
}
return 0;
}
위와 같은 아주 간단하고도 무식한 코드를 짜고, 컴파일(gcc -o a.out test.c).
(코드 이상/구멍(?)으로 인한 문제제기 거부!)
a.out실행... 시간이 어느정도 흐른 후, 아래의 메시지가 출력되며 core-dump파일 생성.
Filesize limit exceeded (core dumped)
오... 이것봐라.. 증말이네(경험 부족 -_-+).
log파일 크기를 체크하니 2.1GB(2147483647)였다.
'(2)'를 풀어놓고 했을 경우는, 파일 크기가 위 크기에서 더 커지지 않고, 데이터도 써지지
않는다.
'(3)'을 플어놓고 했을 경우는 함수 kkk의 프린트문이 출력되고 정상 종료 처리되었다.
(소스에 나온 것 처럼, 이와 같은 상황에서 발생하는 signal은 SIGXFSZ이다.)
약 2GB라는 파일 크기 제한이 있다고 판단되어, 이와 같은 상황 재현시 문제해결을 위해
방법을 찾았다.
1. 파일 크기가 일정 크기 이상이 될 경우 로그 파일을 분할 하는 방법
2. 파일 크기가 2GB를 초과하더라고 프로세스가 계속 데이터를 쓸 수 있게 하고,
core-dump및 재시작이 안되게 하는 방법.
효과적인 방법은 '1'이라 생각하지만, 시간 관계상(현재 BMT중...-_ㅠ) '2'번 선택.
열심히 검색한 결과 gcc의 컴파일 옵션을 통해 가능한 방법을 찾았다.
-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
혹은
-D_FILE_OFFSET_BITS=64
혹은
-D_FILE_OFFSET_BITS=64
두 개의 옵션 중 file offset bits만 64bit으로 적용하면 2GB를 초과하여 log입력이 가능하다.
위엔 언급한 샘플 소스를 이 옵션을 적용하여 컴파일 후 실행해본 결과,
3GB까지(이후에 시간관계상 중단) 문제없이 써짐을 확인할 수 있었다.
로그가 이렇게 까지 커지는게 비효율적이라 생각하지만,...
뭐 당장 로그 많이 쌓는 프로세스 중단을 막긴 막아야 하니까.....
= 끝 =
댓글을 달아 주세요