wwarthen / RomWBW

System Software for Z80/Z180/Z280 Computers
GNU Affero General Public License v3.0
332 stars 98 forks source link

RPi4: Build failure "zxcc: Cannot locate bios.bin" when path depth is less than 4 levels #362

Closed skullandbones closed 1 year ago

skullandbones commented 1 year ago

@wwarthen I attempted to build the dev branch with HEAD commit 092e44c62e450a21a37809ce842981b33d8dc317

I decided to do a test build in the /run directory which is a RAM based tmpfs file system.

The path was /run/test/RomWBW, I did make but the build failed:

SLR180 Copyright (C) 1985-86 by SLR Systems Rel. 1.32 #NL0029

 zmo-rw01/HF
End of file Pass 1
End of file Pass 2
 0 Error(s) Detected.
 937 Absolute Bytes. 91 Symbols Detected.

../../../Tools/Linux/zxcc MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-RW01
+ ../../../Tools/Linux/zxcc MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-RW01
zxcc: Cannot locate bios.bin

                            make[3]: *** [Makefile:10: zmp.com] Error 1
make[3]: Leaving directory '/run/test/RomWBW/Source/Apps/ZMP'
make[2]: *** [../../Tools/Makefile.inc:136: all] Error 2
make[2]: Leaving directory '/run/test/RomWBW/Source/Apps'
make[1]: *** [../Tools/Makefile.inc:136: all] Error 2
make[1]: Leaving directory '/run/test/RomWBW/Source'
make: *** [Makefile:3: all] Error 2

I did some experiments by using a fresh git clone of RomWBW in various directories to see what worked and what failed: /tmp/RomWBW - build failed /tmp/temp/RomWBW - build failed /tmp/temp/temp2/RomWBW - build succeeded

So it seems that there is a problem building bios.bin as it appears to depend on the depth of the path to the RomWBW directory.

I didn't see this failure while looking at issue 358 because my path was /home/pi/projects/romwbw

Dean

skullandbones commented 1 year ago

In the good case:

/run/test/temp/temp2/RomWBW$ find . | grep bios.bin
./Tools/Linux/bios.bin
./Tools/zxcc/bios.bin - is in git repo
./Tools/unix/zxcc/bios.bin
./Tools/unix/zxcc/cpm/bios.bin - is in git repo
./Source/pSys/bios.bin

In the bad case:

/tmp/RomWBW$ find . | grep bios.bin
./Tools/zxcc/bios.bin
./Tools/Linux/bios.bin
./Tools/unix/zxcc/cpm/bios.bin
./Tools/unix/zxcc/bios.bin

So it seems that ./Source/pSys/bios.bin is missing at the point the build fails.

The error message Cannot locate bios.bin comes from Tools/unix/zxcc.c:

void load_bios(void)
{
    char dir[CPM_MAXPATH + 1], fname[CPM_MAXPATH + 1];
    char* q;
    size_t bios_len;

    FILE* fp = fopen("bios.bin", "rb");
    if (!fp)
    {
        strcpy(fname, bindir80);
        strcat(fname, "bios.bin");
        fp = fopen(fname, "rb");
    }
    if (!fp)
    {
#ifdef _WIN32
        dir[0] = 0; /* use strncat in case the path is very long */
        strncat(dir, _pgmptr, CPM_MAXPATH - 8);   /* copy the executable path */
#elif defined(__APPLE__)
        uint32_t size = CPM_MAXPATH - 8;
        _NSGetExecutablePath(dir, &size);
#else
        readlink("/proc/self/exe", dir, CPM_MAXPATH - 8);   /* allow room for bios.bin */
#endif
        q = strrchr(dir, DIRSEPCH);
        *++q = 0;
        strcpy(fname, dir);
        strcat(fname, "bios.bin");
        fp = fopen(fname, "rb");
    }
    if (!fp)
    {
        fprintf(stderr, "%s: Cannot locate bios.bin\n", progname);    <---- Appears to fail here
        zxcc_term();
        zxcc_exit(1);
    }
    bios_len = fread(RAM + 0xFE00, 1, 512, fp);
    if (bios_len < 1 || ferror(fp))
    {
        fclose(fp);
        fprintf(stderr, "%s: Cannot load bios.bin\n", progname);
        zxcc_term();
        zxcc_exit(1);
    }
    fclose(fp);

    DBGMSGV("Loaded %d bytes of BIOS\n", bios_len);
}
skullandbones commented 1 year ago

Modified zxcc.c to show the bios.bin path and filename: https://github.com/skullandbones/RomWBW/tree/Issue-362_RPI4_no_bios.bin

Repeated a failed build and the reported path shows corruption in the path string:

make[3]: Leaving directory '/tmp/RomWBW/Source/Apps/Test'
+ make --directory ZMP
make[3]: Entering directory '/tmp/RomWBW/Source/Apps/ZMP'
../../../Tools/Linux/zxcc MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-RW01
+ ../../../Tools/Linux/zxcc MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-RW01
zxcc: Cannot locate /tmp/RomWBW/Tools/Linux/zxccV/bios.bin

                                                          make[3]: *** [Makefile:10: zmp.com] Error 1
make[3]: Leaving directory '/tmp/RomWBW/Source/Apps/ZMP'
make[2]: *** [../../Tools/Makefile.inc:136: all] Error 2
make[2]: Leaving directory '/tmp/RomWBW/Source/Apps'
make[1]: *** [../Tools/Makefile.inc:136: all] Error 2
make[1]: Leaving directory '/tmp/RomWBW/Source'
make: *** [Makefile:3: all] Error 2

The path string contains a "V" that should not be there.

wwarthen commented 1 year ago

Wow, this is very odd. I admit that I did see this exact error once when I first tried an RPi build, but it disappeared after I ran the build again.

Nothing about the build has changed with respect to this. Also, I am not seeing this anywhere but Raspberry Pi. I don't see an obvious problem with the code. Can't imagine how the "V" got there.

The "bios.bin" in the pSys directory is produced by the build. It is not the same bios.bin as the others. It is not in GitHub and should not be. I think you see it in the successful builds because the build produced it.

I will take a look at this in more detail, but probably won't be able to get to it until Monday. Very busy weekend for me. If you have more time to play with this, it would be helpful to see the output of readlink before it is manipulated. It sort of looks like the readlink call is producing invalid results.

Thanks,

Wayne

wwarthen commented 1 year ago

Had a few spare minutes and quickly looked up the documentation on readlink(). So... turns out that readlink() does NOT null terminate the resulting string. Basically, it is a miracle that this bug has not been encountered before. The fix is trivial; just need to null terminate the string using the length returned by the readlink() call.

I can take care of this in the next day or two.

Thanks,

Wayne

skullandbones commented 1 year ago

@wwarthen I have created PR #363 based on your suggestion of adding a NUL termination to the dir string.

My testing on my RPi4 is now successful with no load bios.bin failures.

Please take a look at my PR and provide review comments. If you think the PR is good enough then please go-ahead and merge it.

Thanks, Dean

wwarthen commented 1 year ago

Hi @skullandbones,

Your PR was great and has been merged. I will be closing this issue now.

Thank you!

Wayne