Valnir wrote:

Program terminated with signal 11, Segmentation fault.
#0  0x080b373c in set_host (ch=0xb74f63bc, d=0xb74f5240) at comm.c:5793
5793                free_string(ch->usrdata->alt_hosts[h]);
(gdb) print ch->usrdata
$1 = (USER_DATA *) 0xb74f60b0
(gdb) print h
$2 = -1219534064
(gdb) print ch->usrdata->alt_hosts[h]
Cannot access memory at address 0x948ced3c
(gdb)

Well, we found your symptom, now what is the problem? You ask how can h become 
-1219534064 inside a for loop. I've seen it happen a couple of ways. First, the 
int gets incremented to the point it flips negative, or it gets assigned the 
value of a pointer, such as h = (int) ch;


#0  0x080b373c in set_host (ch=0xb74f63bc, d=0xb74f5240) at comm.c:5793
5793                free_string(ch->usrdata->alt_hosts[h]);
(gdb) print i
$1 = 6
(gdb)

merc.h:    char *               alt_hosts[MAX_HOSTS];   /* last X hosts */

/* the entire function */
void set_host ( CHAR_DATA *ch, DESCRIPTOR_DATA *d )
{
    char *hosts[MAX_HOSTS];
    int h, i = 0;

    if ( ch == NULL || d == NULL )
    {
        bug( "Set_host: ch or d is NULL!", 0 );
        return;
    }

    if ( IS_NPC(ch) )
    {
        send_to_char( "Mobs don't have descriptors or hosts.\n\r", ch );
        return;
    }

    free_string( ch->pcdata->host );
    ch->pcdata->host = str_dup( d->host );
    free_string( ch->usrdata->host );
    ch->usrdata->host = str_dup( d->host );

    /* is this host already our most recent? */
    if ( !str_cmp( ch->usrdata->alt_hosts[0], d->host ) )
        return;

    /* set array elements to '\0' */
    for ( h = 0; h < MAX_HOSTS; h++ )
        hosts[h] = &str_empty[0];

    hosts[i++] = str_dup(d->host);
First, as an FYI, this line is going to cause an off-by-one error.
    /* consolidate list and remove the current host from the list, if needed
*/
    for ( h = 0; h < MAX_HOSTS; h++ )
    {
        if ( !str_cmp( ch->usrdata->alt_hosts[h], d->host ) )
            continue;

        if ( !IS_NULLSTR(ch->usrdata->alt_hosts[h]) )
        {
            hosts[i++] = str_dup(ch->usrdata->alt_hosts[h]);
At the first run through, this statement will be something like hosts[1] = str_dump( alt_hosts[0] ), if there are alt_hosts. If you have a full list (MAX_HOSTS in side), hosts will have an overrun, since it will be trying to assign to hosts[MAX_HOSTS] which is invalid memory. (actually, if you look, the int h is created immediately after hosts[], so hosts[MAX_HOSTS], in ram, probably points to the same place &h would. Try it out in GDB. print &hosts[<value of MAX_HOSTS>] and print &h and copy the results in your reply. I haven't tried it myself, so I'm not 100% on the outcome either. :P)
            free_string(ch->usrdata->alt_hosts[h]);
            ch->usrdata->alt_hosts[h] = &str_empty[0];
        }
    }

    /* clear list and re-add entries */
    for ( h = 0, i = 0; h < MAX_HOSTS; h++ )
    {
        if ( !IS_NULLSTR(hosts[i]) )
            ch->usrdata->alt_hosts[h] = str_dup(hosts[i++]);
        else
            break;
    }

    save_account( ch->usrdata );
    return;
}

Let me know if this helps you understand my problem.

- Valnir




From: David Wilson [mailto:[EMAIL PROTECTED] Sent: Wednesday, March 28, 2007 9:01 PM
To: Nathan Kodak
Cc: [email protected]
Subject: Re: Crash after server move

On 3/28/07, Valnir <[EMAIL PROTECTED]> wrote:
Below is the output from the core and the info you requested. I'm curious
how "h" could be such an odd ball number while inside a defined for loop?

- Valnir

What's the value of i? It looks like you have an overflow somewhere. What's
the size of the alt_hosts array?
-David
Program terminated with signal 11, Segmentation fault.
#0 0x080b373c in set_host (ch=0xb74f63bc, d=0xb74f5240) at comm.c:5793
5793 free_string(ch->usrdata->alt_hosts[h]);
(gdb) print ch->usrdata
$1 = (USER_DATA *) 0xb74f60b0
(gdb) print h
$2 = -1219534064
(gdb) print ch->usrdata->alt_hosts[h]
Cannot access memory at address 0x948ced3c (gdb)


________________________________________
From: [EMAIL PROTECTED] on behalf of Ammaross Danan
Sent: Wed 3/28/2007 2:27 AM
To: [email protected]
Subject: Re: Crash after server move
Valnir wrote:
We're getting ready to port our mud to a new server and we're having a bit
of an issue. Everything compiles clean, but when we login we get past our account login and when we select what character to play the mud crashes.

Program terminated with signal 11, Segmentation fault.
#0 0x080b373c in set_host (ch=0xb74f63bc, d=0xb74f5240) at comm.c :5793
5793 free_string(ch->usrdata->alt_hosts[h]);

print ch->usrdata
print h
print ch->usrdata->alt_hosts[h]

These will give us the proper feedback on exactly what is causing the crash. I'm willing to bet ch->usrdata is 0x0, or is 0x3 or some such
invalid mem address (caused by an overrun of some sort). If it is, you
may want to insert an alloc_mem in the new_char_data() and the
corresponding free_mem() in the free_char_data().
(gdb) where
#0 0x080b373c in set_host (ch=0xb74f63bc, d=0xb74f5240) at comm.c:5793
#1 0x080a905c in nanny (d=0xb74f5240, argument=0xb74f5661 "Valnir") at comm.c:2560
#2 0x080a4a49 in game_loop_unix (control=4) at comm.c:885
#3 0x080a4424 in main (argc=2, argv=0xbf911974) at comm.c:490
(gdb)

It's crashing while trying to update the listing of hosts that a players
has
connected from.

/* consolidate list and remove the current host from the list, if
needed
*/

might want to put this block inside a if ( ch->usrdata != null ) check
for ( h = 0; h < MAX_HOSTS; h++ )
{
if ( !str_cmp( ch->usrdata->alt_hosts[h], d->host ) )
continue;

if ( !IS_NULLSTR(ch->usrdata->alt_hosts[h]) )
{
hosts[i++] = str_dup(ch->usrdata->alt_hosts[h]);
free_string(ch->usrdata->alt_hosts[h]);
ch->usrdata->alt_hosts[h] = &str_empty[0];
}
}
The new server is running GCC 4.1.1 and any help would be greatly
appreciated. Thanks!

- Valnir



Ammaross Danan
--
ROM mailing list
[email protected]
Unsubscribe here ->>> http://www.rom.org/cgi-bin/mailman/listinfo/rom

Reply via email to