Segmentation Fault core dumped

Posted by Robert Powell on Tue 13 Jan 2004 02:27 AM — 11 posts, 38,084 views.

Australia #0
I have added some code that when used crashes the mud and gives says its a segmentation fault and that the core has dumped, but befor i post all the code and bug you to help me fix it i would like to have a go at trying to fix it first.

What i would like are some tips on debugging the code, i have tryed to find the core file to examin but couldnt find it, and dont know much about using the debugger.

BTW im running Mandrake 9.2 and using Kdevelop gui as im not much with the comnand line.
USA #1
The only help I could give you with a specific debugger would be with GDB.

However, the theory of debugging is basically as follows...

The "core dump" is somewhat of a trace of the program's execution to the point of the crash. Most importantly, it (almost always) contains a stack trace: a list of the functions called in which order up until the crash.

The stack trace is the most critical part for most of the debugging you will do. It will show you exactly where the program crashed, what lines from which functions, and called in what order.

Stack traces can have different names; Visual Studio calls it "examining the call stack" or something like that.

You can also print out (or examine in a GUI environment) variables, which is useful to see why a particular thing died... did it have bogus variable information? etc.

The core dump will usually be in the directory your program runs under. If you're using standard SMAUG (or most derivatives), that will be in the area/ subdirectory.

Sometimes, a core file is not generated. If that is the case, take a look at:
http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=2953
http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=3383
for some extra information regarding core dumps.

Hope that helps... :)
Australia #2
Ok i have found the core files but i cant open them in kdevelop cause it keeps screwing up the paths and i cant work out how to give it the correct path, how do i examin them from the command line.
USA #3
Go to wherever your SMAUG source is.

e.g. cd ???/???/smaug/src

Now go up one directory...

cd ..

Then type:

gdb src/smaug area/core

Where "smaug" is the name of the executable, and "core" is the filename of your core dump. It might be called core.xxxx in which case you use the filename of the real file.

This will launch GDB. You can type "help" to get a list of commands, but that's hard to understand unless you know what you're looking for.

You want to do a backtrace... to do so, you type:

bt

At the GDB prompt. However before that, it should show you the place where your program crashed. That's not always helpful though, so the backtrace is the way to go.

You can always navigate through the backtrace to see the actual lines of code. To do so, type "up" and "down".

That's a pretty quick'n'dirty introduction to GDB... I hope that helps you at least find the guilty line. :)
Australia #4
well i got real close to making it work via command line, i could load the core file just didnt know how to match that with the exe file, but thanks now i do.

Oh the codebase is smaugfuss1.4a, its probably important to know this.

Here is the backtrace information that the core file gave me, im trying to install a locker snippet that i got from http://www.shadow-lands.com/snippets.html, it makes the lockers ok opens ok but crashes on closing the locker.


#0  0x400c21c6 in mallopt () from /lib/i686/libc.so.6
(gdb) bt
#0  0x400c21c6 in mallopt () from /lib/i686/libc.so.6
#1  0x400c0e6f in free () from /lib/i686/libc.so.6
#2  0x080595dc in clear_vrooms () at act_move.c:355
#3  0x080c4295 in delete_locker (ch=0x8514118) at locker.c:381
#4  0x080c4023 in do_locker (ch=0x8514118, argument=0xbffff207 "close")
    at locker.c:298
#5  0x080c2dbf in interpret (ch=0x8514118, argument=0xbffff207 "close")
    at interp.c:547
#6  0x0809861d in game_loop () at comm.c:638
#7  0x08097ef1 in main (argc=2, argv=0xbffff714) at comm.c:289
#8  0x40064c57 in __libc_start_main () from /lib/i686/libc.so.6

Here is the the section of code from locker.c that the dump points to. the while is line 381

void delete_locker( CHAR_DATA *ch )
{
    /* Clean-up the locker room -- Remove the loaded objects */
    while ( ch->pcdata->locker_room->first_content )
    {
        extract_obj( ch->pcdata->locker_room->first_content );
    }
    
    /* Kill the locker object */
    DISPOSE( ch->pcdata->locker );
    ch->pcdata->locker      = NULL;

    ch->pcdata->locker_vnum = 0;
    ch->pcdata->locker_room = NULL;

    /* Need to delete the virtual room */
    clear_vrooms();
}

The 298 is the sprintf exeeded weight limit, tho in another dump it has refered to the line for saving the locker.

else if( ! str_cmp( arg, "close" ) ) 
    {
        if( ! ch->pcdata->locker )
        {
            send_to_char( "You are not currently in the locker room.\r\n", ch );
            return;
        }
        
    	locker = ch->pcdata->locker;

        /* Total the weight of the contents */
        locker->holding = 0;
        
        for( obj = ch->in_room->first_content; obj; obj = obj->next_content )
        {
            locker->holding = locker->holding + ( obj->weight * obj->count );

            if( obj->item_type == ITEM_CONTAINER )
            {
                send_to_char( "You may not leave containers in the locker room.\r\n", ch );
                return;
            } 
        }

        if( locker->holding > locker->capacity )
        {
            sprintf( buf, "The weight limit of your locker has beed exceeded.  "
                          "You must carry\r\nsome items out when you leave.\r\n" );
            send_to_char( buf, ch );
            return;
        } 
        
        /* Save the locker */
        fwrite_locker( ch );

        /* Return the player to the real world. */ 
        char_from_room( ch );
        char_to_room( ch, get_room_index( ch->pcdata->locker_vnum ) );

        delete_locker( ch );

        do_look( ch, "auto" );
        send_to_char( "Your locker has been closed and saved.\r\n", ch );
       }    
    else
    {
        send_to_char( "Syntax: locker <open | close>\r\n", ch );
    }
       
    return;    
}


The other bits of code that i thin are important would be the stuff i put into save.c

/*
     * Slick recursion to write lists backwards,
     *   so loading them will load in forwards order.
     */
>   if ( obj->prev_content && ( os_type != OS_CORPSE && os_type != OS_LOCKER ) )
	fwrite_obj( ch, obj->prev_content, fp, iNest, OS_CARRY );

and

	fprintf( fp, "ShortDescr   %s~\n",	obj->short_descr     );
    if ( QUICKMATCH( obj->description, obj->pIndexData->description ) == 0 )
	fprintf( fp, "Description  %s~\n",	obj->description     );
    if ( QUICKMATCH( obj->action_desc, obj->pIndexData->action_desc ) == 0 )
	fprintf( fp, "ActionDesc   %s~\n",	obj->action_desc     );
    fprintf( fp, "Vnum         %d\n",	obj->pIndexData->vnum	     );
>   if ( ( os_type == OS_CORPSE || os_type == OS_LOCKER ) && obj->in_room )
      fprintf( fp, "Room         %d\n",   obj->in_room->vnum         );
    if ( obj->extra_flags != obj->pIndexData->extra_flags )
	fprintf( fp, "ExtraFlags   %d\n",	obj->extra_flags     );
    if ( obj->wear_flags != obj->pIndexData->wear_flags )
	fprintf( fp, "WearFlags    %d\n",	obj->wear_flags	     );


I think im totaly lost hehe. IN the mean time i have found another locker snippet in lrdelders site i think i will try it while i wait for a responce on thin one.
Amended on Tue 13 Jan 2004 08:09 AM by Robert Powell
USA #5
There was a bug in that locker code somewhere. I forget where now, but I do believe it got fixed in Resortmud, so you may have some luck with plucking locker.c out of the most recent revision of RM4.

http://www.smaug.org/pub/mud/imc/linux-bases/mw-rm41r0.tar.gz

It uses the same locker snippet you got from Shadowlands.
Amended on Tue 20 Nov 2007 04:25 AM by Nick Gammon
Australia #6
Thanks for that tip i will give it a go and see what happens, im out of town for the next few days so i wont be able to try it till monday, but i will post a followup as to how i went.
Australia #7
Samson your the man, i did as you said and all is well and working correctly, no more crashing, i have another question.

Now i should look through the code befor i do ask this and try and work it out, but how do i make it so that when you OPEN LOCKER that all the objects in the locker dont jump in to your inventory but rather stays put in the room.
Canada #8
You probably need to change the call from obj_to_char(obj, ch); to obj_to_room(obj, ch->in_room)
Australia Forum Administrator #9
For some hints about using gdb, see Debugging with gdb.
Australia #10
Thanks nick for the definitive guide to debugging, for an absolute newb like my self it will be most helpfull.