[서버 프로그램 한달 운영하면 클라이언트가 접속 못하는 상태에 빠집니다.]

dam808의 이미지

안녕하세요
Solaris 10 에서 C로 구현한 멀티쓸레드 TCP/IP 서버이며

혼자서 이래저래 자료도 찾아보고 공부도 하고 있지만 해결되지 않아 이렇게 글을 올리게 되었습니다.

서버 프로세스는 클라이언트가 접속하면 쓰레드를 한개 생성하고

쓰레드와 클라이언트가 패킷을 주고 받는 동안

로그파일을 하나 생성해서 주고 받는 패킷에 대한 내용을 작성합니다.

파일 포인터는 써야 할 내용이 있을때

열고, 쓰고, 닫는 로직으로 되어 있습니다.

그런데 이 서버를 약 한달 정도 운영하면 Hang-Up에 빠집니다. (core 없이 client 요청 못받는 상태)

쓰레드가 만드는 로그 파일이 생성은 되지만 사이즈가 0인 것들이 한 일주일 뒤부터 생기면서

한달 즈음 지나면 쓰레드가 생성 요청하는 모든 파일이 생성은 되지만 내용은 아무 내용이 없는 사이즈 0인 파일만 존재하는 것입니다.


서버가 시작되고 Hang에 빠지는 기간 동안 제가 파악하는 유일한 징조는

로그 파일에 fprintf 결과가 나타나지 않는다는 것입니다.

(pfiles로 보면 fd 정상, thread수 정상, socket state 정상, prstat정보 정상, cpu 점유 정상)

도대체 이유가 뭘까요.

소스 전체적으로 다시 리뷰를 하고 있습니다 (Reentrant 검토, 자원 반화검토 중)

하지만 원인을 찾기가 너무 어렵네요.

아래 로그 남기는 로직을 한번 검토 부탁드립니다.

FILE*
_log_open_Statistics(char* fname)
{
	FILE *fp = NULL;
	struct tm pt;
	time_t cur_time;  
	time(&cur_time);
	localtime_r(&cur_time, &pt);	
 
	sprintf(fname, "%sLog_Statistics_%04d%02d%02d.txt",g_gonf1.log_dir, pt.tm_year + 1900, pt.tm_mon + 1, pt.tm_mday);
	fp = fopen(fname, "ab+");
	return fp;
}
 
void 
log_write_Statistics(unsigned char *str, int len)
{
	FILE *fpStatistics = 0x00;
	char fname[1024] = {0x00,};
 
	fpStatistics = _log_open_Statistics(fname);
	if(fpStatistics != 0x00)
	{
		fprintf(fpStatistics,"%s %d byte\n", str, len);
		fclose(fpStatistics);
	}
}

감사합니다.

익명 사용자의 이미지

혹시 디스크 full은 아닌가요?

dam808의 이미지

디스크는 정상입니다.

unsouled의 이미지

client 요청을 받지 못한다는 것으로 보아 혹시 어딘가 fd leak 이 발생해서
해당 프로세스에서 더 이상 fd 를 받지 못하는 상황이 된 게 아닐까요?

dam808의 이미지

pfiles로 찍은 내용을 보았는데 fd가 순차적으로 쌓이는 현상은 없었습니다. 하지만 한번 더 확인해 봐야겠네요

jick의 이미지

컴파일할 때는 -W -Wall 옵션 주고 하셨죠? (gcc가 아니면 컴파일 옵션이 다를 수도 있겠군요.)

fopen/fprintf/fclose 대신에 O_APPEND option 주고 open한 다음에 write, close를 쓰면 system call을 직접 부르니 로그가 좀 더 잘(?) 남을지도 모르겠습니다. 그렇게 하면 좀 더 원인을 파악하기 쉽지 않을까요?

areios의 이미지

조심스럽게 추측해봅니다.
혹시 스레드 안에 어딘가의 무한루프로 인해 스레드가 끝나지 않고 한 클라이언트에 점유된채로 남아있는건 아닐까요?

dam808의 이미지

무한루프는 없고 최대 3분정도의 loop 가 도는 로직은 있습니다. 쓰레드 안에서 또다른 쓰레드를 생성시키는 것이 껄끄러워
그냥 둔 부분입니다.

takabi의 이미지

안 닫힌 파일 포인터가 있는 것은 아닐까요?
열린 파일포인터가 계속 늘어나다가 최대값에 도달해서 작동을 멈추는 것은 아닌지요?

-----

dam808의 이미지

계속 모니터링 해봐야 될것 같네요.. 그래도 서버가 hang이 걸리는 정도라면 무언가가 눈에 띄게 쌓여 있어야 하는데 쌓여있는건 사이즈가 0인 파일들 뿐입니다.

trymp의 이미지

fopen() 같은 system call 이 항상 성공한다는 보장은 없으며,

system call 을 사용할 경우 실패시 errno 와 error string 을

꼭 디버그용도로 찍어두는게 중요하다고 봅니다.

fprintf 도 마찬가지고요,

multi-thread 라면 file write 시에 race condition 같은 것도 고려해야 할 것 같습니다.

이상 초보의 허접한 댓글이었습니다.

모지리의 이미지

개별 쓰레드마다 파일 fp를 열어서 사용하시는건가요?

파일 fp를 전역으로 설정해서 공유하는 방식으로 하시면 될거 같아 보입니다.

익명 사용자의 이미지

/proc 밑에 프로세스 아이디로 들어가셔서 fd 같은거 조사해보세요.. 릭이 있지 않나...

dam808의 이미지

제가 문제 해결하면 꼭 게시글 올리겠습니다.

먼저 io쪽 low level로 바꾸고 로그 찍어서 더 확인해 보겠습니다.

답변 감사드립니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.