ルギア君の戯言

雑多な記事。

7年1月6日 (金) - TeX Live 20100722 + e-pTeX 20110315 奮闘記 その8

みんな「みーっつ! みんな笑顔で明るいあるぱ城!」
ドンちゃん「よし、今日も仕事始め!」


……………


というわけで、まず、メモリの確保の問題を解明するために、ビルドついでに

$ ../tools/OmoiKondara -G -v texlive

している。
キリルン「ビルド時間だいぶ短くなったでゲソね〜。」
ルギア君「うむ。もう終わったか。まあ、完走しているわけじゃないけどね。」

--real:4570.52 utime:3496.18 stime:687.35

最後に RPM ファイルに固めるのを除いて 1 時間強というわけだ。Quad Core 以上のマシンならもっと速いだろう。ただし、その差はたかが知れている、らしい。
ルギア君「さて、お決まりの gdb の時間だ。」

$ export PATH=/var/tmp/texlive-.../usr/bin:$PATH
$ export LD_LIBRARY_PATH=/var/tmp/texlive-.../usr/lib64:$PATH
$ export TEXMFMAIN=/var/tmp/texlive-.../usr/share/texmf
$ export TEXMFDIST=/var/tmp/texlive-.../usr/share/texmf-dist
$ export TEXMFVAR=/var/tmp/texlive-.../usr/share/texmf-var
$ export TEXMFCONFIG=/var/tmp/texlive-.../usr/share/texmf-config
$ gdb tex

まずは、そのメモリ確保の問題を起こしている根源を見つけ出す作業だが、しかたがないので、

(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000401d20 in main at texextra.c:796
        breakpoint already hit 1 time
2       breakpoint     keep y   0x000000000040b660 in mainbody at texini.c:3770
        breakpoint already hit 1 time
5       breakpoint     keep y   0x000000000040c380 in mainbody at texini.c:4145
        stop only if first == 0
6       breakpoint     keep y   0x000000000040c3a0 in mainbody at texini.c:4148
        breakpoint already hit 1 time
7       breakpoint     keep y   0x0000000000407dbf in loadfmtfile
                                               at texini.c:2836
        breakpoint already hit 1 time
8       hw watchpoint  keep y                      extramembot
        breakpoint already hit 1 time

このようにまずは until コマンドを使えば関数丸ごと飛ばせるから、その中で問題があれば次その中に step すればいい。という風にまず main から調べていっていくと、texini.c の 2837 行目に存在することがわかった。その内容は、

(gdb) r
Starting program: /var/tmp/texlive-2010-0.6m.mo8-root-lugia/usr/bin/tex 

Breakpoint 1, main (ac=1, av=0x7fffffffd928) at texextra.c:796
796     {
(gdb) c
Continuing.

Breakpoint 2, mainbody () at texini.c:3770
3770    {
(gdb) c
Continuing.
Hardware watchpoint 8: extramembot

Old value = 0
New value = -268435455
0x0000000000402136 in initialize () at texini.c:119
119         mubytecswrite [i ]= -268435455L ;
(gdb) c
Continuing.
This is TeX, Version 3.1415926 (TeX Live 2010)

Breakpoint 6, mainbody () at texini.c:4148
4148          scannerstatus = 0 ;
(gdb) s
4149          warningindex = -268435455L ;
(gdb) 
4150          first = 1 ;
(gdb) 
4151          curinput .statefield = 33 ;
(gdb) 
4152          curinput .startfield = 1 ;
(gdb) 
4153          curinput .indexfield = 0 ;
(gdb) 
4154          line = 0 ;
(gdb) c
Continuing.
**a

Breakpoint 7, loadfmtfile () at texini.c:2836
2836      memmax = memtop + extramemtop ;
(gdb) s
2834      pagetail = memtop - 2 ;
(gdb) 
2835      memmin = membot - extramembot ;
(gdb) 
2836      memmax = memtop + extramemtop ;
(gdb) 
2837      yzmem = xmallocarray ( memoryword , memmax - memmin + 1 ) ;
(gdb) 
xmalloc (size=18446744071586067984)
    at /opt/Momonga/pkgs/texlive/BUILD/texlive-2010/texlive-20100722-source/texk/kpathsea/xmalloc.c:24
24      {
(gdb)

ここで、お馴染みの数値が出ていることに気がつくだろう。もう一度実行して、

(gdb) r
Starting program: /var/tmp/texlive-2010-0.6m.mo8-root-lugia/usr/bin/tex 

Breakpoint 1, main (ac=1, av=0x7fffffffd928) at texextra.c:796
796     {
(gdb) c
Continuing.

Breakpoint 2, mainbody () at texini.c:3770
3770    {
(gdb) c
Continuing.
Hardware watchpoint 8: extramembot

Old value = 0
New value = -268435455
0x0000000000402136 in initialize () at texini.c:119
119         mubytecswrite [i ]= -268435455L ;
(gdb) c
Continuing.
This is TeX, Version 3.1415926 (TeX Live 2010)
 
Breakpoint 6, mainbody () at texini.c:4148
4148          scannerstatus = 0 ;
(gdb) c
Continuing.
**aa

Breakpoint 7, loadfmtfile () at texini.c:2836
2836      memmax = memtop + extramemtop ;
(gdb) s
2834      pagetail = memtop - 2 ;
(gdb) 
2835      memmin = membot - extramembot ;
(gdb) 
2836      memmax = memtop + extramemtop ;
(gdb) 
2837      yzmem = xmallocarray ( memoryword , memmax - memmin + 1 ) ;
(gdb) p sizeof(memoryword)
$26 = 8
(gdb) p memmax
$27 = 2999999
(gdb) p memmin
$28 = 268435455
(gdb) p memmax - memmin + 1
$29 = -265435455
(gdb) p membot
$30 = 0
(gdb) p memtop
$31 = 2999999
(gdb)

というわけで完全にアンダーフローしているというわけだ。membot は 0 だから良いとして、問題は extramembot である。すでに watch が設定してあるので気がついただろうが、同じソースの 119 行目で、マジックナンバーとして -268435455L が代入されている。grep で探して気がついたのだが、ctangle で処理されたソースの中にはこのマジックナンバーが大量に存在している。なので、このプログラムが悪の根源となっている可能性は高い。このマジックナンバーは C 言語の中だけでなく、tangle (ctangle ではなく) で処理した Pascal プログラムの中にも登場する。

キリルン「なるほどでゲソー。」

ちなみにこのマジックナンバーはソースの中には全くない。

ルギア君「まあ、可能性があることとしては gcc-3.4 でビルドするとか、それプラス Pascal コンパイラである GNU Pascal をインストールしてみるとかすればいいんじゃないかな。」
キリルン「なるほどでげそー。」
ルギア君「あとどうやら、TeX Live には」

$ make check

ルギア君「あったらしい。」
キリルン「チェックしてあげなければダメじゃなイカ。」

根源から直そうとすると、この件は面倒なので、一度、gcc-3.2 でビルドしてそれでもダメだったら、諦めます。auctex は、うーん、どうしようか。YaTeX で十分だから auctex は使ってないんだよなー。というか、auctex の方もドキュメントの作成でつまっているだけだから、それをカットすれば問題ないはず。pdf ファイルも dvi ファイルも付いてきているし。え? それじゃ意味がない?