5

私はwaitpid()とsignal()で遊んでいて、WIFSIGNALED(status) = WIFSTOPPED(status) = WIFCONTINUED (status) = trueを返すための信頼できるテストケースを探していますが、何も見つかりません...

コードをデバッグできるように、それらが true を返すようにする方法を教えてください。

また、これらのマクロをテストするために signal() でどのシグナルをキャッチする必要があるかについてのいくつかのヒントが役立ちます...

4

4 に答える 4

6
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

#define NELEMS(x) (sizeof (x) / sizeof (x)[0])

static void testsignaled(void) {
   kill(getpid(), SIGINT);
}

static void teststopped(void) {
   kill(getpid(), SIGSTOP);
}

static void testcontinued(void) {
   kill(getpid(), SIGSTOP);
   /* Busy-work to keep us from exiting before the parent waits.
    * This is a race.
    */
   alarm(1);
   while(1) {}
}

int main(void) {
   void (*test[])(void) = {testsignaled, teststopped, testcontinued};
   pid_t pid[NELEMS(test)];
   int i, status;
   for(i = 0; i < sizeof test / sizeof test[0]; ++i) {
      pid[i] = fork();
      if(0 == pid[i]) {
         test[i]();
         return 0;
      }
   }
   /* Pause to let the child processes to do their thing.
    * This is a race.
    */
   sleep(1);
   /* Observe the stoppage of the third process and continue it. */
   wait4(pid[2], &status, WUNTRACED, 0);
   kill(pid[2], SIGCONT);
   /* Wait for the child processes. */
   for(i = 0; i < NELEMS(test); ++i) {
      wait4(pid[i], &status, WCONTINUED | WUNTRACED, 0);
      printf("%d%s%s%s\n", i, WIFCONTINUED(status) ? " CONTINUED" : "", WIFSIGNALED(status) ? " SIGNALED" : "", WIFSTOPPED(status) ? " STOPPED" : "");
   }
   return 0;
}
于 2009-05-26T00:26:14.540 に答える
3

WIFSIGNALED の取り扱いは簡単です。kill()子プロセスは、システム コールで自殺できます。コア ダンプを確認することもできます。一部のシグナルによってコア ダンプが作成されます (SIGQUIT、IIRC)。一部のシグナルは (SIGINT) をサポートしません。

WIFSTOPPED の処理は難しい場合があります。kill()試してみる簡単な手順は、子プロセスがシステム コールで SIGSTOP を再度送信することです。実際、それはうまくいくはずだと思います。SIGTTIN と SIGTTOU と SIGTSTOP をチェックしたいかもしれないことに注意してください - 私はそれらが WIFSTOPPED にカウントされると信じています。(SIGSTOP は、非 POSIX システム コールを介して実行中のプロセスにデバッガーによって送信された場合にのみ正常に機能する可能性もありますptrace()。)

WIFCONTINUED の処理は、親がしなければならないことだと思います。プロセスが停止したことを検出した後、呼び出しコードは SIGCONT シグナルを送信してプロセスを続行する必要があります (kill()再度)。子供はこれ自体を伝えることができません。停止されました。繰り返しますが、心配する余分なしわがあるかどうかはわかりません-おそらく.

于 2009-05-25T23:57:40.463 に答える
1

以下のようなフレームワークを使用すると、wait()との結果を確認できますwaitpid()

pid_t pid = fork();

if (pid == 0) {
    /* child */
    sleep(200);
}
else {
    /* parent */
    kill(pid, SIGSTOP);

    /* do wait(), waitpid() stuff */
}

signal()送信された信号(または関連する機能を使用)を実際にキャッチする必要はありません。signal()特定のシグナルのデフォルトの動作をオーバーライドするハンドラーをインストールします-したがって、プロセスを終了するシグナルをチェックする場合は、そのデフォルトの動作を持つハンドラーを選択します-" man -s7 signal"は、シグナルのデフォルトの動作の詳細を提供します。

あなたが言及したマクロの場合、、SIGSTOPWIFSTOPPED(status)、およびSIGCONTの使用WIFCONTINUED (status)SIGINTWIFSIGNALED(status)

テストの柔軟性を高めたい場合は、kill( " man kill"を参照)を使用してプロセスにシグナルを送信できます。kill -l送信できるすべての信号が一覧表示されます。

于 2009-05-25T21:31:16.843 に答える
-1

テストでは、fork() して子プロセスに特定のシグナルを送信できますか? このシナリオでは、子プロセスはテスト ケースですか?

編集

私の答えは、C テストのコーディングについてです。fork し、子プロセス (シグナル ハンドラがインストールされているプロセス) の pid を取得すると、kill(2). このようにして、終了ステータスをテストできます

于 2009-05-25T20:30:06.640 に答える