![]() |
|
|
In January 2001, I ported O'Reilly's gmat text formatting package to FreeBSD. There was a problem: it produced ridiculous numbers of error messages, the first two pages contained junk which appeared to be the contents of a directory, and the footnotes came one word per line.
Lenny Muellner of O'Reilly tried to work out what was going wrong, but beyond suspecting that the macro files had been corrupted, he couldn't think of anything:
Greg, I'm trying to figure out what the junk is in the beginning of the PostScript file you sent me, and I haven't been able to reproduce the problem when I do a fresh install of the gmat distro on a linux machine here. But when I look at the actual PostScript, there's stuff like this: (ch01-errmq\321\315f ch01-err~$\300\316f)-5 F(#ch01-err#\321)0 132 Q(-) -1 I(Df\()-3.33 1 M(\214xing-communicator)-2.5 E 16.277 (.html1-\300\341f muttu48589\321\352f mytv\243)-.55 F F4(2)-2 I F0 18.776(\317\343f .#mytv\321\344f)2 J(mytv~$\300d)-2.5 E 6.626(muttA4858\ 9\321\343f muttc48589\321\345f muttM48589\321\346f muttW48589\321\347f \ muttj48589\321\264f mutto97330\321\350f)0 144 R(muttx97330\321\342f)0 156 Q(muttk97330\321\351f)0 168 Q(gmat.sgm\315l\321\353f\270)-5 E (gmat.errMW\321)-5 E(blacklist.5122\354f)-2.5 E(blacklist.534g)-2.5 E I may be wrong, but this looks to me like it has the names of the files that you emailed me==ch01-err, gmat.sgm, gmat.err, etc. in other words, it looks like some binary representation of the contents of a directory. Is there any chance that one of the files in the macros directories got somehow corrupted with this stuff?
On 25 January, I went through the output of a ktrace session and looked for the stuff again. Based on Lenny's input, I went and compared the original with the installed macros. Here's what I saw:
$ (for i in *; do diff -wu $i /usr/local/share/gmat/macros/$i; done)|less === tmac.G Fri Mar 24 03:42:38 2000 +++ /usr/local/share/gmat/macros/tmac.G Thu Jan 11 12:21:42 2001 @@ -20,12 +20,12 @@ .\" .\" ############ DEFAULTS AND MISC VARIABLES .\" The following strings are set in accord with the Makefile -.ds TMPDIR %%TMPDIR%% -.ds BINDIR %%BINDIR%% -.ds gmat_gmacroff %%BINDIR%%/gmacroff +.ds TMPDIR /var/tmp +.ds BINDIR /usr/local/bin +.ds gmat_gmacroff /usr/local/bin/gmacroff .\" DEFINE THE FOLLOWING paths for your local environment! .ds gmat_echo /bin/echo -.ds gmat_sed /bin/sed +.ds gmat_sed /usr/bin/sed .ds gmat_rm /bin/rm .ds gmat_mv /bin/mv .\" The following strings set variables to subdirectories of the book
That looked fine. The only things that are changed are the names of the files and directories, and they were all what I want. So I went through the ktrace.out I mentioned before. What I found was:
57346 troff RET fork 57347/0xe003 57346 troff CALL wait4(0xe003,0xbfbfebe0,0,0) 57347 sh RET getdirentries 1024/0x400 57347 sh CALL getdirentries(0x9,0x80d8000,0x1000,0x80d40b4) 57347 sh RET getdirentries 0 57347 sh CALL lseek(0x9,0,0,0,0) 57347 sh RET lseek 0 57347 sh CALL close(0x9) 57347 sh RET close 0 57347 sh CALL fork 57347 sh RET fork 57348/0xe004 57347 sh CALL getpgrp 57347 sh RET getpgrp 57264/0xdfb0 57347 sh CALL wait4(0xffffffff,0xbfbfec90,0x2,0) 57348 sh RET fork 0 57348 sh CALL execve(0x80d16b4,0x80d16f4,0x80d1708) 57348 sh NAMI "/bin/rm" 57348 rm RET execve 0 57348 rm CALL geteuid 57348 rm RET geteuid 0 57348 rm CALL ioctl(0,TIOCGETA,0xbfbfee1c) 57348 rm RET ioctl 0 57348 rm CALL lstat(0xbfbff087,0xbfbfede8) 57348 rm NAMI "/var/tmp" 57348 rm RET lstat 0 57348 rm CALL write(0x2,0xbfbfe680,0x4) 57348 rm GIO fd 2 wrote 4 bytes "rm: " 57348 rm RET write 4 57348 rm CALL write(0x2,0xbfbfe6a0,0x18) 57348 rm GIO fd 2 wrote 24 bytes "/var/tmp: is a directory" 57348 rm RET write 24/0x18 57348 rm CALL write(0x2,0xbfbfe680,0x1) 57348 rm GIO fd 2 wrote 1 byte " " 57348 rm RET write 1 57348 rm CALL lstat(0xbfbff090,0xbfbfede8) 57348 rm NAMI "/date.*" 57348 rm RET lstat -1 errno 2 No such file or directory 57348 rm CALL exit(0x1) 57347 sh RET wait4 57348/0xe004 57347 sh CALL exit(0x1)
This is a bit hard to interpret, but basically troff is spawning a shell, which executes rm to remove two files, /var/tmp and /date.*. That looked suspicious. So I went back and checked:
$ find macros/|xargs grep date macros/tmac.G:.sy \\*[gmat_rm] -f \\*[TMPDIR]/date.* macros/tmac.G:.sy \\*[gmat_echo] ".ds tD `date +%H:%M`" > \\*[TMPDIR]/date.\n# macros/tmac.G:.so \\*[TMPDIR]/date.\n# macros/tmac.G:.\".sy \\*[gmat_rm] -f /tmp/date.\n# macros/tmac.sgmlmacs:.tm You may need to change your text to accommodate the change macros/tmac.sgmlmacs:.ds pubdate \\$* macros/tmac.sgmlmacs:.if !"\\*[pubdate]"" \\*[pubdate]. macros/tmac.sgmlmacs:.ds pubdate macros/sgmlmacs:.tm You may need to change your text to accommodate the change macros/sgmlmacs:.ds pubdate \\$* macros/sgmlmacs:.if !"\\*[pubdate]"" \\*[pubdate]. macros/sgmlmacs:.ds pubdate
Based on the substitutions, that very first line would translate to rm -f /var/tmp/date.*. But what we got was rm -f /var/tmp/ date.*. So I checked my macro files once more, and sure enough, there was a space after the changed pathnames. I removed that, and now everything works fine. I wish I were still doing the debug book, that would be a beauty.
The next day I committed a patch file to the Ports Collection. It seems the ultimate in understatement:
=== macros/tmac.G~ Fri Mar 24 03:42:38 2000 +++ macros/tmac.G Fri Jan 26 13:46:44 2001 @@ -20,8 +20,8 @@ .\" .\" ############ DEFAULTS AND MISC VARIABLES .\" The following strings are set in accord with the Makefile -.ds TMPDIR %%TMPDIR%% -.ds BINDIR %%BINDIR%% +.ds TMPDIR %%TMPDIR%% +.ds BINDIR %%BINDIR%% .ds gmat_gmacroff %%BINDIR%%/gmacroff .\" DEFINE THE FOLLOWING paths for your local environment! .ds gmat_echo /bin/echo
Greg's home page | Greg's diary | Greg's photos | Copyright |