mike@rlvd.UUCP (Mike Woods) (12/12/85)
<@------*L The lightning bolt hits the line eater--more--> Well it was like this... I was playing ultra-rogue and doing the best ever. I was on level 82 (having got there the hard way; no banishment for me!) with about 20,000,000 experience (though the nasty evil sorceress' had pinched all the artifacts!) when I accidently hit a quartermaster (for about third or fourth time in the game) (this may not be significant). Of course he vanished and woke up all the monsters on the level (it was a maze level). I didn't think much of this (I don't even know if it really did matter) but when I went down to level 83 I found that the dragons and giants seemed to have got a lot tougher and were using nastier staffs (or whatever they use to fire flames/ice/lightning etc.). I did the level, went down to level 84 and decided to save the game. Trouble was, it wouldn't let me, whenever I entered a filename the game came back with error 0! I strolled on round level 84 but by now the game was running very slowly (the machine was hardly loaded at all). I went down to 85 and decided to take out the party room and quit. The monsters were getting tougher and tougher (even the Nymphs summoned by the sorceresses took four or five hits with a silvered +8 +8 two handed sword) and I met up with an evil sorceress who just would not die (I must have hit her 30-40 times) so I decided it was time to end the game (due only to the strange behaviour of the game, my fighter could have gone on for a lot longer (he fell into a Platinum Dragon's lair on level 72 and had killed all the monsters in it with his sword)). I quit and it went through the motions of counting up my gold but when it printed up the top ten it gave a bus error when it attempted to print my score (which, at 21,000,000, was first). To say that I was not pleased is a little of an understatement. I examined the core and found that the program had been doing an fseek on a NULL file stream. My score was not added to the score file. Is this a known bug? Is it likely to happen everytime I do well? Will it be fixed? In older versions of Rogue there were usually ways round the fatal bugs, has anyone found a way round this one? Any information will be gladly accepted. Mike Woods. -- UK JANET: mike@uk.ac.rl.vd UUCP: ..!mcvax!ukc!rlvd!mike
laman@ncr-sd.UUCP (Mike Laman) (12/17/85)
In article <973@rlvd.UUCP> mike@rlvd.UUCP (Mike Woods) writes: > >I was playing ultra-rogue and doing the best ever. I was on level 82 ... >when I accidently hit a quartermaster (for about >third or fourth time in the game) (this may not be significant). ... >I didn't think much of this (I don't even know if it >really did matter) but when I went down to level 83 I found that the >dragons and giants seemed to have got a lot tougher... > >I did the level, went down to level 84 and decided to save the game. >Trouble was, it wouldn't let me, whenever I entered a filename the >game came back with error 0! I strolled on round level 84 but by now >the game was running very slowly (the machine was hardly loaded at >all). > >I went down to 85 and ... so I decided it was >time to end the game... >I quit and it went through the motions of counting up my gold but >when it printed up the top ten it gave a bus error when it attempted >to print my score (which, at 21,000,000, was first). > >To say that I was not pleased is a little of an understatement. I >examined the core and found that the program had been doing an fseek >on a NULL file stream. My score was not added to the score file. > >Is this a known bug? Is it likely to happen everytime I do well? >Will it be fixed? In older versions of Rogue there were usually ways >round the fatal bugs, has anyone found a way round this one? > >Any information will be gladly accepted. I have never seen nor played urogue, but I think I may know what the problem is. (As a matter of fact, I don't even know what you mean by "going through the motions of counting up my gold".) How many times did you save the game? I suspect that you have filled up all of your file stream slots in the process. This can occur two ways. The obvious way is that some routine has done an fopen() but no fclose(). If you keep calling the routine, you will use up all of your available file stream slots (and file descriptors in this case too). I don't know anything about urogue, much less how it is implemented, so I don't know if there are user commands that are answered by fopening a file and printing it. If so, it is possible they forgot to fclose() it. The reason I'm venturing a guess, is because rogue has the same problem, but for a different reason. If you don't understand then start up a game of rogue and save it. Now restart the saved game and save it, again. Keep restarting and saving the game. You will get to save the game only 17 times. Hmmmmm 17 you say... Yep. Notice that 20 - 3 = 17. Big deal you say. What if I say _NFILE - 3 = 17 where 3 is the sum of initially set file descriptors (stdin, stdout, stderr) and _NFILE == 20 for many systems. Ok. Now, how are the 17 FILE stream slots being used up? Easy :-). The code to save a game may look like this: if((outf = fopen(savefile)) == NULL) Complain and return; Encrypt (magically of course) the data while writing it out. fclose(outf); The code to restore a saved game may look like this: if((inf = fopen(savedfile)) == NULL) Complain and return; Decrypt (more magic too) the data while overwriting the process' data. fclose(inf); In rogue, the program is saved by encrypting (somehow :-)) the data between an interesting starting data address in your running process out to the end of the data area (sbrk(0)). Now look again at the algorithm for saving a game. Encrypt the data THEN fclose the FILE stream. Problem: The stdio data structure (_iob[20]) is already ``saved'' out in the save file, so the fclose() in the running process DOESN'T FREE THE SLOT IN THE SAVE FILE (emphasis mine :-)). Now when you restore the game, your stdio data structure (_iob[]) is OVERWRITTEN with the saved one. there is n problem with the file descriptors themselves. They were closed when you exited the saved game before in an earlier process. But the ``new'' stdio data structure (_iob[]) has a slot that is used up (the associated file descriptor was closed along ago). So each time you save a game you use up a slot in the _iob[]. The fix is simple: 1) Use a global FILE stream pointer for the output FILE stream used for saving the data, 2) After reading in the restore data (when restarting a game) fclose the global file stream pointer. This works since the FILE stream pointer is just a pointer into _iob[]. The stdio calls close() which fails. The close is ignored, but more importantly, the _iob[] slot is freed, so the next fopen will get that slot. The work around depends on what the problem is. If it is the save/restore problem, then don't save a game up to the limit. If it is an fopen of some data file without an fclose, then don't issue the command that eats up the slots by forgetting to close the file stream pointer. I suspect the reason you got your FILE stream pointer equal to 0 (NULL) was because an fopen() was done on the score file, but NO error checking was performed on the return value. Thus the FILE stream pointer was zero (NULL) as you snooping found. Does anybody know the history/ancestry of urogue? From what version of rogue did it originate (if at all)? I wonder how many other bugs there are from the rogue from which it originated. Sorry, for the long reply, but it is a complex problem. It's simple once you understand it. This has sparked my interest in urogue and I'd like to play it. Anyone have a binary for a PYR system running 2.5? I know I have a snowball's chance in hell of getting the source. It sounds like I fun game, despite the bugs. But then we roguers have learned to live with bugs. Reminds me of the Nymph and arrow bugs. Mike Laman UUCP: {ucbvax,philabs,sdcsla}!sdcsvax!ncr-sd!laman