[cc65] Re: readdir bug

From: Ullrich von Bassewitz <uz1musoftware.de>
Date: 2012-09-14 13:01:18
Hi!

On Thu, Sep 13, 2012 at 09:05:46PM +0200, Spiro Trikaliotis wrote:
> as "thank you" for Uz' permanent support, I thought I'd try to work on
> the readdir bug that does not allow to present more than 8 directory
> entries.

Well actually my support could be a lot better, but thank you anyway:-)

I've also spent 2-3 hours debugging the problem a few days ago. I think I can
rule out some things, but didn't find the actual error. So let's try to throw
our knowledge together ...

I will first recapitulate what is known to me, then present my findings, then
comment on yours.

So... I've tested reading directories in several ways. Just reading seems to
work and is not limited to a specific number of entries.

Olivers test program does not only read the directory, but does also open and
close each file. This triggers the error somehow as can be seen by taking
Olivers program and commenting out the lines that open/close the file. What is
also interesting is that it fails with true drive emulation in VICE but works
otherwise. At least here with my version of VICE.

Since 7 entries can be opened, plus the directory, my first assumption was
that it has to do with the maximum number of open files (which is 8 for the
CBM platform). Assuming that closing the files doesn't work correctly, the
maximum number could be reached, which may trigger some bug.  However STDIN,
STDOUT and STDERR are also open. This means 11 open files in total, which does
not match the 8 allowed. To rule this out, I checked the internal library data
structures used to track open files just before and after the error occurs and
they're ok. So this doesn't seem to be the problem.

My next assumption was that it has to do with the KERNAL file table, which has
10 entries. I did also check them before and after the error and they seemed
also ok.

So I traced the code to see where the error comes from. It happens in the loop
which is preceeded by the comment "Read the next file entry into the buffer".
There is no error reading from the directory, but the first byte read into the
bufer is actually zero, so there is in fact no data in the buffer which leads
to a parse error later.

This was the point where I went out of time and stopped. One would have to
check what actually happens when the call to _dirread1 occurs.

Now ...

> In fact, currently, I'd think it is a compiler bug that triggers it.

I doubt this is the case, see below.

> You see, I instrumented with some outputs, and I modified the case 2 by
> making it as simple as possible.

Please note that instrumenting the output with printf is dangerous, because
printf does file I/O and therefore interferes heavily with the calls that read
from the directory. Each time you call printf, the KERNAL is called to switch
files. This is why I didn't use this method in the give case. I had used it in
an earlier case and run into trouble.

> The "#if 0" is important: If I leave the line as is, then the routine
> processes all directory entries of the 1541 disk, regardless of how many
> of them are there. (Of course, the values output are not correct, but
> this is not the issue I want to show.)

I've tried adding the #if 0 to the code and compared the assembly results. It
didn't change the code with the exception of a subroutine call and a store of
the accumulator into a static storage location. I cannot really imagine this
being the cause of the problem, especially because the cbm_filetype routine
seems to be rather harmless.

> If I change it to "#if 1" instead, then the buffer output in "1:" and
> "2:" is WRONG after the 8th directory entry. That's the case where
> normally, readdir() aborts after the 8th entry. Here, it does not
> because I added the "return &entry;" after the printf("7-...").

This is exactly what I experienced - see above. It is not that the directory
file handle is closed or invalid, it is that read() returns data that doesn't
seem to be from the directory.

I will try to trace that down once I find the time. Or in case you want to
have a look at it: Let the program run just before the last call to readdir,
then break at _dirread1 and check what it does.

Unfortunately this is complicated by not having a decent debugger available.
My current version of VICE is not even able to load the label file any more.
It reads it, but cannot find most of the symbols later. So I have to lookup
the symbols manually in the map or debug files. Unfortuntely their values
change with every change in the source ...

Regards


        Uz


-- 
Ullrich von Bassewitz                                  uz@musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Fri Sep 14 13:02:48 2012

This archive was generated by hypermail 2.1.8 : 2012-09-14 13:02:52 CEST