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
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
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
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
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
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
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
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
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
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
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
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.