2011-10-07 5 views
5

하위 스레드에 가입하는 동안 세그멘테이션 오류가 발생했습니다. 스택 오버플로 및 나머지 인터넷에서 디버깅에 대해 생각할 수있는 모든 옵션을 모두 고갈 시켰습니다! :) 내가 할 수있는 한 철저하게 이 될거야. 이 코드는 C++로 작성되었으며 OSX 10.6.8에서 GNU GCC로 컴파일되었습니다. 필자는 '-pthread'매개 변수를 사용하여 'pthread'라이브러리에 링크했습니다. 나는 또한 '-ltread'를 시도했다. 차이 없음.OSX에서 세분화 오류로 인해 pthread_join이 일시적으로 중단됨

pthread_t gTid; 

pthread_attr_t gAttr; 

int gExitThread = 0; 

나는 실행 내 메인 스레드에서 자식 스레드를 만드는거야 : 다음

err = pthread_attr_init(&gAttr); 
if (err) 
{ 
    throw CONTROLLER_THREAD_ERROR; 
} 

err = pthread_attr_setdetachstate(&gAttr, PTHREAD_CREATE_JOINABLE); 
if (err) 
{ 
    throw CONTROLLER_THREAD_ERROR; 
} 

err = pthread_create(&gTid,&gAttr,threadHandler,NULL); 
if (err) 
{ 
    throw CONTROLLER_THREAD_ERROR; 
} 

내부 'threadHandler', 나는이를 나는 다음과 같은 전역 변수를 사용하고

핵심 기초 API를 사용하여 루프를 실행합니다.

// Enter run loop 
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, RUN_LOOP_TIMEOUT, false); 
while (result == kCFRunLoopRunTimedOut) 
{ 
    if (gExitThread) break; 
    result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, RUN_LOOP_TIMEOUT, false); 
} 

gExitThread 전역 변수가 사용되었습니다. 스레드가 정상적으로 을 죽여야한다는 신호를 보냅니다. RUN_LOOP_TIMEOUT 매크로는 2 초로 설정됩니다 (큰 값과 작은 값은 차이가 없음).

스레드

는 메인 스레드에서 다음 코드 조각에 의해 살해하라는 지시를 내 렸습니다된다

int err = 0; 
void* exitValue = NULL; 

printf("Stopping controller thread...\n"); 

gExitThread = 1; 
err = pthread_join(gTid, &exitValue); 
if (err) 
{ 
    displayError2(err); 
    throw CONTROLLER_THREAD_ERROR; 
} 

err = pthread_attr_destroy(&gAttr); 
if (err) 
{ 
    throw CONTROLLER_THREAD_ERROR; 
} 

'pthread_join을'에 대한 호출은 잠시 후 세그먼트 오류와 충돌합니다. 또한 'pthread_join'호출을 보통 sleep로 바꾸는 것이 2 초라고 말하면서 'usleep (2000000)'을 실행할 때 정확히 같은 세그먼테이션 오류를 일으킨다는 것을 알았습니다! 아래 'pthread_join'과 'usleep'에 대한 코어 덤프의 백 추적을 복사합니다.

pthread_join을 :

#0 0x00007fff8343aa6a in __semwait_signal() 
#1 0x00007fff83461896 in pthread_join() 
#2 0x000000010000179d in Controller::cleanup() at src/native/osx/controllers.cpp:335 
#3 0x0000000100008e51 in ControllersTest::performTest (this=0x100211bf0) at unittests/src/controllers_test.cpp:70 
#4 0x000000010000e5b9 in main (argc=2, argv=0x7fff5fbff980) at unittests/src/verify.cpp:34 

usleep (2000000) : 어떤 도움이 크게 감사합니다

#0 0x00007fff8343aa6a in __semwait_signal() 
#1 0x00007fff8343a8f9 in nanosleep() 
#2 0x00007fff8343a863 in usleep() 
#3 0x000000010000177b in Controller::cleanup() at src/native/osx/controllers.cpp:335 
#4 0x0000000100008e3d in ControllersTest::performTest (this=0x100211bf0) at unittests/src/controllers_test.cpp:70 
#5 0x000000010000e5a5 in main (argc=2, argv=0x7fff5fbff980) at unittests/src/verify.cpp:34 

.

답변

8

threadHandler 안에있는 while 루프의 코드가 segfault를 일으키는 것으로 보입니다. 스레드 내에서 신호 (예 : SIGSEGV)가 생성되면 프로세스 자체가 종료됩니다.

모든 스레드에 대해 백 트레이스를 얻으려면 GDBthread apply all bt을 사용해보십시오.

+0

밀라노에 감사드립니다. 그게 바로 그거야! 내 스레드에서 클래스 유형에 대한 NULL 포인터를 캐스팅 한 다음 해당 인스턴스의 데이터 멤버에 액세스 할 때 충돌했다는 것을 알 수 있습니다. 고정되어있을뿐만 아니라 스레드와 gdb에 대해 좀 더 알고 있습니다 :) – lawrenceB

관련 문제