2012-04-27 2 views
4

작업 스레드가 작업을 수행하기위한 조건에서 대기하는 종료 처리기 스레드가 있습니다. 신호는 작업자 스레드의 소멸자에서 수행됩니다.예외가 다른 스레드에서 catch 된 후에 스레드가 실행될 때 SIGABRT로 프로세스가 중단됩니다.

다음은 종료 처리기 스레드의 코드입니다.

void Class::TaskExitHandler::run() throw() 
{ 

while(! isInterrupted()) { 

    _book->_eot_cond.wait(); // Waiting on this condition 
    { 
     CLASS_NAMESPACE::Guard<CLASS_NAMESPACE::FastLock> eguard(_book->_exitlist_lock); 

     list<TaskGroupExecutor*>::const_iterator itr = _book->_exited_tasks.begin(); 

     for(; itr != _book->_exited_tasks.end(); itr++) { 
      (*itr)->join(); 
      TRACER(TRC_DEBUG)<< "Deleting exited task:" << (*itr)->getLoc() << ":" 
        << (*itr)->getTestID() << ":" << (*itr)->getReportName() << endl; 
      delete (*itr); 
     } 
     _book->_exited_tasks.clear(); 
    } 
    _book->executeAny(); 
} 
} 
} 

자, 관찰 된 것은 작업자 스레드 (하층에서 발생) 예외를 캐치 할 때,이 스레드가 계속되도록하고, 즉시 SIGABRT이다 종료 코드 (134)와 코어. 그래서 "던져()"를 사용하여 예외가 발생하지 않도록 지정이 실행() 함수는 스펙, 프레임 4에서 (예외가 발생 것 같다

#0 0x0000005555f49b4c in raise() from /lib64/libc.so.6 
#1 0x0000005555f4b568 in abort() from /lib64/libc.so.6 
#2 0x0000005555d848b4 in __gnu_cxx::__verbose_terminate_handler() from /usr/lib64/libstdc++.so.6 
#3 0x0000005555d82210 in ??() from /usr/lib64/libstdc++.so.6 
#4 0x0000005555d82258 in std::terminate() from /usr/lib64/libstdc++.so.6 
#5 0x0000005555d82278 in ??() from /usr/lib64/libstdc++.so.6 
#6 0x0000005555d81b18 in __cxa_call_unexpected() from /usr/lib64/libstdc++.so.6 
#7 0x0000000120047898 in Class::TaskExitHandler::run() 
#8 0x000000012001cd38 in commutil::ThreadBase::thread_proxy() 
#9 0x0000005555c6e438 in start_thread() from /lib64/libpthread.so.0 
#10 0x0000005555feed6c in __thread_start() from /lib64/libc.so.6 
Backtrace stopped: frame did not save the PC 

follows-로

는 스택 트레이스는). __cxa_call_unexpected()에 대한 다양한 참조에 따라 stacktrace는 "throw()"사양의 함수에서 예외가 발생할 때 중단 할 컴파일러의 일반적인 동작을 보여줍니다. 문제의 분석에 맞습니까?

테스트하려면이 메서드에서 try catch를 추가하고 예외 메시지를 인쇄하십시오. 이제 그 과정은 핵심이 아니 었습니다. 예외 메시지는 작업자 스레드가 포착 한 메시지와 동일합니다. 제 질문은이 스레드가 다른 스레드에 의해 잡힌 예외에 어떻게 접근 할 수 있습니까? 예외 처리와 관련된 일부 데이터 구조를 공유합니까?

이 부분을 밝혀주세요. 그것은 아주 수수께끼입니다 ..

주가 : - 스택 트레이스 당으로, call_unexpected이라고합니다() 실행 후 즉시 발생합니다. 그것은 어떻게 든 예외 스택이나 데이터가 공유된다는 나의 의구심을 강화시킵니다. 그러나이 행동에 대한 언급을 찾지 못했습니다.

+0

'였습니다이 ("던져를 사용하여 예외가 발생하지 않도록 지정이 실행() 함수) "spec, 예외 (프레임 4에서) 발생 Heh! 당신이 일을 제대로 끝내고 싶다면, 모든 사양을 먼저 태우십시오! –

+0

예! 불행하게도이 클래스는 일반적인 유틸리티 클래스를 상속해야하므로 제한이 있습니다. : – Vivek

+0

아마 두 스레드가 모두 던져 졌을까요? 이상한 코드입니다 - 스레드 마이크로 관리처럼 보입니다. –

답변

1

난 내 자신의 질문에 대답한다

이 SO 스레드는 아마도 관심을 모든 예외를 잡기 위해 스레드를 설정에 대해 설명합니다. 이 경우 TaskExitHandler 스레드에서 소멸자가 호출되었습니다. 이 소멸자는 주 스레드에서 예외를 발생시키는 동일한 작업을 수행하고있었습니다.

TaskExitHandler 스레드가 throw (또는 예상)하지 않도록 설계되었으므로 try-catch 블록이 없으므로 예외가 발생할 때 프로세스가 중단되었습니다.

소멸자의 호출이 암시 적이기 때문에 스택 추적에 절대로 표시되어 절대로 발견하기가 어렵습니다. 이 예외 유출을 찾기 위해 각 객체를 추적해야했습니다. 보인다 그래서 적극적인 참여 : 대한

감사합니다 모든 사람이 약간의 활성 반응을 얻을 내 첫 번째 질문 ..

0

나는 찌르겠다. 당신의 연구를 계속할 수 있기를 바란다.

TaskExitHandler가 실행중인 스레드가 모든 작업자 스레드의 상위 스레드라고 의심됩니다. TEH는 그렇지 않은 아이들과 합류하기 위해 힘든 시간을 보냈습니다.

하위/작업자 스레드는 예외를 처리하지 않습니다. 그러나 예외는 어딘가의으로 처리해야합니다. 그렇지 않으면 전체 프로세스가 종료됩니다. 상위 스레드 (일명 TEH)는 예외 처리를위한 프로세스 스택/체인의 마지막 중지 지점입니다. 샘플 코드는 TEH의 예외 처리가 단순히 예외를 처리하거나 처리하지 않는다는 것을 보여줍니다. 그래서 밖으로 코어.

반드시 공유되는 데이터 구조가 아니라 프로세스/스레드 ID 및 메모리 공간입니다. 자식 스레드는 부모 및 서로간에 전역 메모리/힙 공간을 공유하므로 잠금 용도로 사용되는 세마포 및/또는 뮤텍스가 필요합니다.

좋은 캡슐화는 작업자 스레드가 어떤/그들이 볼 수있는 모든 예외를 처리 할 수있을만큼 똑똑해야한다고 지시한다. 이렇게하면 개별 스레드를 부모 스레드와 나머지 프로세스 트리를 종료하는 대신 강제 종료 할 수 있습니다. OTW에서는 TEH에서 예외를 계속 catch 할 수 있지만 스레드가 예외 처리에 대한 지식을 갖고있을 가능성은 거의 없습니다.

위의 내용이 분명하지 않은 경우 의견을 추가하시면 더 자세히 설명 드리겠습니다.

약간의 연구를했으며 스택 메모리가 아닌 힙 메모리에 대해 예외가 생성되었음을 확인했습니다. 프로세스의 모든 쓰레드는 같은 힙 *을 공유하기 때문에 자식 쓰레드가 그것을 잡을 수 없을 때 부모 쓰레드가 예외를 볼 수있는 이유는 (적어도 나에게) 더 이해가된다. * FWIW, 새로운 스레드를 시작하는 대신 프로세스를 포크하면 새로운 힙을 얻게됩니다. 그러나 포크는 모든 힙 내용을 새 프로세스로 복사하기 때문에 메모리에 대한 비용이 많이 드는 작업입니다. 이 catching exceptions from another thread

+0

설명이 맞는 것입니다.하지만 여기에 해당되지 않습니다. 내 문제에 대한 대답을 식별했습니다. 당신은 대답에 대한 내 위의 주석을 볼 수 있습니다.하지만 한 스레드가 throw 및 예외, 다른 스레드 (부모가 아니라 형제)이 그것을 잡을 수 있습니까? 나는 새로운 질문을 게시하지 않습니다. 문제와 관련된 원래 질문은 동일했습니다. 문제는 해결되었지만 내 질문에 대답하지 못했습니다 :) – Vivek