Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[9fans] plan9port build failure on Linux (debian)

43 views
Skip to first unread message

David Morris

unread,
Mar 2, 2008, 11:24:52 PM3/2/08
to
I am trying to install plan9port on a Linux system (Debian),
and am getting the following error:

9 yacc -d -s bc bc.y

fatal error:can't create , <nil>:1
mk: 9 yacc -d ... : exit status=exit(1)
mk: for i in ... : exit status=exit(1)

Everything compiles just fine up to this point with no
errors. This looks to be the first step of building the
lexx application. Because there is no filename listed in
the error message, I am guessing this is the result of a bug
in the code or the makefile (err, mkfile, I suppose).

Any idea of what the problem is? Or if its a bug in the
code, where I can get a stable version?

Details of my build environment and my install process
follow....

OS : Debian lenny (with a few packages from sid (unstable))
Arch: i386

plan9port version:
downloaded Saturday from http://swtch.com/plan9port/
After bug, updated from CVS

Install location: /usr/local

Install process:
# cd /usr/local
# sudo tar xvzf plan9port.tgz
# cd plan9
# sudo ./INSTALL
(failed with noted error)
# sudo cvs update -dP
# sudo ./INSTALL
(failed with noted error)

Thanks,

--David

Hongzheng Wang

unread,
Mar 3, 2008, 12:24:34 AM3/3/08
to
Hi,

I have just cvsed and rebuilt the whole system. No error occurs. And
my system is Debian sid. So, I think the problem you encountered
might due to some missing or mismatched packages on your debian box.
Perhaps, the install.log in /usr/local/plan9/ would be helpful to
discover what's wrong during installation.

--
HZ

David Morris

unread,
Mar 3, 2008, 3:46:47 AM3/3/08
to
On Mon, Mar 03, 2008 at 01:23:06PM +0800, Hongzheng Wang wrote:
> Hi,
>
> I have just cvsed and rebuilt the whole system. No error
> occurs. And my system is Debian sid. So, I think the
> problem you encountered might due to some missing or
> mismatched packages on your debian box. Perhaps, the
> install.log in /usr/local/plan9/ would be helpful to
> discover what's wrong during installation.

Well, one step forward, one step back....

install.log was no help, the message I quoted was everything
relevant.

I took a stab at running gdb through yacc, but the compiler
optimized the code to the point finding the problem was
nearly impossible.....best I can say is its somewhere in the
dofmt() function (lib9/fmt/dofmt.c) or something it calls.

So I pulled out my VERY slow laptop and spent a few hours
letting it compile plan9port.

This time the build worked, so looks like some lenny/sid
packages don't work well together. Hmm, or another
possibility occurs to me. I use the AMD64 kernel
(2.6.22-3-amd64) on my desktop, but i686 on the laptop
(2.6.22-3-i686). Any chance that could cause a problem?

I tried copying the "pure lenny" install to the main system
file structure, but that clearly does not work because wmii
(the application I need plan9port for) does not run.

So, any ideas on how to fix the build process? The problem
stems from yacc.c at line #2173 in the sprint() function.
Could I replace that with the standard library sprintf()
function as a stop-gap measure?

--David

erik quanstrom

unread,
Mar 3, 2008, 9:11:49 AM3/3/08
to
> install.log was no help, the message I quoted was everything
> relevant.
>
> I took a stab at running gdb through yacc, but the compiler
> optimized the code to the point finding the problem was
> nearly impossible.....best I can say is its somewhere in the
> dofmt() function (lib9/fmt/dofmt.c) or something it calls.

i trust you ran yacc under gdb not gdb through yacc. :-)
the problem is unlikely to be with the print. it likely
occurred in argument parsing.

one thing that should be fixed in p9p is the ARGF() calls
should be replaced with EARGF(usage()) in setup(). the
definition of usage should be

void
usage(void)
{
fprint(2, "usage: yacc [-Dn] [-vdS] [-o outputfile] [-s stem] grammar\n");
exits("usage");
}

once that is fixed, it would be interesting to see if yacc
prints a usage statement instead of printing the garbage.

assuming that things are still broken, i would suggest
adding fprint(2, "...") statements in setup to understand
where things are going wrong.

- erik

sqweek

unread,
Mar 3, 2008, 10:10:35 AM3/3/08
to
On Mon, Mar 3, 2008 at 5:46 PM, David Morris <li...@morris-clan.net> wrote:
> This time the build worked, so looks like some lenny/sid
> packages don't work well together. Hmm, or another
> possibility occurs to me. I use the AMD64 kernel
> (2.6.22-3-amd64) on my desktop, but i686 on the laptop
> (2.6.22-3-i686). Any chance that could cause a problem?

I run p9p on x86_64 at work (CentOS), so no. There are some problems
with 9pfuse under x86_64 (which look like fuse's fault to me), but the
only problem I had at build was missing dependencies (some X11
development packages).
I'll try and remember to cvs update and see if it still builds.
-sqweek

Russ Cox

unread,
Mar 3, 2008, 11:18:20 AM3/3/08
to
> I am trying to install plan9port on a Linux system (Debian),
> and am getting the following error:
>
> 9 yacc -d -s bc bc.y
>
> fatal error:can't create , <nil>:1
> mk: 9 yacc -d ... : exit status=exit(1)
> mk: for i in ... : exit status=exit(1)

The <nil> is just because the error has happened
very early and yacc hasn't opened the input file yet.
If you poke around in the code you'll find that
it was trying to create bc.tab.h (or should have been)
but somehow this code (stem="bc", FILED = "tab.h"):

sprint(buf, "%s.%s", stem, FILED);
fdefine = Bopen(buf, OWRITE);
if(fdefine == 0)
error("can't create %s", buf);

ended up with an empty string in buf instead of bc.tab.h.

> So, any ideas on how to fix the build process? The problem
> stems from yacc.c at line #2173 in the sprint() function.
> Could I replace that with the standard library sprintf()
> function as a stop-gap measure?

It would be interesting to know if that makes it work,
but more interesting would be why the Plan 9 sprint
is broken. This is a pretty simple sprint call and should work.

Can you reproduce the prolem if you just run:

cd /usr/local/plan9/src/cmd
9 yacc -s bc bc.y

?

I'm also interested to see the output of:

nm /usr/local/plan9/bin/yacc | grep sprint

@erik:


> once that is fixed, it would be interesting to see if yacc
> prints a usage statement instead of printing the garbage.

The command line passed in the mkfile has worked in
thousands of other builds. Even if stem was nil, buf
should at least end up being "<nil>.tab.h" or ".tab.h"
or at the very worst, if %s was broken, ".".

I doubt the command line is being misparsed, but
I don't have any justifiable alternate theories.

Russ

David Morris

unread,
Mar 3, 2008, 11:25:27 AM3/3/08
to

Good to know. I was thinking more along the lines of a
problem because I'm using a 64-bit kernel in a 32-bit
userspace, a setup I've had other applications have problems
with, though it was a binary distribution I simply had to
recompile.

--David

David Morris

unread,
Mar 3, 2008, 12:27:56 PM3/3/08
to
On Mon, Mar 03, 2008 at 11:17:47AM -0500, Russ Cox wrote:
> > I am trying to install plan9port on a Linux system (Debian),
> > and am getting the following error:
> >
> > 9 yacc -d -s bc bc.y
> >
> > fatal error:can't create , <nil>:1
> > mk: 9 yacc -d ... : exit status=exit(1)
> > mk: for i in ... : exit status=exit(1)
>
> The <nil> is just because the error has happened
> very early and yacc hasn't opened the input file yet.
> If you poke around in the code you'll find that
> it was trying to create bc.tab.h (or should have been)
> but somehow this code (stem="bc", FILED = "tab.h"):
>
> sprint(buf, "%s.%s", stem, FILED);
> fdefine = Bopen(buf, OWRITE);
> if(fdefine == 0)
> error("can't create %s", buf);
>
> ended up with an empty string in buf instead of bc.tab.h.

At that point in the code, stem is set to "bc" as expected.

> > So, any ideas on how to fix the build process? The problem
> > stems from yacc.c at line #2173 in the sprint() function.
> > Could I replace that with the standard library sprintf()
> > function as a stop-gap measure?
>
> It would be interesting to know if that makes it work,
> but more interesting would be why the Plan 9 sprint
> is broken. This is a pretty simple sprint call and should work.

For what its worth, I just added the following lines to
yacc.c at the top of the file:

#include <stdio.h>
#define sprint sprintf

The build of plan9port just completed with no errors, the
problem is somewhere in sprint().

I'll try and find time tonight to test out the plan9port
build to verify it works. Let me know if I can provide any
other useful information. I might try tracking down the bug
later this week, but not certain I'll have much time to do
so.

> Can you reproduce the prolem if you just run:
>
> cd /usr/local/plan9/src/cmd
> 9 yacc -s bc bc.y
>
> ?

Yes, I get the exact same output.

> I'm also interested to see the output of:
>
> nm /usr/local/plan9/bin/yacc | grep sprint

Here is the result:

0804fbe0 T sprint

> @erik:
> > once that is fixed, it would be interesting to see if yacc
> > prints a usage statement instead of printing the garbage.
>
> The command line passed in the mkfile has worked in
> thousands of other builds. Even if stem was nil, buf
> should at least end up being "<nil>.tab.h" or ".tab.h"
> or at the very worst, if %s was broken, ".".

Makes sense.

> I doubt the command line is being misparsed, but
> I don't have any justifiable alternate theories.

My first thought was also the command-line was not being
parsed, but gdb shows stem is set to "bc" as expected. Its
why I suspect the problem somewhere under sprint().

--David

erik quanstrom

unread,
Mar 3, 2008, 2:04:03 PM3/3/08
to
>
> For what its worth, I just added the following lines to
> yacc.c at the top of the file:
>
> #include <stdio.h>
> #define sprint sprintf
>
> The build of plan9port just completed with no errors, the
> problem is somewhere in sprint().
>
> I'll try and find time tonight to test out the plan9port
> build to verify it works. Let me know if I can provide any
> other useful information. I might try tracking down the bug
> later this week, but not certain I'll have much time to do
> so.

it is very likely that you have broken yacc in a different
way by doing this. stdio formats are not compatable with
plan 9 print formats. for example, u is a flag when used
with sprint but a verb when used with printf.

(not to mention the fact that other programs than yacc
use sprint.)

have you verified that a standalone program with a
similar print statement has the same problems?

- erik

David Morris

unread,
Mar 3, 2008, 2:56:42 PM3/3/08
to
On Mon, Mar 03, 2008 at 02:02:04PM -0500, erik quanstrom wrote:
> >
> > For what its worth, I just added the following lines to
> > yacc.c at the top of the file:
> >
> > #include <stdio.h>
> > #define sprint sprintf
> >
> > The build of plan9port just completed with no errors, the
> > problem is somewhere in sprint().
> >
> > I'll try and find time tonight to test out the plan9port
> > build to verify it works. Let me know if I can provide any
> > other useful information. I might try tracking down the bug
> > later this week, but not certain I'll have much time to do
> > so.
>
> it is very likely that you have broken yacc in a different
> way by doing this. stdio formats are not compatable with
> plan 9 print formats. for example, u is a flag when used
> with sprint but a verb when used with printf.
>
> (not to mention the fact that other programs than yacc
> use sprint.)

Just ran a quick test. While the applications compiled,
they were non-functional as you suspected. I tried
replacing the content of sprint() with vsprintf(). All
applications compiled and the functionality I've tried so
far (that used by the wmii window manager) seems to work.

Entirely possible, though, I've just been lucky in not
hitting a string parsed differently by sprint().

> have you verified that a standalone program with a
> similar print statement has the same problems?

I just gave it a try using the following:

============================================================
#define FILED "tab.h"
#define stem "bc"

int main(int argc, char** argv)
{
/* Lines copied from yacc.c */
char buf[256];
int result = sprint(buf, "%s.%s", stem, FILED);
printf("%i: %s\n", result, buf);
/* End code from yacc.c */
return 0;
}
============================================================

The result was the same as in yacc: return value of 0 and
'buf' is empty.

--David

Russ Cox

unread,
Mar 3, 2008, 11:44:01 PM3/3/08
to
We tracked this down off-list.

Given these types:

char *buf;
uint len;

gcc-4.2 assumes that buf+len >= buf.

The test for wraparound when computing len in sprint looks like:

len = 1<<30; /* big number, but sprint is deprecated anyway */
/*
* on PowerPC, the stack is near the top of memory, so
* we must be sure not to overflow a 32-bit pointer.
*/
if(buf+len < buf)
len = -(uintptr)buf-1;

gcc-4.2 compiles this away. Adding some uintptr casts
works around the problem. This change is checked
into the plan9port code and will be in tomorrows tar file.

Because David is running 32-bit code on a 64-bit kernel,
the stack is near the very top of 32-bit address space
and tickles the gcc-4.2 bug.

It would not surprise me if there are some exploitable
buffer overflows (in standard code, not p9p) now that
gcc is silently discarding checks like this one.

Russ

Douglas A. Gwyn

unread,
Mar 5, 2008, 11:21:49 AM3/5/08
to
Russ Cox wrote:
> The test for wraparound when computing len in sprint looks like:
> len = 1<<30; /* big number, but sprint is deprecated anyway */
> /*
> * on PowerPC, the stack is near the top of memory, so
> * we must be sure not to overflow a 32-bit pointer.
> */
> if(buf+len < buf)
> len = -(uintptr)buf-1;

There are several serious portability issues with that.
The main thing is that casting a pointer to an integer type
does not in general produce a "byte address", but rather
just some encoding that can be converted back to a pointer.

And of course buf+len produces undefined behavior if buf
does not point to an array of length at least len.

Such an address-range check chould be delegated to an
auxiliary function that is tailored to the platform as
part of the porting process. That way whatever nonportable
kludge is used won't silently find its way into a port
where it doesn't work.

0 new messages