saving vs ball&chain

I started activating new program_state.saving and discovered that
saving of ball and chain could access freed memory.  The change
for the former and fix for the latter are mixed together here (but
easily distinguishable).

The saving flag inhibits status updating and perm_invent updating,
also map updating that goes through flush_screen().  That should
fix the exception triggered after an impossible warning was issued
during a save operation.  impossible() goes through pline() which
tries to bring the screen up to date before issuing a message.
During save, data for that update can be in an inconsistent state.

The code to save ball and/or chain when not on floor or in invent
(I think swallowed is the only expected case) was examining the
memory pointed to by uball and uchain even if saving the level had
just freed floor objects and saving invent had just freed carried
objects.  So for the usual cases, stale pointer values for uball
and uchain would be present and checking their obj->where field
was not reliable.
This commit is contained in:
PatR
2020-12-02 06:29:58 -08:00
parent 1360e63644
commit 4d6a140d34
7 changed files with 119 additions and 45 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 decl.h $NHDT-Date: 1606765210 2020/11/30 19:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.246 $ */
/* NetHack 3.7 decl.h $NHDT-Date: 1606919254 2020/12/02 14:27:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.247 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2007. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1103,6 +1103,8 @@ struct instance_globals {
boolean havestate;
unsigned ustuck_id; /* need to preserve during save */
unsigned usteed_id; /* need to preserve during save */
struct obj *looseball; /* track uball during save and... */
struct obj *loosechain; /* track uchain since saving might free it */
/* shk.c */
/* auto-response flag for/from "sell foo?" 'a' => 'y', 'q' => 'n' */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 extern.h $NHDT-Date: 1606343573 2020/11/25 22:32:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.882 $ */
/* NetHack 3.7 extern.h $NHDT-Date: 1606919254 2020/12/02 14:27:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.886 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -3122,6 +3122,7 @@ E void FDECL(flip_worm_segs_horizontal, (struct monst *, int, int));
E void FDECL(setworn, (struct obj *, long));
E void FDECL(setnotworn, (struct obj *));
E void NDECL(allunworn);
E struct obj *FDECL(wearmask_to_obj, (long));
E long FDECL(wearslot, (struct obj *));
E void FDECL(mon_set_minvis, (struct monst *));