Possible MXP crash?

Posted by Greven on Wed 10 Mar 2004 11:58 PM — 10 posts, 20,377 views.

Canada #0
I recently had a crash that I can't seem to recreate, but I'd like to prevent another from happening. The crashed happened here:
void set_pager_color( sh_int AType, CHAR_DATA *ch )
{
   if ( !ch || !ch->desc )
      return;
    
   write_to_pager( ch->desc, color_str( AType, ch ), 0 );
   ch->desc->pagecolor = ch->colors[AType];
}
Here is my gdb:
#5  0x081bfcce in set_char_color (AType=2088, ch=0x9) at color.c:985
985        ch->desc->pagecolor = ch->colors[AType];
(gdb) print ch
$9 = (CHAR_DATA *) 0x9
(gdb) print ch->desc
Cannot access memory at address 0x7d


I assume it got messed up in write_to_pager... Anyone had something with this? I'm using MXP, so I thought maybe someone might have some idea.
USA #1
Could you post a backtrace if this should happen again? Displaying frame 5 isn't enough information to go on.
Canada #2
This is the full back trace, since I use a crash system(via segvio, I know, I know, but it works), but incase, this is the whole back trace:
#0  0x42fafac1 in kill () from /lib/libc.so.6
#1  0x42faf6eb in raise () from /lib/libc.so.6
#2  0x42fb1127 in abort () from /lib/libc.so.6
#3  0x080c0a44 in SegVio (signum=0) at comm.c:429
#4  <signal handler called>
#5  0x081bfcce in set_char_color (AType=2088, ch=0x9) at color.c:985
#6  0x080636c2 in to_channel (argument=0x8282624 "ing link to Fei.", channel=9, verb=0x820f31a "Log", level=152) at act_comm.c:1039
#7  0x080d940a in log_string_plus (str=0x8282620 "Closing link to Fei.", log_type=0, level=152) at db.c:4186
#8  0x080f5722 in interpret (ch=0x8799d10, argument=0xbfedc206 "2010") at interp.c:261
#9  0x080884f3 in do_rat (ch=0x8799d10, argument=0xbfedc200 "close 2010") at act_wiz.c:1298
#10 0x080f5ba5 in interpret (ch=0x8799d10, argument=0xbfedc1f4 "2010 202015 close 2010") at interp.c:376
#11 0x080c1471 in game_loop () at comm.c:730
#12 0x080c0813 in main (argc=8, argv=0xbfedc684) at comm.c:335
#13 0x42f9bd06 in __libc_start_main () from /lib/libc.so.6
Australia Forum Administrator #3
There are some strange things in this backtrace. You typed:

rat 2010 202015 close 2010

- did you?

Seems strange to start with, but then in "interpret" it seems to think you are closing a link, not a door, otherwise why is it saying "Closing link to Fei"?

Then in log_string_plus I have this code:


    if ( strncmp( str, "Log ", 4 ) == 0 )
      offset = 4;
    else
      offset = 0;



That would chop off "Log " from the start of the message, but in your case it is chopping of "Clos" which seems to be working the other way around.

Then when it tries to send that message to channel 9 it ends up going to ch=9 (character 9). Very strange. Is this stock code or have you been changing things?
Canada #4
Ok, thanks for the reply. First:
Quote:
There are some strange things in this backtrace. You typed:

rat 2010 202015 close 2010

- did you?
Yes, the builder accidentally put the wrong number into rat, giving it a field of about 200000, which was far too much info, and he got a buffer overflow, so it disconnected him. The log message telling that he was being logged off was the problem. In set_char_color, it managed to get past the check verifying that it was ok, but later became corrupted, and the only place would seem to be in write_to_pager. As to that, I am using Samson's color code, as well as followed your instructions for putting mxp into our codebase. I've looked through the code, but cannot see anything that might cause a problem, but I can paste it here if it would be of help. Thanks for the replies again.
Australia Forum Administrator #5
Well, buffer overflows will tend to do virtually anything, so I wouldn't blame the MXP code too much. See where the overflow itself occurred, and stop that happening.
Canada #6
Errr, pardon the misuse of the term. The term I was refering to applies here:
        if (d->outsize > 32000)
	{
	    /* empty buffer */
	    d->outtop = 0;
	    bug("Buffer overflow. Closing (%s).", d->character ? d->character->name : "???" );
	    close_socket(d, TRUE);
	    return FALSE;
 	}
Where the descriptors output buffer was far to large. This was so large do to a 200000 room rat command. The "closing link to Fei" came from close_socket, which is wierd, because I would have expected close_socket somewhere in the stack...
Australia Forum Administrator #7
Yes, that is strange, however it seems to me there is a potential problem there. In SMAUG FUSS the test reads:


    while ( d->outtop + length >= d->outsize )


This means it is testing if the new length makes it too long.
Canada #8
Yes, I also have that while loop:
    /*
     * Expand the buffer as needed.
     */
    while ( d->outtop + length >= (int) d->outsize )
    {
        if (d->outsize > 32000)
	{
	    /* empty buffer */
	    d->outtop = 0;
	    bug("Buffer overflow. Closing (%s).", d->character ? d->character->name : "???" );
	    close_socket(d, TRUE);
	    return FALSE;
 	}
	d->outsize *= 2;
	RECREATE( d->outbuf, char, d->outsize );
    }

    /*
     * Copy.
     */
    convert_mxp_tags(d, d->outbuf + d->outtop, txt, origlength );
    d->outtop += length;
    d->outbuf[d->outtop] = '\0';
    return TRUE;
That the last bit of write_to_buffer. I compared the end of the smaugfuss and mine(SWR, btw), and they are virtually identical, except for the mxp stuff.
Australia Forum Administrator #9
Hard to say. Maybe put a breakpoint on the close_socket part and then re-do the "rat" command to make it happen again. Then carefully watch what it does.