2011-07-25 10 views
1

私はepollを使ってネットワーキングプログラミングを行っています。セグメンテーションフォールトエラーが発生しますが、マルチスレッドで実行されているため、ログを使用してエラーを正確に取得する場所を見つけるのは難しいです。マルチスレッドネットワークプログラムにgdbを使用するには

私はgdbを使用しようとしていたので、スタックトレースを見ることができます。これをgdbで実行すると、epoll_waitからこのエラーが発生します。別のクライアントからサーバーに接続しても、まったく動作しません。

私はそれがセグメンテーションフォールトエラーを取得する場所を事前に 感謝を見つけるためにGDBを使用することができますので、これをどのように修正すればよい。..

epoll_wait error 
: Interrupted system call 
+0

あなたはCまたはC++にいますか? – Puppy

答えて

3

EINTRを正しく処理するためにプログラムを修正する必要があります。 EINTR( "中断されたシステムコール")は致命的なエラーではありません。 「システムコールを再試行してください」という意味です。したがって、epoll_wait()を呼び出すコードはそれを検出し、呼び出しを静かに再試行します。このような何か:

int rv; 
do { 
    rv = epoll_wait(epfd, events, maxevents, timeout); 
} while (rv == -1 && errno == EINTR); 

それとも、あなたは一定のタイムアウトを持っている場合、あなたはそれをすべての呼び出し再計算する必要があります。

int rv; 
rv = epoll_wait(epfd, events, maxevents, timeout); 
while (rv == -1 && errno == EINTR) { 
    ...TODO: recalculate timeout here... 
    rv = epoll_wait(epfd, events, maxevents, timeout); 
} 

あなたがこのことを知っていなかった場合、あなたはおそらく、同じバグを持っているが他のシステムコールへの呼び出し。特にread()とwrite()だけでなく、他の多くの呼び出しも - あなたが使っている呼び出しのマニュアルページを調べて、EINTRがエラーの可能性があるかどうかを確認してください。

EINTRが起こらないようにするのは通常は実用的ではありません。シグナルを使用するライブラリを使用している場合や、シグナルを自分で使用している場合はEINTRを取得できます。前回私が見たところでは、Linuxスレッドライブラリはシグナルを使用していました。

2

お使いの環境でのコアダンプ保存を有効にします。コマンドulimit -c unlimitedを実行し、プログラムを再実行します。クラッシュすると、コアダンプがgdbにロードされ、クラッシュのバックトレースが表示されます。マルチスレッドプログラムの場合、一度に1つのコマンドですべてのスレッドからバックトレースを取得すると便利です:(gdb) thread apply all bt

関連する問題