mac@ardent.com (10/10/89)
A rust monster was chewing up my hard shoes, so I took them off; to see: Segmentation fault (core dumped) It seems that in Boots_off(), unlike all the other Item_off() routines, setworn((item *)0,item_class) gets called before the switch statement that prints the cute message or whatever. There is a comment that says this is to support the Levitation boots, which end up returning from float_down() or some such. Well, it seems that setworn reaches in and effectivly undefines *uarmf, which even though another copy was made (into *obj), since the target gets zero'ed, all pointers to dereference to zero. Hence seg fault; Hence the following patch: [Note: I could have just cached obj->otyp, but was not sure what other routine might need obj or uarmf] [Note 2: This occurred on an Ardent Titan, which might have been a bit more ambitious than other machines at optimization; however, the code to me looks to be broken...] *** do_wear.c.old Mon Oct 9 22:45:31 1989 --- do_wear.c Mon Oct 9 22:49:33 1989 *************** *** 116,126 **** register struct obj *obj = uarmf; /* For levitation, float_down() returns if Levitation, so we * must do a setworn() _before_ the levitation case. */ long oldprop = u.uprops[objects[uarmf->otyp].oc_oprop].p_flgs & ~(WORN_BOOTS | TIMEOUT); - setworn((struct obj *)0, W_ARMF); switch(obj->otyp) { case SPEED_BOOTS: if (!oldprop) { --- 116,128 ---- register struct obj *obj = uarmf; /* For levitation, float_down() returns if Levitation, so we * must do a setworn() _before_ the levitation case. + * mac@ardent: however, setworn cannot be called until + * after the switch statement, as it alters uarmf, which is obj... + * hence if Lev, call there, else at end. */ long oldprop = u.uprops[objects[uarmf->otyp].oc_oprop].p_flgs & ~(WORN_BOOTS | TIMEOUT); switch(obj->otyp) { case SPEED_BOOTS: if (!oldprop) { *************** *** 151,156 **** --- 153,160 ---- break; case LEVITATION_BOOTS: if (!oldprop) { + /* Fix by mac@ardent 10/9/89 */ + setworn((struct obj *)0, W_ARMF); (void) float_down(); makeknown(obj->otyp); } *************** *** 162,167 **** --- 166,173 ---- break; default: impossible("Unknown type of boots (%d)", obj->otyp); } + /* Fix by mac@ardent 10/9/89 */ + setworn((struct obj *)0, W_ARMF); return 0; } mac@ardent.com [sorry for posting a copy of this to r.g.h; it looks so bad there what with the current discussion about how bugs should go here, hints/games discussions there.... Oh well.]