clean_obj_queue crash

Posted by Syriac on Tue 04 Aug 2009 08:28 PM — 12 posts, 50,096 views.

#0
For some reason its passing an unacceptable value through the function and I can't figure out why. :(

Program received signal SIGSEGV, Segmentation fault.
0x000000324207725a in _int_free () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.10.1-2.x86_64 nss-softokn-freebl-3.12.3.99.3-2.11.3.fc11.x86_64 zlib-1.2.3-22.fc11.x86_64
(gdb) bt
#0  0x000000324207725a in _int_free () from /lib64/libc.so.6
#1  0x00000000004e5cc3 in free_obj (obj=0x109bc00) at handler.c:6892
#2  0x00000000004e5965 in clean_obj_queue () at handler.c:6841
#3  0x0000000000582f95 in update_handler () at update.c:3554
#4  0x00000000004a2835 in game_loop () at comm.c:716
#5  0x00000000004a1d8c in main (argc=1, argv=0x7fffffffe6c8) at comm.c:343


in handler.c

/* borrowed from smaug 1.8 */
void clean_obj_queue( void )
{
   OBJ_DATA *obj;

   while( extracted_obj_queue )
   {
      obj = extracted_obj_queue;
      extracted_obj_queue = extracted_obj_queue->next;
      free_obj( obj );
      --cur_qobjs;
   }
}

/* Deallocates the memory used by a single object after it's been extracted. */
void free_obj( OBJ_DATA * obj )
{
   AFFECT_DATA *paf, *paf_next;
   EXTRA_DESCR_DATA *ed, *ed_next;
   // REL_DATA *RQueue, *rq_next;
   MPROG_ACT_LIST *mpact, *mpact_next;

    if( !obj ) {
        bug( "%s: obj = NULL", __FUNCTION__ );
        return; }


   for( mpact = obj->mpact; mpact; mpact = mpact_next )
   {
      mpact_next = mpact->next;
      DISPOSE( mpact->buf );
      DISPOSE( mpact );
   }
   /*
    * remove affects
    */
   for( paf = obj->first_affect; paf; paf = paf_next )
   {
      paf_next = paf->next;
      DISPOSE( paf );
   }
   obj->first_affect = obj->last_affect = NULL;

   /*
    * remove extra descriptions
    */
   for( ed = obj->first_extradesc; ed; ed = ed_next )
   {
      ed_next = ed->next;
      STRFREE( ed->description );
      STRFREE( ed->keyword );
      DISPOSE( ed );
   }  
   obj->first_extradesc = obj->last_extradesc = NULL;

   STRFREE( obj->name );
   STRFREE( obj->description );
   STRFREE( obj->short_descr );
   STRFREE( obj->action_desc );
   DISPOSE( obj );  //<---Crash originates here.
   return;
}



call to function in update.c is clean_obj_queue( );
USA #1
Do any of these help?
http://www.gammon.com.au/forum/bbshowpost.php?id=5017
http://www.gammon.com.au/forum/bbshowpost.php?id=4568
http://www.gammon.com.au/forum/bbshowpost.php?id=4526
Amended on Tue 04 Aug 2009 08:39 PM by Zeno
#2
Doesn't seem to help much... :(
#0  0x000000324207725a in _int_free () from /lib64/libc.so.6
#1  0x00000000004e610d in free_obj (obj=0x10a35a0) at handler.c:6903
#2  0x00000000004e5ccf in clean_obj_queue () at handler.c:6844
#3  0x000000000058355b in update_handler () at update.c:3554
#4  0x00000000004a2a79 in game_loop () at comm.c:716
#5  0x00000000004a1fd0 in main (argc=1, argv=0x7fffffffe6c8) at comm.c:343
(gdb) f 
#0  0x000000324207725a in _int_free () from /lib64/libc.so.6
(gdb) f 1
#1  0x00000000004e610d in free_obj (obj=0x10a35a0) at handler.c:6903
6903	   DISPOSE( obj );
(gdb) f 2
#2  0x00000000004e5ccf in clean_obj_queue () at handler.c:6844
6844	      free_obj( obj );
(gdb) f 3
#3  0x000000000058355b in update_handler () at update.c:3554
3554	    clean_obj_queue();		/* dispose of extracted objects*/
(gdb) f 2
#2  0x00000000004e5ccf in clean_obj_queue () at handler.c:6844
6844	      free_obj( obj );
(gdb) f 1
#1  0x00000000004e610d in free_obj (obj=0x10a35a0) at handler.c:6903
6903	   DISPOSE( obj );
(gdb) print *obj
$1 = {next = 0xdf0f50, prev = 0x10a3420, next_content = 0xdf10c0, prev_content = 0x0, first_content = 0x0, last_content = 0x0, in_obj = 0x0, carried_by = 0x0, 
  originator = 0x0, ownerorig = 0x0, first_extradesc = 0x0, last_extradesc = 0x0, first_affect = 0x0, last_affect = 0x0, affected = 0x0, pIndexData = 0x9bc200, in_room = 0x0, 
  name = 0x0, short_descr = 0x0, description = 0x0, id_mark = 0x0, action_desc = 0x0, item_type = 9, mpscriptpos = 0, extra_flags = {bits = {0, 0, 0, 0}}, magic_flags = 0, 
  wear_flags = 33, mpact = 0x0, mpactnum = 0, wear_loc = -1, weight = 5, cost = 0, level = 1, tmag = 0, timer = 0, value = {2, 2, 0, 0, 0, 0}, count = 1, serial = 4159, 
  room_vnum = 10333}
Amended on Wed 05 Aug 2009 10:42 AM by Syriac
Australia Forum Administrator #3
All I can suggest is maybe you are disposing of the object twice. Perhaps put a breakpoint in clean_obj_queue and watch the pointers, see if one shows up twice.

As another thread suggested, try running valgrind on the program, see if that picks up memory allocation problems.
USA #4
How up to date are you on bugfixes from the SmaugFUSS site? The code you put here looks fine, so this is probably the result of another problem elsewhere that leads up to it.
#5
As far as I can tell I am up-to-date, I tried to bring over the dispose and strfree functions from the mud.h file however they weren't working right for some reason. Could that be the problem?

also here is this --
(gdb) p clean_obj_queue
$2 = {void (void)} 0x4e49a5 <clean_obj_queue>
USA #6
If your codebase is not setup to compile using g++ you won't be able to just take the STRFREE and DISPOSE macros as they are from SmaugFUSS. They've been modified to use the c++ typeid call to aid in pinpointing places where the wrong macro is used to deallocate the string.
#7
After some further probing I'm 99.9% sure the issues lies somewhere in the DISPOSE(obj) function... STRFREE works flawlessly as can be seen in our random item system when it names objects. What a frustrating little problem. We've just ran without the clean_obj_queue for so long using reboot/hotboot as a work around.
#8
#define DISPOSE(point)                                          \
do                                                              \
{                                                               \
if (!(point))                                                   \
{                                                               \
bug( "Freeing null pointer %s:%d", __FILE__, __LINE__ ); \
fprintf( stderr, "DISPOSEing NULL in %s, line %d\n", __FILE__, __LINE__ ); \
}                                                               \
else free(point);                                               \
point = NULL;                                                   \
} while(0)


the point = NULL looks odd to me since it was just emptied right before with the free(point) am I crazy for thinking this?
Australia Forum Administrator #9
What do you mean "emptied"?

What that code is doing is checking if point is not NULL. If it *is* NULL it raises an error. If not, it frees the memory, and then sets point to NULL, so next time you won't try to dispose of it twice.

It's not foolproof, you can make copies of pointers, so only one of the copies is set to NULL.
#10
Well, I'm stumpped... I've tried just about everything, the issue appears to originate with the DISPOSE code - I've tried taking it from smaug 1.8, smaugfuss, a snippet I found online... nothing seems to work. I just cannot figure it out. I've just decided to comment out the clean_obj_queue... we haven't used it for a long time, the only bad thing is it requires daily hotboot/reboots.
#11
Such a dumb oversight - was using str_dup instead of STRALLOC when setting names on random items. Therefore, names were not technically null but were also not mapped to memory, so when it attempted to clear the memory it hit a null.