[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[FDclone-users:00150] Re: {FreeBSD,OpenBSD}/sparc64, IA64(AIX 対応その後)
- Subject: [FDclone-users:00150] Re: {FreeBSD,OpenBSD}/sparc64, IA64(AIX 対応その後)
- From: SHIOTA Shoichi <Shoichi.Shiota@lightwell.co.jp>
- Date: Wed, 30 Apr 2003 14:57:21 +0900
潮田@今日もお遊びで出社中です。
ちょっと長いです。
Takashi SHIRAI <shirai@unixusers.net> wrote:
> trap_common() は shell の基本機能として重要な部分ではない
> ので、中身をそっくり削除してしまっても大勢に影響はありません。
> なので、system() 以外の行を削除してみて症状が再現するかどう
> か試してみて下さい。
この流れでいくと system() は signal() の typo ですよね。
trap_common() の
flags = signallist[i].flags;
から
if (trapped < 0) Xexit2(sig + 128);
までを削除して試しました。
削除前同様の暴走でした。
> portability を考えるとこの signal() は外せないのですが、も
> し本当に signal() が SIGCHLD を発生させているのだとしたら、
> sigaction() に置換えてみましょうか。
> それで直るとしたら、OS 側で用意されている library 実装が原
> 因ということになるでしょうか。
>
> if (signallist[i].func) {
> struct sigaction act;
>
> act.sa_handler = (sigcst_t)(signallist[i].func);
> act.sa_flags = 0;
> sigemptyset(&act.sa_mask);
> sigaction(sig, &act, NULL);
> }
これは、暴走しませんでした。
今日たまたまきている者に AIX 4.3.3 をかりて試しましたが、
そちらでも暴走することなく終了しました。
ただ、このためしたマシンが
oslevel -r
になにも答えないおかしな環境だったので、休み明けにもう少し
素性の知れた WS でも試します。
> FDclone の中で SIGCHLD を特別扱いしている箇所は 3 箇所だけ
> だと思います。
> 1. trap_chld() の中で checkjob() を呼んでいる。
> 2. makechild() の中で SIGCHLD の mask を外している。
> 3. posixsh.c/gettermio() の中で SIGCHLD の block 対
> 象に追加している。
> それぞれ該当箇所は 1 行のみですので、その 1 行を削除してみ
> ることで、元のままの trap_common() でも支障なく動作したりす
> るようであれば、別のところに原因があるということになりますね。
> 一度試してみて下さい。
3通りすべて試しましたが、同様に暴走しました。
以下は余談気味。
で、そういえばと思い出したものがあります。
去年入社の新人が秋頃に AIX でだけ暴走しますと言ってきた
プログラムがありました。
そんなに長くないのでそのまま貼り付けますと、
--- ここから ---
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
static void CatchSIGCHLD(int iSignal);
static void SetSignal(void);
static int iCount = 0;
int main(int argc, char *argv[])
{
int i = 0;
int j = 0;
pid_t iPid = 0;
do {
SetSignal();
for (i = 0; i < 10; i++) {
iPid = fork();
if (iPid == 0) {
_exit(0);
}
else {
wait(&j);
}
}
} while (0);
return 0;
}
/* SIGCHLDを受けたらプリント */
static void CatchSIGCHLD(int iSignal)
{
iCount++;
printf("Hello[%d]!! pid(pid=%d)\n", iCount, getpid()); fflush(stdout);
SetSignal();
return;
}
/* ハンドラーのセット */
static void SetSignal(void)
{
signal(SIGCHLD, CatchSIGCHLD);
return;
}
--- ここまで ---
これは、
shiota@alpha <~> $ ./a.out
Hello[1]!! pid(pid=58052)
Hello[2]!! pid(pid=58052)
Hello[3]!! pid(pid=58052)
Hello[4]!! pid(pid=58052)
Hello[5]!! pid(pid=58052)
Hello[6]!! pid(pid=58052)
Hello[7]!! pid(pid=58052)
Hello[8]!! pid(pid=58052)
Hello[9]!! pid(pid=58052)
Hello[10]!! pid(pid=58052)
shiota@alpha <~> $
こんな風な結果を期待しており、実際 FreeBSD(x86) や Linux(alpha)
ではそうなりました。
が、 Tru64 上では、
-bash-2.05b$ ./a.out
Hello[1]!! pid(pid=234322)
Hello[2]!! pid(pid=234322)
Hello[3]!! pid(pid=234322)
Hello[4]!! pid(pid=234322)
Hello[5]!! pid(pid=234322)
Hello[6]!! pid(pid=234322)
Hello[7]!! pid(pid=234322)
Hello[8]!! pid(pid=234322)
Hello[9]!! pid(pid=234322)
-bash-2.05b$
と 10 番目が出力されません。
そして本命の AIX ですが
shiota@delta <~/ss> $ ./a.out
(すごく省略)
Hello[206416]!! pid(pid=33884)
Hello[206417]!! pid(pid=33884)
Hello[206418]!! pid(pid=33884)
Hello[206419]!! pid(pid=33884)
Hello[206420]!! pid(pid=33884)
Hello[206421]!! pid(pid=33884)
Hello[206422]!! pid(pid=33884)
Hello[206423]!! pid(pid=33884)
Illegal instruction
shiota@delta <~/ss> $
(Illegal の前に化け文字が出てましたが消しています)
と暴走・リソースを食いつぶし、その内おちるしまつ。
結局この解決方法は見つからず、この新人が退社(はやっ)したため
問題ごと頭から消していました。
前回述べました某所のソースには、
--- ここから ---
/********************************/
/*** シグナルをセットする関数 ***/
/********************************/
void SetSignalFunc(void)
{
signal(SIGTERM, KillChild);
signal(SIGCHLD, ExitChild);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
return;
}
/**************************************/
/*** 子プロセスの終了処理をする関数 ***/
/**************************************/
void ExitChild(int iSignal)
{
pid_t iPid = 0;
(省略)
/* シグナルの再セット */
SetSignalFunc();
return;
}
--- ここまで ---
と書いた部分があるだけに、この動作は理解できないのですが、
力不足で見ないふりです。
(この ExitChild() は、日中に毎日一万回以上よばれているんですけれ
ど、なぜ動いているのだろう)