Image of grog
Greg's problems with gmat
Greg's diary
Photo index
Greg's home page
Network link stats
Greg's other links
Copyright information
Groogle

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

Valid XHTML 1.0!

$Id: gmat.php,v 1.2 2008/09/21 00:16:06 grog Exp $