Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all bug

名前

       sigaltstack - シグナルスタックのコンテキストを設定・取得する

書式

       #include <signal.h>

       int sigaltstack(const stack_t *ss, stack_t *oss);

   glibc 向けの機能検査マクロの要件 (feature_test_macros(7)  参照):

       sigaltstack():
           _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
           || /* glibc 2.12 以降: */ _POSIX_C_SOURCE >= 200809L

説明

       sigaltstack()   を使うと、 プロセスは新しい代替シグナルスタックを定義したり、 既存の代替シ
       グナルスタックの状態を取得できる。  シグナルハンドラーが代替シグナルスタックを要求するよう
       に設定されていると  (sigaction(2)  参照)、ハンドラーの実行中はそのシグナルスタックが使われ
       る。

       代替シグナルスタックを使う際の一般的な手順は、以下の通りである:

       1. 代替シグナルスタックで使うメモリー領域を確保する。

       2. sigaltstack()  を使って、 代替シグナルスタックの存在と場所をシステムに知らせる。

       3. sigaction(2)  を使ってシグナルハンドラーを確立する際、 SA_ONSTACK  フラグを指定すること
          により、  そのシグナルハンドラーを代替シグナルスタック上で実行することを システムに知ら
          せる。

       ss 引き数は、新しいシグナルスタックを指定するために使う。 また oss  引き数は、現在確立され
       ている  シグナルスタックの情報を取得するために使う。 この操作のうち 1 つだけを実行させるに
       は、 使用しない引き数を NULL  に指定すればよい。  引き数となる構造体は、以下のような型であ
       る:

           typedef struct {
               void  *ss_sp;     /* スタックのベースアドレス */
               int    ss_flags;  /* フラグ */
               size_t ss_size;   /* スタックのバイト数 */
           } stack_t;

       新規の代替シグナルスタックを確立するには、   ss.ss_flags   を  0  に設定し、  ss.ss_spss.ss_size に スタックの開始アドレスとスタックサイズを指定する。 定数 SIGSTKSZ  は、代替シ
       グナルスタックが通常必要する  サイズよりも充分大きく定義されている。  また定数 MINSIGSTKSZ
       は、 シグナルハンドラーの実行に必要な最小サイズに定義されている。

       代替スタックでシグナルハンドラーが起動された場合には、 カーネルにより自動的に、ss.ss_sp で
       指定されたアドレスは 動作しているハードウェアアーキテクチャーに適したアドレス境界に 調整さ
       れる。

       既存のスタックを無効にするには、 ss.ss_flagsSS_DISABLE に指定する。 この場合、ss  の他
       のフィールドは無視される。

       oss  が  NULL  以外の場合、 oss に代替シグナルスタックの情報が返される。 これは (実質的に)
       sigaltstack()  の呼び出しより先に行われる。 oss.ss_sposs.ss_size フィールドに スタック
       の開始アドレスとスタックサイズが返される。 oss.ss_flags には以下のどちらかの値が返される:

       SS_ONSTACK
              プロセスが代替シグナルスタック上で実行されている  (プロセスが既にそのシグナルスタッ
              ク上で実行されている場合は、 それと同じシグナルスタックには変更できない点に注意する
              こと)。

       SS_DISABLE
              代替シグナルスタックが現在無効になっている。

返り値

       sigaltstack()   は成功した場合  0  を返す。  失敗した場合は -1 を返して、 エラーを示す値に
       errno を設定する。

エラー

       EFAULT ss または oss  のどちらが、NULL  以外で、  かつプロセスのアドレス空間の外を指してい
              る。

       EINVAL ss が NULL 以外で、ss_flags フィールドが SS_DISABLE 以外の 0 でない値になっている。

       ENOMEM 新しい代替シグナルスタック  (ss.ss_size)  に指定したサイズが  MINSTKSZ より小さかっ
              た。

       EPERM  代替シグナルスタックが有効であるときに変更を行おうとした  (つまり、プロセスが既に現
              在の代替シグナルスタック上で実行されていた)。

準拠

       SUSv2, SVr4, POSIX.1-2001.

注意

       代替シグナルスタックを使用する最もよくある場面は、    SIGSEGV   シグナルを扱うときである。
       SIGSEGV はプロセスの通常のスタックが利用できる空間が使い果たされた際に  生成されるシグナル
       である。この場合には、  SIGSEGV 用のシグナルハンドラーをプロセスのスタック上では起動するこ
       とができない。 そのため、このシグナルを扱おうとする場合には、 代替シグナルスタックを使用し
       なければならない。

       プロセスが標準のシグナルスタックを使い果たすことが予想される場合は、  代替シグナルスタック
       を確立すると便利である。 例えば、スタックが最上位アドレスから 下位アドレス方向に非常にたく
       さん積まれてしまうことで、  最下位アドレスから上位アドレス方向に積まれるヒープとぶつかって
       しまう場合や、 setrlimit(RLIMIT_STACK, &rlim) の呼び出しで確立された  制限に達してしまった
       場合に、この様な事が起こる。  標準のスタックを使い果たしてしまうと、  カーネルはプロセスに
       SIGSEGV シグナルを送る。  このような状況では、代替シグナルスタック上でしかシグナルをキャッ
       チできない。

       Linux  がサポートする多くのハードウェアアーキテクチャーでは、 スタックは下位アドレス方向に
       積まれる。 sigaltstack() はスタックが積まれる方向を自動的に決定する。

       代替シグナルスタック上で実行されている  シグナルハンドラーから呼ばれる関数も、代替シグナル
       ハンドラーを使う  (プロセスが代替シグナルスタック上で実行されている場合、 他のシグナルで呼
       び出されるハンドラーもこの代替シグナルハンドラーを使う)。 標準のスタックとは異なり、  シス
       テムは代替シグナルスタックを自動的に拡張しない。  代替シグナルスタック用に確保したサイズを
       越えた場合、 結果は予想できない。

       execve(2)  の呼び出しが成功すると、 既存の全ての代替シグナルスタックが削除される。 fork(2)
       経由で作成された子プロセスは、親プロセスの代替シグナルスタックの 設定のコピーを継承する。

       sigaltstack()   は以前の sigstack()  を置き換えるものである。 過去プログラムとの互換性のた
       め、glibc では sigstack()  も提供している。  新しいのアプリケーションは全て  sigaltstack()
       を使って書くべきである。

   歴史
       4.2BSD  には  sigstack()   システムコールがあった。 この関数は少し異なった構造体を使ってお
       り、 呼び出した側がスタックの積まれる方向を知っていなければならないという 大きな欠点があっ
       た。

       以下のコードで sigaltstack()  の使用法の一部を示す:

           stack_t ss;

           ss.ss_sp = malloc(SIGSTKSZ);
           if (ss.ss_sp == NULL)
               /* ハンドルエラー */;
           ss.ss_size = SIGSTKSZ;
           ss.ss_flags = 0;
           if (sigaltstack(&ss, NULL) == -1)
               /* ハンドルエラー */;

関連項目

       execve(2), setrlimit(2), sigaction(2), siglongjmp(3), sigsetjmp(3), signal(7)

この文書について

       この  man ページは Linux man-pages プロジェクトのリリース 3.79 の一部である。 プロジェクト
       の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。