[완료] Segmentation Fault 가 발생했습니다.
글쓴이: hyper9 / 작성시간: 토, 2010/02/20 - 5:47오전
문제가 발생한 곳은요 ~
아래와 같습니다. printf()을 실행할 때 바로 segmentation fault가 생깁니다.
. . SSL_CTX *ssl_ctx; . . . ssl_ctx = get_ssl_ctx(); printf("ssl_ctx->method = %x \n", ssl_ctx->method); . .
위의 code중에서 get_ssl_ctx() function의 내부에서 SSL_CTX 구조체를 초기화 합니다.
get_ssl_ctx() function은 대략 아래와 같은 모양입니다.
SSL_CTX *get_ssl_ctx() { SSL_CTX *ssl_ctx; . . printf("ssl_ctx->method = %x \n", ssl_ctx->method); return ssl_ctx; }
위와 같이 get_ssl_ctx()안에서 ssl_ctx->method를 print하면 제대로
보이지만, get_ssl_ctx()에서 return된 이후에 print를 하면
segmentation fault가 나는 이유가 뭘까요?
조언을 부탁드립니다.
어떻게 debugging을 시작해 보는 것이 좋을지 알려주시는 것도 역시 감사드립니다. ^^
Forums:
올려주신 소스의
올려주신 소스의
.
.
이 부분이 가장 의심이 가는군요..
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
왜 그렇게 생각하셨을까요?
제 설명이 부족했는지 몰라도 일단은 get_ssl_ctx() function은 SSL_CTX 구조체를 return하고 있고요
그 구조체를 return하는 "return ssl_ctx" 바로 직전에 ssl_ctx->method를 print했을 때, 제대로
초기화 된 값을 볼 수 있었고요.
그리고 get_ssl_ctx()에서 return된 값을 바로 get_ssl_ctx() function을 호출한 function에서
print했을 때, ssl_ctx->method를 print하면 segmentation fault가 발생했던 것인데요.
제 생각에는
.
.
부분은 그렇게 중요하다고 생각이 들지 않았거든요.
일단은 segmentation fault가 발생하는 바로 근처만을 올린 것이고,,
사실 .... 부분은 SSL_CTX를 초기화하는 부분입니다.
제 생각이 뭔가 틀린건지도 모르겠네요.
조언 부탁드립니다.
ssl context가 어떻게 선언되어 있는지 정보 부족이라서 단언할 수 없다는 뜻이겠죠.
즉 function 내부에서 ssl_ctx pointer가 가르키고 있는 부분이 stack(local variable)인지, heap memory alloc 영역인지, 아니면 기타이유인지 기존 code만 가지고 판단하기가 애매하다는 뜻이겠죠.
만일 ssl context 구조체(?)가 local 변수라면, get_ssl_ctx() return후 ssl_ctx pointer는 invalid하겠죠.
아 그렇군요 ^^
다시 확인해서 update하겠습니당. ~ ^^
약간 update했습니다.
위에 올렸던 내용 중에 잘못된 것이 있어서, 아래와 같이 수정했습니다.
아래에서 보시는 바와 같이 ssl_ctx2는 get_ssl_ctx() 바깥쪽에 static으로
선언되어 있었습니다.
생략된 부분은 주로 SSL_CTX에 내용을 채워넣은 초기화 과정입니다.
이걸 보면 위에서 조언을 주신 것처럼 일단 ssl_ctx2가 local은 아닌 것 같습니다.
조언 부탁 드립니다. 감사합니다. ~
간단한 에러가 아니라면 위해 여러 정보를 알려주시는 것이 답변달기에 좋습니다.
예를 들어
실행 platform과 버전
사용 compiler와 버전
관련 라이브러리와 버전
최대한 관련 정보를 제공할 수록 답변이 붙을 확률이 높아집니다.
딱히 문제가 되지 않는다면 생략된 code까지 올려주시거나, 같은 error가 발생하는 test code를 올려주시면 더 높아지겠죠.
ps)
google 검색을 해보니 OPEN SSL 라이브러리 관련 문제같군요.
google "SSL_CTX seg fault"로 올라온 답변들을 참조해보면
1) SSL_library_init();를 빼먹었는지 확인
2) SSL_CTX를 비롯해 여러 context가 적절히 설정되었는지 return code등으로 확인할 것
3) 일단 최적화 option을 off하고 debug mode에서 test
http://www.mail-archive.com/openssl-users@openssl.org/msg59073.html
한가지 제가 빼먹은 중요한 (?) 내용은요..
지금 이 code가 32bit machine에서 compile하고 실행했을 때는
문제가 없었는데,
64bit machine에서 문제가 생긴 상태입니다.
그리고 또 다른점은 ,,32bit machine은 Fedora 7이었고,
지금 64bit machine은 Fedora11 입니다.
따라서 SSL library와 gcc compiler도
32bit에서는 Fedora7에 있는 것으로
64bit에서는 Fedora11에 있는 것으로 사용했습니다.
다른 내용도 확인해서 update하겠습니다.
DDD/GDB를 사용해 봤습니다.
일단 get_ssl_ctx()함수가 return되기 직전에 ssl_ctx2의 값을 print해보면,,
0xfffffffff0002750 이라고 보입니다. (물론 이 address는 시도할 때마다 바뀌네요)
하지만 get_ssl_ctx()에서 return되고 난 후에 print해보면,
0xfffffffff0002750: Cannot access memory at address 0xfffffffff0002750이라고
나오네요..
아직 이유는 모르겠습니다.
저역시 . . . 부분이
저역시
.
.
부분이 중요하다고 추측됩니다..특히 '초기화'라고 하신부분이요.
예를 들면, 그럴린 없다고 생각하지만, get_ssl_ctx안에서
SSL_CTX ctx;
ssl_ctx = &ctx;
같은 엉터리 코드일지 아닐지 어찌 알겠습니까...
흐흐 ...가 범인이다에 한표
저도 스택 값의 주소를 포인터에 저장하여 리턴 했다에 한표겁니다.
정 애매모호하시면 valgrind를 돌려보시면 명확해질 듯 합니다.
get_ssl_ctx() 안에서,,,
return하고 있는 것은 ssl_ctx2인데요..
설사 말씀하신 엉터리 코드가 있어도,
return하고 있는 것이 ssl_ctx2이기 때문에 결과와는 아무 상관없다는
생각이 드는데요,,
제가 잘못생각하는 걸까요?
ssl_ctx2가 local이
ssl_ctx2가 local이 아니더라도 어디를 pointing하고 있느냐에 따라 충분히 문제가 생길 수 있습니다.
조만간,,간단한 sample code를 올리겠습니다.
이 문제를 똑같이 재현하는 sample code를 올리는 게 좋겠네요 ^^
다들 생각하시는 방향이 다를 수 있으니까요..
아마 하루 이틀내로 준비할 수 있을 것 같습니다.
갑자기 많이 바빠져서 ㅜㅜ
아뭏든 감사드립니다 ~
정말 제가 적은
정말 제가 적은 코드에서 무엇이 문제인지 모르시겠다면 변수의 범위에 대해 공부해보시는게 좋을것 같습니다-_-;;
ssl_ctx 라는 변수는
get_ssl_ctx()에서 사용되는 변수도 아니고,
물론 생략된 부분에 있을 거라고 추측을 하셨겠지만,
local에서 사용되다가 어떻게 되었더라도..
결국은 ssl_ctx2라는 변수가 return되는 것이라서
그렇게 생각했는데요..
뭔가 변수의 범위에 관해서 잘못알고 있는 걸까요?
혹시 이런건 아닐지...
위와 같은 경우 주소는 글로벌에 저장되어 있지만.. 실제 내용은 로컬이죠
답변 감사드립니다.
제가 다시 한번 확인후에 다시 글을 올리겠습니다.
정말 그 이유라면 시원할 것 같습니다. ^^
다시 감사드립니다 ~
heap으로 안 써서 그런거 같은데요
pointer에 malloc으로 heap메모리를 할당하고
초기화 하고 리턴하는지 확인이 필요할 것 같습니다.
드디어 source를 전체 올립니다 ^^
갑자기 바쁜일이 생겨서 늦어졌습니다.
일단 전체 source를 아래와 같이 올립니다.
file은 3개입니다.
첫번째 file인 main.c 입니다.
두 번째 file은 aaa.c 입니다.
세 번째 file은 aaa.c 입니다.
실행 결과는 예상하시겠지만,,,aaa.c의 두번째 print문에서 Segmentation Fault가 납니다.
실행환경은 Fedora 11 / 64bit 입니다.
하지만, 이 program들을 동일한 방법으로 Fedora 7/32bit에서 compile한 후 실행하면
Segmentation Fault없이 aaa.c의 두번째 print문이 성공적으로 잘 보입니다.
source 올리는게 늦어져서 죄송하고요,,조언 주시면 감사하겠습니다. ^^
좀 이상하게 보이는 부분이 있네요..
aaa.c의 두번째 print문은
printf("ssl_thread #2 [%x] \n", ssl_ctx->method); 입니다.
bbb.c의 print문은
printf("get_ssl_ctx [%x] \n", aaa_ctx->method); 입니다.
[bushi@rose tmp]$ ls
OTL
아..그렇군요..
감사합니다..이젠 잘 됩니다...
뭣 때문에 seg.fault가
뭣 때문에 seg.fault가 발생했는지 아셨습니까 ?
전,
ssl_ctx = get_ssl_ctx();
에서 행해진 묵시적인 형변환때문이라 생각하지만,
워낙 단촐한 코드를 올리셔서 확신을 할 수 없었습니다.
컴파일러가 분명히 경고를 했을텐데 그걸 무시하셨을리가 없으니까요.
뭐가 문제였었던겁니까 ?
OTL
get_ssl_ctx()의 extern declaration 이 ..
제 원래의 code에 없었는데, compiler가 경고를 하는 것 같지 않던데요.
올려주신 code를 보면서 비교해보고 get_ssl_ctx()의 extern declaration을 추가하고
난 후에 segmentation fault가 발생하지 않습니다.
그런데,,이게 Fedora 7에서는 문제없던 code였는데,
Fedora 11에서 문제가 생겼었고요.
더군다나 예전에 Fedora 7에서 문제가 없었기때문에 declaration을 제대로 살펴보지 않았던
것도 사실입니다.
선언이 되어 있지 않았을 경우에 Compiler의 행동이 Fedora 7에서와 Fedora 11에서의
경우가 다른 것 같다고 이해를 해버렸는데,,,
너무 쉽게 넘어가고 있는 것인지도 모르겠습니다.
코더가 가르쳐주지
코더가 가르쳐주지 않는다면, 컴파일러는
int get_ssl_ctx();
로 가정하고 컴파일합니다.
컴파일러가 가정한 이 코드는 sizeof(int)==sizeof(void*)인 모든 플랫폼에서 아무런 문제 없습니다.
64bit 에선 다릅니다.
http://kldp.org/node/103442#comment-478641 에 다른 분의 경험담이 있습니다.
OTL
-Wall 옵션을 넣어도
-Wall 옵션을 넣어도 경고가 안나오나요? 기억이 잘... 나중에 실험해보고 다시 글 올릴께요~
----
Let's shut up and code.
----
Let's shut up and code.
아..그렇군요...
그건 좋은 정보이네요.
감사합니다. ^^
댓글 달기