HP-UX General
1820881 メンバー
3959 オンライン
109628 解決策
新規ポスト

getenv(3C)中にシグナル割り込みが発生した場合の動作

 
A_Ma
時折のコントリビューター

getenv(3C)中にシグナル割り込みが発生した場合の動作

どなたかご存知の方、ご教示下さい。

開発中のアプリケーションで、プロセスのデッドロックが発生しました。このプロセスをSIGABROTでkillし、coreを開いたところ、getenv(3C)の処理中にシグナル(SIGALRM)を受信し、そのシグナルハンドラ内でまたgetenv(3C)を呼び出した箇所で固まっていたように見えています。

getenv()の処理中にシグナル割り込みし、さらにそのシグナルハンドラ内でgetenv()をコールすることは、デッドロックが発生する要因となりえるのでしょうか?

(その後テストプログラムを作成してこのような衝突を頻繁に繰り返してみましたが、再現していません)
4件の返信4
nadachi
レギュラーアドバイザー

getenv(3C)中にシグナル割り込みが発生した場合の動作

あまり良い手ではありませんが、getenv()を使った小さなプログラムをarchive linkして、出来た実行形式ファイル上でコードを調べて見ました。

getenv: STW r2,-20(r30)

getenv+4: STW,MA r3,128(r30)

getenv+8: STW r4,-124(r30)

getenv+0xC: STW r5,-120(r30)

getenv+10: STW r6,-116(r30)

getenv+14: STW r7,-112(r30)

getenv+18: STW r8,-108(r30)

getenv+1C: STW r9,-104(r30)

getenv+20: STW r10,-100(r30)

getenv+24: ADDIL L%0xfffff800,r27,r1

getenv+28: LDW 1344(r1),r8

getenv+2C: COPY r26,r4

getenv+30: CMPB,= r0,r8,getenv+0x0044

 # 何か条件をテストして、

getenv+34: LDI 0,r3

getenv+38: ADDIL L%0x4000,r27,r1

getenv+3C: B,L __thread_mutex_lock,r2

 # __thread_mutex_lock()を呼び出している。

getenv+40: LDO 296(r1),r26

 ということから、推測ですが、multi-threadの

プログラムの場合は、環境変数に関わる mutex を

ロックしてから実際の仕事をしているのでは。

( __thread_mutex_lock()の呼び出しの前にあるチェックは、multi-thread環境かどうかのチェックだと思います。)

 そうだとすると、"getenv()の処理中にシグナルハンドラ内でまたgetenv()を呼び出したところ" というのは、この環境変数に関わる mutex を待っている部分では ?

nt
貴重なコントリビューター

getenv(3C)中にシグナル割り込みが発生した場合の動作

Deadlock の理由は nadachi さんの書かれている通りだと思います。

> getenv()の処理中にシグナル割り込みし、さらにそのシグナル

> ハンドラ内でgetenv()をコールすることは、デッドロックが発

> 生する要因となりえるのでしょうか?

sigaction(2) に signal-catching functions から安全に呼べる

function (signal safe function) の list がありますが、 getenv()

はその中にありません。(signal unsafe)

そしてそこには

> when a signal interrupts an unsafe function and the signal-catching

> function calls an unsafe function, the behabior is undefined.

と書かれています。 signal handler で getenv() を使うことが問題

のようです。



nadachi
レギュラーアドバイザー

getenv(3C)中にシグナル割り込みが発生した場合の動作

ntさんありがとうございます。なるほど、"getenv()"関数がsignal unsafeであると、man pageに書いてあるんですね。やっぱりコードを調べるのは良い手ではなかった。
A_Ma
時折のコントリビューター

getenv(3C)中にシグナル割り込みが発生した場合の動作

nadachi様、nt様、ありがとうございました。

ちょっと見てみたらsignal unsafeな関数山盛りで泣きそうです(+_+)。ちょっとずつなおして行かなきゃ…。