1748000 メンバー
4823 オンライン
108757 解決策
新規ポスト

プロセス停止

 
kohji
新しいメンバー

プロセス停止

HP-UX11iv2 においてプロセスが CORE を吐くことなく停止してしまう現象が発生しています。

アプリケーションがやや複雑なので原因を特定できていないのですが...。

TCP ストリームに対してデータを send しているときに、LAN ケーブルを切断するなどして、更にデータを送り続けると SNDBUF が満杯になりブロッキングモードで捕まります。

この状態で、他のスレッドから該当するソケットを close すると、このタイミングでどうやらプロセスが停止してしまうように見えます。

このような現象になられた方はいらっしゃいますか?

具体的な回避策を検討したいのですが。

6件の返信6
uhyo
貴重なコントリビューター

プロセス停止

停止というのは、ハングのことですか?それともプロセスが消滅するということですか?

ハングでないとすると、検討違いの意見になってしまう可能性が高いのですが、そもそもソケットのcloseは何の関数を使ってらっしゃいますか?

もちろんそれはスレッドセーフな関数ですよね。

以前、スレッド間でファイルポインタの操作をして

誤ってミューテックスロック状態になったというのを

聞いたことがあったもので。
kohji
新しいメンバー

プロセス停止

停止というのは消滅です。

親プロセスで wait していないのでゾンビになっています。

close は close(2) を使用しています。

send も同様に send(2) です。

よろしくお願い致します。
oops
貴重なコントリビューター

プロセス停止

カーネルから送る動機的なシグナル(アドレス違反の SIGSEGV等)の場合、デフォルトの動作では必ずコアが作成されます。特にシグナルに対する動作を何も決めていないのであれば、外部から kill() などをされた可能性が高いと思います。

アプリを改変できるなら、該当スレッドが所属するプロセス内で、sigwait() 等によりシグナルを待っている専用スレッドを用意することはできませんか?

そこでとりあえず全部のシグナルを受信して、ログにシグナル番号と時間とかを書き出すといいと思うのですが。
kohji
新しいメンバー

プロセス停止

シグナルはすべてデフォルトなのでCOREを作る筈なのです。kill()でいろいろなシグナルを出してみましたが、その場合は作成されます。

もう少し厳密に書くと、socket()で作成したディスクリプタdに対してconnect()した後、データを送信するスレッドT1がsend()を行います。

同時にセッション状態の監視のため、ディスクリプタdに対して別のスレッドT2がselect()をかけます。

この状態でTPケーブルを抜いて送信を継続するとSNDBUFが満杯になり、ブロッキングモードのsend()がリターンしなくなります。

やがてkeepaliveのタイムアウトになり、select()にイベントが上がります。(keepaliveオプションを指定しています)

切断を検知したという意味で、スレッドT2はディスクリプタdに対してclose()を行います。

このときスレッドT1のsend()は捕まったままだと思われます。

この後、このプロセスがpsで表示されなくなりゾンビになります。
nt
貴重なコントリビューター

プロセス停止

close された socket に対して send() をして SIGPIPE を受け取って

死んでいるのではないですか?

T1 が send() で block

T2 が select() から抜けて socket を close

T1 が send() から error return

T1 が error check をせずに再び send() (??)

send() が EPIPE を返すとともに SIGPIPE を送る

SIGPIPE は core を作りません。

kohji
新しいメンバー

プロセス停止

そのとおりでした。

ありがとうございました。