問題タブ [sigaction]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - OS X sigaction が sa_mask を誤って設定する
Macbook (OSX 10.9.5 (13F34)) では、次の簡単なプログラム:
不思議なことに次のように表示されます:
sa_mask
のメンバーが で与えられたosa
ように一致することを期待します。mask
sigprocmask
POSIX はこのフィールドの要件を指定していますか? SIGKILL
マンページでの唯一の言及は、その値が指定されていないのようなブロックできないシグナルに関するものです。
Linux では、このプログラムは以下を出力します。
予想通り。
gcc のバージョンは次のとおりです。
バイナリは以下に対してリンクされています。
macos - sigaction および setitimer システム コールを使用して BSD/OS X にアセンブリ言語タイマーを実装する
sigaction() & setitimer() システム コールを使用して、OS X Lion の 32 ビット アセンブラでタイマー ルーチンを実装しようとしています。アイデアは、setitimer() を使用してタイマーを設定し、生成されたアラーム信号が、sigaction() によって以前に設定されたハンドラー関数を呼び出すようにすることです。私は Linux で動作するこのようなメカニズムを持っていますが、OS X で動作するようには見えません。OS X と Linux ではシステム コールの規則が異なり、OS X には 16 バイトのアラインメント要件があることを知っています。これらを補っているにもかかわらず、私はまだそれを機能させることができません (通常は "Bus error: 10" エラー)。アラインメントに何か問題があったと考えて、私が望むことを実行する単純な C プログラムを作成し、clang 3.2 を使用してアセンブリ コードを生成しました。次に、sigaction() & への呼び出しを置き換えることで、機械で生成されたアセンブリを変更しました。setitimer() に適切な system & int $0x80 呼び出し、およびスタック アライメント命令を使用します。結果のプログラムはまだ機能しません。
アセンブリの生成に使用した C プログラム sigaction.c を次に示します。結果のアセンブリコードが読みやすくなるように、 printf と sleep をコメントアウトしたことに注意してください。
}
上記のファイルで「clang -arch i386 -S sigaction.c」を使用して生成されたアセンブリ コードを次に示します。
「clang -arch i386 sigaction.s -o sigaction」を使用してアセンブリ コードをコンパイルし、lldb を使用してデバッグし、ハンドラ関数にブレークポイントを配置すると、実際にハンドラ関数が毎秒呼び出されます。したがって、アセンブリ コードが正しいことはわかっています (C コードについても同様です)。
sigaction() の呼び出しを次のように置き換えると:
および setitimer() の呼び出し:
アセンブリ コードが機能しなくなり、手動でコーディングしたアセンブリ コードと同じ "Bus error: 10" が生成されます。
スタックをアラインするために使用している subl/addl 命令を削除し、値を変更してスタックが 16 バイト境界にアラインされるようにしましたが、何も機能していないようです。バス エラー、セグメンテーション フォールトが発生するか、ハンドラー関数を呼び出さずにコードがハングします。
デバッグ中に気づいたことの 1 つは、sigaction 呼び出しが、基になるシステム コールの周りに長いラッパーを持っているように見えることです。lldb 内から両方の関数を逆アセンブルすると、sigaction() には長いラッパーがありますが、setitimer にはありません。これが何かを意味するかどうかはわかりませんが、sigaction() ラッパーがデータを渡す前にデータを処理している可能性があります。そのコードをデバッグしようとしましたが、まだ決定的なものは見つかりませんでした。
sigaction() および setitimer() 関数を適切なシステム コールに置き換えることで、上記のアセンブリ コードを機能させる方法を知っている人がいれば、大歓迎です。次に、これらの変更を取得して、手作業でコーディングしたルーチンに適用できます。
ありがとう。
更新: 手書きのアセンブリ コードを扱いやすいサイズに縮小し、sigaction() & setitimer() ライブラリ呼び出しを使用して動作させることができましたが、syscall が動作しない理由はまだわかりません。コードは次のとおりです(timer.s):
「clang -arch i386 timer.s -o timer」でコンパイルし、lldb でデバッグすると、ハンドラー ルーチンが毎秒呼び出されます。コード内の syscall を使用してコードを機能させる努力をやめました。それらは sigaction() および setitimer() 呼び出しの周りでコメントアウトされています。自分自身 (および他の人) を教育する以外の理由がない場合でも、可能であればシステム コールのバージョンを機能させたいと考えています。
再度、感謝します。
更新 2: setitimer syscall が機能するようになりました。変更されたコードは次のとおりです。
しかし、同じ編集は sigaction sys コールでは機能しません。これにより、最初の結論に戻ります。sigaction() ライブラリ関数は、実際の syscall を行う前に特別なことを行っています。dtruss からのこのスニペットは、同じことを示唆しているようです:
sigaction() syscall を使用 (動作していません):
sigaction() ライブラリ呼び出し (動作中):
ご覧のとおり、2 つのバージョンで 2 番目の引数が異なります。syscallではsigaction構造体(0x2030)のアドレスがそのまま渡されているようですが、ライブラリコールでは別のものが渡されています。「何か他のもの」が sigaction() ライブラリ関数で生成されていると推測しています。
更新 3: FreeBSD 9.1 にもまったく同じ問題が存在することがわかりました。setitimer システムコールは機能しますが、sigaction システムコールは機能しません。OS X と同様に、sigaction() ライブラリ呼び出しは機能します。
BSD にはいくつかの sigaction syscall があります。これまでのところ、OS X で使用していたのと同じ 0x2e のみを試しました。おそらく、他の sigaction システムコールの 1 つが機能するでしょう。BSD にも同じ動作があることを知っていれば、C ソース コードを引っ張ることができるので、追跡が容易になります。さらに、これにより、問題が何であるかをすでに知っている可能性のある、より幅広い人々のグループに問題が開かれます。
syscall がどのように機能するかについての私の理解と、Linux で sigaction が機能するという事実に基づいて考えると、自分のコードで何か間違ったことをしていると思わざるを得ません。ただし、 int $0x80 呼び出しを sigaction() ライブラリ関数に置き換えるとコードが機能するという事実は、これと矛盾しているようです。FreeBSD 開発者マニュアルには、アセンブリ言語プログラミングに関する章全体と、システム コールの作成に関するセクションがあるため、私が行っていることが可能になるはずです。
https://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/x86-system-calls.html
誰かが私が間違っていることを指摘できない限り、次のステップは sigaction() の BSD ソースを調べることだと思います。前に述べたように、OS X で sigaction の逆アセンブル バージョンを調べたところ、他のシステム コールに比べて非常に長く、マジック ナンバーでいっぱいであることがわかりました。うまくいけば、C コードを見ることで、それが機能する原因が明らかになるでしょう。最終的には、間違った sigaction 構造体 (いくつかあります) を渡すか、どこかにビットを設定するのに失敗するなど、単純なことである可能性があります。
signals - 「signal()」の代わりに「sigaction()」を使用する場合 (およびその理由) は?
システム関数 signal() と sigaction() を深く調べています
これら 2 つの関数に関するいくつかのページを読みましたが、主に移植性と「競合状態がない」という違いについて説明していました。
誰かが私のためにこれらを明確にすることができますか?
ps 制御信号を変更しようとしているときに、signal() 関数ではなく sigaction() 関数を使用するように案内されました。何故ですか?
どんな助けでも大歓迎です。君たちありがとう!!
c - ハンドラーに到着する複数のシグナル
いくつかの子プロセスをフォークしたメインプロセスがあります。
それぞれの子供は何かをして、自分自身をブロックします。自分自身をブロックすることにより、すべての子SICHLD
は親プロセスにシグナルを送信します。
また、子供たちが送信sigaction
する をキャッチするために、メイン プロセス コードでアクションを宣言しました。SIGCLHD
SIGCHLD
ハンドラーが呼び出されると、どの子供がシグナルを送信したかを確認し、そのSIGCHLD
子供のために何かを行います。
問題は、複数の子供が同時に信号を送信するとどうなるかということです。kid(1) が を送信したとしましょうSIGCHLD
。ハンドラーはそれをキャッチし、ハンドルを完了する前に、 kid(2) と kid(3) の両方がシグナルを送信します。kid(1) の処理が終わった後、ハンドラーはこれらのシグナルごとに実行されますか、それともこれらのシグナルは無視されますか?
c++ - sigaction 処理後に入力を待つ正しい方法 ctrl+c 別名 SIGINT
Ctrlこのプログラムは、 +経由で SIGINT を送信した後、無限の "Enter a:" をコマンド ラインに出力しCます。このループを終了するには、Ctrl+を使用します\。を含む行のコメントを外すとstd::cin.clear();
、すべて正常に動作します。私の質問は、これは正しい方法ですか?std::cin.clear();
プログラムを待機させたいすべての cin/cout の前に設定する必要があります。そのため、私には適切な方法ではないようです。
PS: シグナル ハンドラで cout を使用するのはよくない考えです。
PPS:std::cin.clear();
古い (非推奨) を使用すると、すべて正常に (なしで) 動作しsignal()
ます。
PPPS: 明確にするために、Ctrl+でプログラムを終了したくありませんC!
c - Linux の create_timer および sigaction API を使用するとセグメンテーション違反が発生する
次のコードを、ARM <-> DSP システムで実行されるより大きなプログラム (残念ながら共有できません) に統合しようとしています。
ご覧のとおり、これは非常に単純なコードであり、システム上で単独で実行すると問題なく動作します。ここでの while ループはデモンストレーション用であり、無視できます。ハンドラーと初期化の手順は同じです。
問題は、より大きなプログラムと統合しようとしたときに始まりました -タイマー間隔を 10ms より短く設定すると、突然、セグメンテーション違反が発生します。
ハンドラー内の演算を「curr_time = 0」という単純な行に削減しようとしましたが、ハンドラー内の浮動小数点演算と関係があるのではないかと考えましたが、役に立ちませんでした。
私は ARM<->DSP 共有メモリ バッファに連続メモリ割り当て API を使用していることに注意してください。ただし、ハンドラーに新しいメモリを割り当てていないため、それと関係があるとは思えません。
では、セグメンテーション違反の考えられる原因について何か考えがある人はいますか?
linux - Linux で SIGCHLD、EINT、および accept() を処理する適切な方法
TCP サーバーを作成するプログラムがあります。accept() がクライアントに接続すると、それを fork() して接続を処理します。そのクライアントが離れると、SIGCHLD のために waitpid() が呼び出されますが、accept() で EINTR が発生します。私の質問は、これをどのように処理する必要があるかです。私は非常に多くの異なる方法を読みました。
ほとんどの人は、EINT を無視して、accept() を再試行すると言います。ちょうどそれを行うマクロを見たことがあります: TEMP_FAILURE_RETRY()。sigaction フラグ SA_RESTART および SA_NOCLDSTOP を設定すると言う人もいます。私はそれを試しましたが、他のエラーが発生します (errno = ECHILD)。また、子供はどのように終了する必要がありますか?_exit(0) と exit(0) の両方を見てきました。
SIGCHLD の処理は次のとおりです。