2012-04-27 11 views
4

終了スレッドハンドラスレッドが作業を行うための条件を待っています。シグナリングは、ワーカースレッドのデストラクタから実行されます。例外が他のスレッドで捕捉された後にスレッドが実行されたときに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を追加し、例外メッセージを出力しました。今やプロセスはコアにはなりませんでした。例外メッセージは、ワーカースレッドによって捕捉された例外メッセージと同じです。 私の質問は、このスレッドは他の人が捕まえた例外にどのようにアクセスするのですか?例外処理に関するデータ構造を共有していますか?

これにいくつか気を付けてください。

注:stacktraceごとに、call_unexpectedはrun()が呼び出された直後に発生します。これは、何とか例外スタックやデータが共有されていることに疑いを抱かせるものです。しかし、この振る舞いへの参照は見つかりませんでした。

+0

ました) "spec、例外を発生させる(フレーム4から)Heh!あなたが仕事を正しくしたい場合は、まずすべてのスペックを燃やしてください! –

+0

ええ!残念なことに、このクラスは共通のユーティリティクラスから継承しなければならず、そのため制限があります。 : – Vivek

+0

多分両方のスレッドがスローされたのですか?これは奇妙なコードです - スレッドのマイクロマネージメントのように見えます。 –

答えて

1

私は自分の質問に答えなければならない。

このSOスレッドはおそらく、対象としていますすべての例外をキャッチするためにスレッドを設定する方法について説明します。 この場合、TaskExitHandlerスレッドでデストラクタが呼び出されたことがありました。このデストラクタは、メインスレッドの例外を引き起こした同じ操作を実行していました。

TaskExitHandlerスレッドは投げられない(または予想される)ように設計されているため、try-catchブロックが存在しないため、例外が発生したときにプロセスが異常終了します。

デストラクタの呼び出しが暗黙的であったため、スタックトレースに表示されることはありませんでした。この例外リークを見つけるには、各オブジェクトを追跡する必要がありました。積極的な参加

みんなありがとう:)それは「スローを(使用して例外をスローしないことを指定し、この実行()関数のようですので、これは」いくつかの活性応答を得るために、私の最初の質問..

0

私は刺すようです - うまくいけば、これはあなたの研究を続けるのに十分なほどです。

私は、TaskExitHandlerを実行しているスレッドがすべてのワーカースレッドの親スレッドであると思われます。 TEHはそうでなければ子供たちと合流するために辛い時間を過ごすでしょう。

子/ワーカースレッドは、スローされた例外を処理していません。ただし、例外はどこかで処理するか、プロセス全体がシャットダウンする必要があります。親スレッド(別名TEH)は、例外を処理するためのプロセスのスタック/チェーンの最後の停止点です。あなたのサンプルコードは、TEHの例外処理は単に例外をスローするかどうかを示しています。だからそれはコアアウト。

必ずしも共有されるデータ構造ではなく、プロセス/スレッドIDとメモリ空間です。子スレッドは、親メモリと互いのメモリ/ヒープ領域を共有するため、ロックの目的でセマフォやミューテックスが必要です。

カプセル化が適切であると、ワーカースレッドは、表示されるすべての/すべての例外を処理できるほどスマートでなければなりません。これにより、親スレッドとプロセスツリーの残りの部分を削除する代わりに、個々のワーカースレッドを強制終了することができます。 OTWでは、TEHで例外を捕捉し続けることができますが、スレッドが例外を処理するための知識を持っていることはほとんどありません。

上記のことが明らかでない場合は、さらに説明していただければ幸いです。

私は少しの研究を行い、例外がスタックメモリではなくヒープメモリに対して生成されることを確認しました。あなたのプロセスのすべてのスレッドは同じヒープ*を共有します。なぜなら、子スレッドがそれをキャッチしないと、親スレッドが例外をなぜ見るのが理にかなっています(少なくとも私にとって)。 * FWIW、新しいスレッドを開始する代わりにプロセスをフォークすると、新しいヒープも取得されます。しかし、フォークは、すべてのヒープの内容を新しいプロセスにコピーするので、メモリに対する高価な操作です。 がcatching exceptions from another thread

+0

私はあなたの答えに私の上記のコメントを見ることができます。しかし、私は1つのスレッドがスローされ、例外は、別のスレッド(ことができます知っていると思います私は新しい質問を投稿していません。問題に関連する元の質問は同じでした。問題は解決しましたが、私の質問は答えられません:) – Vivek

関連する問題