I just had the following lovely assertion:
This looks like one of those cases where simply examining the stack is not very useful. Was I bitten by some debugging code that was inserted to track down the recent pile issues?
Note that it occurred during an autosave. Whole games get borked when you abort in the middle of writing the save file to disc. I didn't even get a tombstone. :'( I know; first world problems. Regardless, the game should never abort while writing to disc. This was an assert, so if I hadn't compiled with debugging symbols, it may not have failed. But I'm not sure; I didn't look at the code to see if the next line would have crashed. That said, a crash while writing to disc is a worst case scenario for a game.
Of course, the best solution is to write perfect code, but failing that, you can replace your SIGSEGV handler while saving and use longjmp() to unwind back to before you started saving. If it was an autosave, the user can go on blissfully unaware, and hopefully it never matters. If it's a quit-save, maybe you can stick @ in town and try to save again? That could really suck, but it's better than a corrupt save file.
Code:
angband: cave.c:435: object_lists_check_integrity: Assertion `pile_contains(c->squares[obj->iy][obj->ix].obj, obj)' failed. Program received signal SIGABRT, Aborted. 0x0000007fb7c77528 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 54 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 0x0000007fb7c77528 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 #1 0x0000007fb7c789e0 in __GI_abort () at abort.c:89 #2 0x0000007fb7c70c04 in __assert_fail_base ( fmt=0x7fb7d5d0c0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x523f10 "pile_contains(c->squares[obj->iy][obj->ix].obj, obj)", file=file@entry=0x523eb8 "cave.c", line=line@entry=435, function=function@entry=0x523fe0 <__PRETTY_FUNCTION__.9844> "object_lists_check_integrity") at assert.c:92 #3 0x0000007fb7c70cac in __GI___assert_fail ( assertion=0x523f10 "pile_contains(c->squares[obj->iy][obj->ix].obj, obj)", file=0x523eb8 "cave.c", line=435, function=0x523fe0 <__PRETTY_FUNCTION__.9844> "object_lists_check_integrity") at assert.c:101 #4 0x00000000004048ec in object_lists_check_integrity (c=0xa66838, c_k=0x990b98) at cave.c:435 #5 0x000000000040a140 in square_know_pile (c=0xa66838, y=4, x=33) at cave-square.c:916 #6 0x0000000000405670 in square_note_spot (c=0xa66838, y=4, x=33) at cave-map.c:219 #7 0x000000000040bf34 in update_one (c=0xa66838, y=4, x=33, blind=0) at cave-view.c:514 #8 0x000000000040c870 in update_view (c=0xa66838, p=0x77f4d8) at cave-view.c:659 #9 0x00000000004a88ec in update_stuff (p=0x77f4d8) at player-calcs.c:2352 #10 0x00000000004a8bec in handle_stuff (p=0x77f4d8) at player-calcs.c:2470 #11 0x00000000004d779c in save_game () at ui-game.c:486 #12 0x00000000004d4d94 in new_level_display_update ( type=EVENT_NEW_LEVEL_DISPLAY, data=0x0, user=0x0) at ui-display.c:2207 #13 0x000000000042259c in game_event_dispatch (type=EVENT_NEW_LEVEL_DISPLAY, data=0x0) at game-event.c:43 #14 0x00000000004228f8 in event_signal (type=EVENT_NEW_LEVEL_DISPLAY) at game-event.c:142 #15 0x00000000004255c8 in on_new_level () at game-world.c:872 #16 0x0000000000425b0c in run_game_loop () at game-world.c:1002 #17 0x00000000004d7638 in play_game (new_game=false) at ui-game.c:435 #18 0x000000000051c994 in main (argc=1, argv=0x7ffffff408) at main.c:524 (gdb)
Note that it occurred during an autosave. Whole games get borked when you abort in the middle of writing the save file to disc. I didn't even get a tombstone. :'( I know; first world problems. Regardless, the game should never abort while writing to disc. This was an assert, so if I hadn't compiled with debugging symbols, it may not have failed. But I'm not sure; I didn't look at the code to see if the next line would have crashed. That said, a crash while writing to disc is a worst case scenario for a game.
Of course, the best solution is to write perfect code, but failing that, you can replace your SIGSEGV handler while saving and use longjmp() to unwind back to before you started saving. If it was an autosave, the user can go on blissfully unaware, and hopefully it never matters. If it's a quit-save, maybe you can stick @ in town and try to save again? That could really suck, but it's better than a corrupt save file.
Comment