이럴때 C언어 정말 싫어진다.

하하의 이미지

아래와 같은 경우 fopen 할때 SIGSEGV 가 발생하고 서버가 죽슴니다.

당근.. log_filename은 이런식으로 할당하였습니다.

char* log_filename; <- 전역변수

할당은

log_filename = (char *) strdup(buf);

이런식으로 되있습니다.

오해의 소지가 있을거 같아 얘기하지만 log_filename 에 널값이 들어

가 fopen 시 세트먼트 폴트가 나는 건 아니구요..

지금 만지고 있는 서버는 소스파일이 30개 정도 됩니다. 그래서 그런지

외부에 원인이 있는듯 추정하고 있지만. 아래와 같이 fopen에서 죽어 버리니

더이상 디버깅도 못해보겠고.. 암담 그자체 입니다.

어쩌면 좋을까요? .. 여러분의 의견을 듣고 싶습니다.. ㅠㅠ;;

(gdb) 
121                     if ( (fp = fopen(log_filename, "a")) == NULL ) {
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x400cd231 in chunk_free (ar_ptr=0x4017ec80, p=0xe7ed7d20) at malloc.c:3225
3225    malloc.c: No such file or directory.
        in malloc.c
Dr_stein의 이미지

ERRORS
       ENOMEM Insufficient memory available to allocate duplicate string.

man page에 이런 내용이 있네여... 웬지 별로 내키지 않는데...

앞마당 먹고 시작한 저그의 8할은 뮤탈 테크를 먼저 탄다. 하지만 나머지 2할때문에 항상 스켄이 모자란다. - _-;

하하의 이미지

위 fopen은 아주 빼버렸습니다.

그런데.. 뒤에 코드중. malloc을 사용하는 부분이 있는데..

아래와 같이

pszBuffer = (char *)malloc(MAX_ENC_LEN);

malloc 하는데 그냥 세그먼트 폴트가 나네요 ......

아무래도.. malloc을 잘 못 사용한듯 합니다.

메모리 할당의 무섬.. 톡톡히 보고 있슴다.

이런 경험 계신 분 있으시면.. ( ex. 메로리 할당 한거 보다

많이 썼을때 free 할때 문제가 발생할 수 있다. )

얘기해 주시면

많은 도움 될거 같습니다. 감사합니다. .. ^____^;;;

“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”

최종호의 이미지

purify를 써 보세요. ㅡ.ㅡ;;

ibm에서 평가판을 다운받으실 수 있을 것입니다.

http//www14.software.ibm.com/webapp/download/product.jsp?id=JGRM-5R7HWV&s=z&cat=&S_TACT=&S_CMP=

marten의 이미지

아래분의 대답이 맞는 것 같아서 내용을 지웁니다.
글 삭제는 어떻게 해야 하는지 모르겠네요..

mrchu의 이미지

fopen을 빼버렸는데도 폴트가 난다면...
소스코드의 더 앞부분에서 할당된 양보다 많은 메모리를 사용한 적이 있는것이 아닌가 의심이 가는군요.
전에도 strdup관련된 할당문제가 질문으로 올라온 적이 있었던것 같으니, 한번 검색해 보세요.
윗분 말씀대로 툴을 사용해서 체크해 보는것이 가장 쉬울 듯 하네요.

pynoos의 이미지

위의 에러는 십중 팔구는 대개 free를 두번한경우입니다.

$ export MALLOC_CHECK_
$ MALLOC_CHECK_=2
$ ./your_program

해서 잡아보시는 것이 ... 좋겠습니다.

saxboy의 이미지

아래 스레드 어딘가에 메모리 디버거에 관한 내용이 있었으니 참고하세요.

보통 pynoos님 말씀대로 free를 두번한 경우, 가끔 할당받은 메모리 overflow하는 경우가 대부분이지요. malloc에서 세그폴트 받는다고 멀쩡한 시스템 원망하는 분들 여럿 보았습니다. 이러지는 마세요.

youlsa의 이미지

리눅스에서 작업하시는거라면 간단하게 valgrind 한번 실행해서 잡으세요.

valgrind --leak-resolution=high --trace-malloc=yes --leak-check=yes --show-reachable=yes -v [프로그램 풀 경로]

이렇게 하시면 손쉽게 잡을 수 있습니다.

=-=-=-=-=-=-=-=-=
http://youlsa.com

하하의 이미지

purify 를 다운 받아 설치 해 보았습니다.

그런데.. 평가판에도 라이센스 키가 필요한거 같습니다.

    Searching for specific license keys in:
      /home/user/purify/config/Temporary.dat
    No specific licenses found.

    No specific licenses found in:
      /home/user/purify/config/Temporary.dat

이곳 저곳 뒤저 보아도 ..

깔아 보신 분 도움 부탁 드립니다.

평가판 라이센스키 알고 계신거 있으시면 알려주셔도 되구요.. ^^;;;

pynoos 님께서 알려주신 부분

Quote:

$ export MALLOC_CHECK_
$ MALLOC_CHECK_=2
$ ./your_program

해 보았습니다. 실행 도중 세그먼트 폴트는 나지 않고 그냥

종료가 되던데요?

위 내용은 환경 변수에 값을 셋팅하는 건데.. 이걸로 어떻게

하는지 .. 아직은 너무 초보라 위 설명만으론 잘 이해가 가질

않습니다. ㅠㅠ;;

또 youlsa 님께서 알려주신..

valgrind를 두번 정도 돌려 봤는데.. 이 툴 사용하는데 좀.

시간이 걸릴듯 합니다.. 괜찮으시면 간략한 사용법이라도 알려

주심 정말 감사하겠습니다....

“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”

하하의 이미지

valgrind 같은 경우.. 이 프로그램을

돌려놓고 프로그램을 돌려보면 정말

아무일 없듯 잘 돌아 가다가 그냥

쉘에서 실행 파일을 돌려보면 바로

폴트 떨어지고 그러거던요?

이놈의 프로그램이 지금 자기가 감시 당하고

있으니깐 잘 돌아야지 하다가 valgrind를 끄면

바로 폴트가 나니.. 이거야 원.. ..... ^___^;;;;;

“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”

하하의 이미지

valgrind 다시 사용하고 있습니다.

자세히 보니. 아래와 같이 데이터를 간간히

깨는 부분이 보입니다.

malloc[simd=1](6) = 0x40DE229C
==19456== Thread 2:
==19456== Invalid write of size 1
==19456==    at 0x8049BDE: get_header (clireq.c:45)
==19456==    by 0x8049D63: get_clireq (clireq.c:95)
==19456==    by 0x80492E7: gated_thread (dessvr.c:20)
==19456==    by 0x40266737: thread_wrapper (vg_libpthread.c:636)
==19456==    Address 0x40DE22A2 is 0 bytes after a block of size 6 alloc'd
==19456==    at 0x400473E4: malloc (vg_clientfuncs.c:100)
==19456==    by 0x8049B8D: get_header (clireq.c:35)
==19456==    by 0x8049D63: get_clireq (clireq.c:95)
==19456==    by 0x80492E7: gated_thread (dessvr.c:20)
==19456== 
==19456== Thread 2:
==19456== Invalid read of size 1
==19456==    at 0x402B06C3: __strtol_internal (../sysdeps/generic/strtol.c:441)
==19456==    by 0x402ADB13: atoi (../stdlib/stdlib.h:302)
==19456==    by 0x8049BF2: get_header (clireq.c:46)
==19456==    by 0x8049D63: get_clireq (clireq.c:95)
==19456==    Address 0x40DE22A2 is 0 bytes after a block of size 6 alloc'd
==19456==    at 0x400473E4: malloc (vg_clientfuncs.c:100)
==19456==    by 0x8049B8D: get_header (clireq.c:35)
==19456==    by 0x8049D63: get_clireq (clireq.c:95)
==19456==    by 0x80492E7: gated_thread (dessvr.c:20)
malloc[simd=1](364) = 0x40DE22D4
free[simd=1](0x40DE22D4)
malloc[simd=1](364) = 0x40DE2470
free[simd=1](0x40DE2470)
==19456==

“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”

youlsa의 이미지

하하 wrote:
valgrind를 두번 정도 돌려 봤는데.. 이 툴 사용하는데 좀.

시간이 걸릴듯 합니다.. 괜찮으시면 간략한 사용법이라도 알려

주심 정말 감사하겠습니다....


위에 제가 쓴 게시물에 있는 명령어대로 실행해보시면 실행이 끝난 다음에 malloc/free 된 메모리들에 대한 현황을 ERROR SUMMARY라는 이름으로 알려줍니다. leak된 것들이 있다면 어떤 종류이고 어떤 내용이 들어있는지 등등을 자세히 알려주니 그것을 보시면 디버깅이 손쉬울 겁니다. 혹 출력되는 메시지가 너무 많아 방해가 되면 --trace-malloc=yes 를 빼주셔도 이 경우에는 별 상관 없을겁니다. malloc/free 될때마다 뿌려주는 메시지를 출력안하는 것입니다.

만약 한번의 alloc에 대해 두번의 free가 가해졌다면 아래와 같은 메시지가 그 위치를 알려줍니다. 보시다시피 main.c의 52번째줄에서 이미 free한 메모리 블럭에 대해 main.c의 53번째줄에서 잘못된 free를 수행한 걸로 나옵니다.

ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==29279== 
==29279== 1 errors in context 1 of 1:
==29279== Invalid free() / delete / delete[]
==29279==    at 0x40025E87: free (in /usr/lib/valgrind/vgskin_memcheck.so)
==29279==    by 0x80489C3: main (main.c:53)
==29279==    by 0x4024190A: __libc_start_main (in /lib/libc-2.3.2.so)
==29279==    by 0x80488E0: (within /home/youlsa/src/montgomery/actiontag)
==29279==    Address 0x4109C024 is 0 bytes inside a block of size 200 free'd
==29279==    at 0x40025E87: free (in /usr/lib/valgrind/vgskin_memcheck.so)
==29279==    by 0x80489B2: main (main.c:52)
==29279==    by 0x4024190A: __libc_start_main (in /lib/libc-2.3.2.so)
==29279==    by 0x80488E0: (within /home/youlsa/src/montgomery/actiontag)
==29279== IN SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

=-=-=-=-=-=-=-=-=
http://youlsa.com

하하의 이미지

감사합니다.

valgrind가 원인을 잡았습니다.

^______^;; 이렇게 기쁠수가....

원인은.. 이거였습니다.

char *header[size];

header = (char *)malloc(size);

read(fd, header, size);

header[size] = 0x00; <------ 요놈이 주범이었습니다.

수정 header = (char *)malloc(size +1); 했습니다.

가장 하기 쉬운 실수라 들었는데.. 역시.. 저 또한 좀더 성장

하기 위한 통과의례라 생각하겠습니다..

답변 주신 모든 분께 감사.. ^^;;;;;;

“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”

raymundo의 이미지

하하 wrote:

char *header[size];

header = (char *)malloc(size);

read(fd, header, size);

header[size] = 0x00; <------ 요놈이 주범이었습니다.

수정 header = (char *)malloc(size +1); 했습니다.

해결하셨다니 다행입니다. size 만큼 잡으면 인덱스가 0 ~ size-1 까지니...

그런데 저 위 네 줄 중에 첫번째 줄은 실수로 들어간 거겠죠?

char * header;
header = (char *) malloc(size);

거나

char header[size];

거나 둘 중 하나여야겠죠. :-) 물론

char *header[size];
header[0] = (char *)malloc(size);

일 수도 있지만 이럴 의도였던 것은 아닌 것 같으니...

좋은 하루 되세요!

하하의 이미지

맞습니다.

char* header; 로 정정합니다..

“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.