[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:00102] Re: AIX でのコンパイルエラーについて



 しらいです。

In Message-Id <03Feb12.152817jst.119047@inetgw.lightwell.co.jp>
        SHIOTA Shoichi <Shoichi.Shiota@lightwell.co.jp>さんwrites:
> 潮田です。

> >  gdb 使えるんなら printf debug や表層的な調査でなく、落ちて
> > いる箇所のコードを特定出来ると思うんですが...。
> すいません、その通りです。
> 私の腕がもっとあれば、ですが。

 gdb の最低限の使い方くらいは判っているけれども、trace で追
い切れる程には熟達していないというところでしょうか?ならもう
暫く printf debug を続けてみましょうか。
 ところで AIX には標準 debugger が無いんでしょうか?gdb っ
て GNU debugger ですよね?標準 cc ではなく gcc を使っていま
す?


> >  でも SIGILL ですか?SIGSEGV で落ちるという話だったかと思う
> > んですが。SIGILL は一体どういうケースで発生しているんでしょ
> > う?
> 単純に、 shell から FDclone を実行するか、 gdb 上で実行するか
> にかかっているように見えます。

 同じ operation をした場合、落ちる場所は同じだけれども gdb
か否かで SIGILL か SIGSEGV かが異なってくるということですか?
SIGSEGV は catch 出来ないので SIGILL になるということですか
ね。


> また、上記の bt の結果ですが、下の様になります。
> (gdb) bt
> #0  0x00000000 in ?? ()
> #1  0x1004795c in trap_common (sig=0) at system.c:1994
> #2  0x1004730c in trap_chld () at system.c:2163

 なんか妙なところで止まってますね。それは signal handler で
すよ。しかも sig=0 ということは、kill -0 されたということに
なりますね。本当?
 やはりどこかで stack overflow が起きているのでしょうか。


> >  該当行には waitpid() がいますね。AIX は wait4() は持ってな
> > いんでしたっけ。どうも pid の値が妙な値になっていそうです。
> wait4() も持っています。

 wait4() はあっても union wait が無いんですよね。ならどの道
waitpid() しか使えませんね。多分 waitpid() の bug ではないで
しょうから、wait4() に置き換えたところで症状は変わらないでし
ょうし。


> >  こっちの pid はそのまま waitjob に渡される筈なのですが、上
> > の値とはまるで関係ありませんね。んー、signed と unsigned の
> > 違いでもなさそうですし、何かの pointer 値でも渡っているんで
> > しょうか。元々は fork() の返り値なんですが。
> そうですよ。
> たとえこの値がプラス側だったとしても、こんな大きな pid は
> みたことないです。

 ええ、ですから多分どこかで memory leak が起こっていて、本
来変わることのない変数値をいじってしまっているんだと思います。
 こういうのは追うのが難しいんですよ。落ちるずっと前に書き換
えられているでしょうから、debugger で追っても追い切れないか
も知れません。

 こうなると printf debug しかない訳ですが、fork() の前後で
端末が移動しますので普通に端末に printf() する訳にもいきませ
ん。
 ということでこんな感じの printf debug になると思います。
	{
		FILE *debugfp;
		char debugpath[MAXPATHLEN];
		int debugfd;

		if ((debugfd = newdup(mktmpfile(debugpath))) >= 0) {
			if (!(debugfp = fdopen(debugfd, "w"))) close(debugfd);
			else {
				fprintf(debugfp, "%d) %d: %d\n",
					getpid(), __LINE__, pid);
				fclose(debugfp);
			}
		}
	}

 これは変数 pid をチェックするためのコードですので「pid」の
部分は適宜読み替えて下さい。
 端末が使えないので log file に吐かせる訳ですが、fork() し
た後は順序が保証されないので、同じ log file に吐いてしまうと
semaphore が面倒です。
 make sh の fdsh なら /tmp に、fd なら $TMPDIR に log が吐
かれますので、getpid() と __LINE__ を頼りに、どの log がどの
printf() に対応しているのかを確認しながら追って下さい。

 こんな感じのコードを、makechild() の途中幾つかと、waitjob()
及び waitchild() の頭に追いておくことで、pid の値がいつどこ
ですげ変わってしまったのかを追えると思います。
 落ちるまでの順序を辿ると、
	exec_simplecom -> makechild -> execve (子)
	                       +-> waitchild -> waitjob (親)
となっており、この過程のどこかで pid の値が狂ったことによっ
て waitpid() が落ちているようです。
 勿論、memory leak 自体は、変数値が変わってしまうよりもまた
ずっと前の箇所で生じているので、この結果から即原因が判明する
訳ではないのですが、解決の糸口にはなると思います。


 で、今後の方針ですが、他にも幾つか bug を直していますので、
このまま AIX & spark64 の支障に関する進展が見られないような
ら、来週頭まで待って 2.02b を release してしまおうと思います。
 それまでに目処がつくようでしたら、この bug も修正してから
2.02b を出します。そうでなければ、2.02b の release 後、舞台
を 2.02b に移してから改めて bug 追跡してみましょう。
 そんな roadmap で如何でしょうか?

                                               しらい たかし