[질문] 스레드 사용 시에 메모리 오류.
멀티플랫폼용 코드를 개발 중에 있습니다.
리눅스, SUN, HP, IBM 용으로 개발 중인데,
pthread를 쓰고 있습니다.
A, B, C, D 라는 라이브러리가 있고C에서 스레드를 이용하여 독립적인 D라는 라이브러리를 로드해서 그 라이브러리 내의 함수를 하나 호출합니다.
이 때, D를 로드하고 함수를 호출하는 과정을 스레드로 구현하였습니다.
이 과정이 리눅스와 SUN에선 잘 되는데
HP와 IBM에서 말썽이더군요.
IBM의 경우에는 로드된 D 라이브러리 내에서 segmentation fault가 생기고
HP의 경우에는 D의 함수를 호출하고 리턴된 후에 C에서 segmentation fault가 생깁니다.
segmentation fault가 생기는 부분은 정말 이해가 안가는 부분에서 생깁니다. 특별히 이상한 동작을 하는 것도 아니고 list내의 값들을 모두 비우는 (remove) 작업이라던지, 단순히 string을 더한다던지 하는 곳입니다.
근데 만일 스레드를 사용하지 않고 위의 과정을 구현하면 아무 문제없이 돌아가더군요.
-> 이러한 이유로 스레드를 사용할 때 스레드를 사용하는 쪽(C)과 스레드를 통해 사용되는 쪽(D)가 서로 메모리를 침범하는게 아닌가 라는 의문을 가졌습니다.
IBM 에서 사용하는 옵션은 다음과 같습니다.
컴파일 시: -D_REENTRANT -qthreaded -qsmp -q64 -c -qrtti=all -w
링크 시 : -D_REENTRANT -qthreaded -qsmp -q64 -G -qmkshrobj
HP에서 사용하는 옵션은 다음과 같습니다.
컴파일 시: -mt -c +DD64 +DA2.0W -I ../include +Z+Oinitcheck -AA
링크 시 : -mt -AA +DD64 +DA2.0W -b -o
대체 어떤 작업을 해줘야 하는지 감이 안옵니다. T_T..
이번주내로 작업은 마쳐야 하는데 말이죠 흑..
도움 부탁드립니다.
참고로 HP에서 에러가 났을 때의 stack은 다음과 같습니다.
#0 0x800003ffbffe1044 in pthread_mutex_lock+0xc () from /usr/lib/pa20_64/libpthread.1 #1 0x800003ffbc17b390 in __thread_mutex_lock+0x80 () from /usr/lib/pa20_64/libc.2 #2 0x800003ffbc1625dc in printf+0x184 () from /usr/lib/pa20_64/libc.2 #3 0x800003ffbca08644 in CTestClass::TestFunc1 ( this=0x800000010018fc60, strFile=@0x800003ffba3883e8) at TestClass.cpp:1896 #4 0x800003ffbca07b44 in CTestClass::TestFunc0 ( this=0x800000010018fc60) at TestClass.cpp:1816 #5 0x800003ffbca079ec in CreateThread (pPara=0x80000001000541d8) at TestClass.cpp:1801 #6 0x800003ffbffde250 in __pthread_body+0x50 () from /usr/lib/pa20_64/libpthread.1 #7 0x800003ffbffe8b0c in __pthread_start+0x14 () from /usr/lib/pa20_64/libpthread.1
Re: [질문] 스레드 사용 시에 메모리 오류.
힙이 깨졌을때 생기는 문제로 보이네요. 해제된 메모리를 쓰거나 읽는 부분이 있을거라고 생각됩니다.
싱글 스레드에서는 메모리가 해제될 때 힙에 '사용가능'표시만 하고 다른 수정은 하지 않기 때문에 메모리를 해제한 뒤에 다시 할당하기 전까지 해제된 메모리를 엑세스해도 웬만해서는 문제가 생기지 않지만, 멀티 스레드에서는 한쪽 스레드에서 메모리를 해제하고 나서 그 메모리를 엑세스하려고 할 때 다른쪽 스레드에서 메모리를 할당하면 쓰레기값이 읽히고 힙이 깨지는 경우가 많지요. 특히 객체를 값으로 넘기거나 리턴받는 경우에 보이지 않는 임시 객체가 생기거나 하는 부분을 유의해서 살펴보시기 바랍니다.
또는 표준 함수나 라이브러리 함수들 중에 thread-unsafe한 코드가 있을 수 있습니다. 보통 유저가 포인터를 넣지 않았는데 포인터를 리턴해주는 시간 체크류 함수나 기타 다른 함수의 경우죠. 표준 함수의 경우 힙이 깨지는 사태는 잘 일어나지 않지만 쓰레기값이나 엉뚱한 값이 나오는 경우가 많고, 라이브러리 함수중에 그런 코드가 있다면 라이브러리 문서를 잘 살펴보거나 라이브러리 제작자에게 멀티스레드 환경에 대해 문의해보는 수밖에 없겠지요. (실제로 상용의 모 게임엔진이 멀티스레드를 고려하지 않고 제작되어 큰 문제가 된 적도 있습니다.)
댓글 달기