0

代替シグナルスタック( )を試していますman sigaltstack

スタックを異なる方法で割り当てる 2 つのコード:

int method1(void)
{
    struct sigaction act, oldact;

    memset(&act, 0, sizeof(act));
    act.sa_sigaction = SignalHandler;
    act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
    sigemptyset(&act.sa_mask);
    if (sigaction(THREAD_SIGNAL, &act, &oldact) != 0) {
        ALOGW("sigaction failed %s\n", strerror(errno));
        return -errno;
    }

    return 0;
}

シグナルの登録中に SA_ONSTACK を使用しただけです。シグナル スレッドがスケジュールされている間、pthread_create で、このフラグが設定されている場合、8kb のスタックが次のように割り当てられます ( SIGSTKSZ = 0x2000(8kb) )。

  ss.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  if (ss.ss_sp != MAP_FAILED) {
    ss.ss_size = SIGSTKSZ;
    ss.ss_flags = 0;
    sigaltstack(&ss, NULL);
    thread->alternate_signal_stack = ss.ss_sp;
  }

シグナルハンドラを登録しながら、同じことを行う別の方法。

int method2(void)
{
    struct sigaction act, oldact;
    stack_t ss;

    ss.ss_sp = malloc(SIGSTKSZ);
    if (ss.ss_sp == NULL)
        return -ENOMEM;

    ss.ss_size = SIGSTKSZ;
    ss.ss_flags = 0;
    sigaltstack(&ss, NULL);

    memset(&act, 0, sizeof(act));
    act.sa_sigaction = SignalHandler;
    act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
    sigemptyset(&act.sa_mask);
    if (sigaction(THREAD_SIGNAL, &act, &oldact) != 0) {
        ALOGW("sigaction failed %s\n", strerror(errno));
        return -errno;
    }

    return 0;
}

この場合、デフォルトのスタックを割り当てるために bionic に依存していません。私は自分のスタックを割り当てて使用しています。

したがって、どちらの場合も、8kb のシグナル スタックを割り当てています。

while(1)内部シグナルハンドラを配置proc/pid/mapsし、プロセスにシグナルを送信した後に確認しました。

結果は次のとおりです。

方法 1 (pthread_create で bionic によって割り当てられたスタック):

7faa8d1000-7faa8d3000 rw-p 00000000 00:00 0        [stack:6633]

方法 2 (アプリケーションによって malloc を使用して割り当てられたスタック):

7fb7300000-7fb7500000 rw-p 00000000 00:00 0        [stack:6567]

奇妙なことに、method2 で malloc() を使用して 8kb のスタックしか割り当てなかったのに、スタックは約 2MB(0x200000) 割り当てられたようです。

何がうまくいかなかったのか、それとも予想される動作なのか、親切にアドバイスしてください。

4

1 に答える 1

0

スタックに関する procfs の情報が正しくない場合があります。シグナル ハンドラでローカル変数のアドレスを出力してみてください。私の賭けは、あなたが見ているスタックがメインスタックであることに気付くでしょう。

なぜこれが起こるのかわかりませんが、カーネルの問題のようです。Linuxでも見ました。

于 2015-08-05T22:51:00.883 に答える