Open JonnyH opened 8 months ago
+1:)
Is it OK to comment that the time spent on the "Play XCom: Apocalypse in one session for multiple hours without quitting" reproduction case here, accounting for all the different platforms and dosbox-versions this has been confirmed on, must be an envieable amount? Kudos.
Describe the bug
I'm looking at a sporadic issue running X:Com Apocalypse, and thing I've found an issue in how dosbox handles multiple "active" DTA blocks, the end result being a FindFile incorrectly fails to find an existing file, and the game crashes (specifically, shows a "Please insert the CD" screen).
So XCom: Apocalypse was compiled using the watcom C compiler, and seems to use it's libc file handling utilities on DOS.
It seems use a wrapper for the find file functions (FindFirst, int 21,4e and FindNext, int21,4f) that first call SetDTA (int21,1a) to keep find contexts separate.
This app searches for files on both the HDD and CD, but seems to interleave the searches, so you end up with something like the following pseudocode:
As far as I can see from the dos documentation I can find, this is acceptable - though both calls are interleaved, each should use a completely separate DTA, and no other calls modify the state of the filesystem, so it should never fail to find an existing file. Even if it might be a bit of an odd pattern.
Now the problem seems to be with Dosbox is when we introduce the DOS_Drive_Cache, and the second FindFirst (to DTA_B above) causes the cache to be invalidated - in
bool DOS_Drive_Cache::FindFirst(char* path, uint16_t& id)
:This invalidates all file handles - including the one being stored in DTA_A, so when the FiindNext() call happens in
bool DOS_Drive_Cache::FindNext(uint16_t id, char* &result, char* &lresult)
the error path gets hit:and the call fails without finding an otherwise existent file.
This seems to show up as the following in a log with Files I/O logging enabled:
Steps to reproduce the behaviour
The repro case is rather hard - it seems to be "Play XCom: Apocalypse in one session for multiple hours without quitting", and you get a "Please Insert The CD" error window show up when trying to start a new battle mission.
But I believe using the pseudocode above, a tighter example could be made - all you need to do is ensure that enough directories are open to fill the cache and cause a flush while there's still another "live" DTA somewhere.
What operating system(s) this bug have occurred on?
Seen on Windows 10, Windows 11 and Linux amd64
What version(s) of DOSBox-X have this bug?
Latest master, occurs at least back to original dosbox 0.72
Have you checked that no similar bug report(s) exist?
Code of Conduct & Contributing Guidelines