30 Jan, 2013, arholly wrote in the 1st comment:
Votes: 0
Hi:
My rstat is crashing and I'm not sure I understand why. This is what I'm getting from the compiler.
Program received signal SIGSEGV, Segmentation fault.
0x0808aa50 in do_rstat (ch=0x8394a68, argument=0x83923d7 "7604") at act_wiz.c:972
972 send_to_char( Format("Door: %d. To: %d. Key: %d. Exit flags: %d.\n\rKeyword: '%s'. Description: %s",
(gdb) bt
#0 0x0808aa50 in do_rstat (ch=0x8394a68, argument=0x83923d7 "7604") at act_wiz.c:972
#1 0x080cd14a in interpret (ch=0x8394a68, argument=0x83923d7 "7604") at interp.c:974
#2 0x0809a788 in substitute_alias (d=0x8391fb8, argument=0x83923d1 "rstat 7604") at alias.c:64
#3 0x0809c1c9 in game_loop_unix (control=8) at comm.c:1036
#4 0x0809bb63 in main (argc=2, argv=0xbfffd824) at comm.c:655
(gdb) frame 0
#0 0x0808aa50 in do_rstat (ch=0x8394a68, argument=0x83923d7 "7604") at act_wiz.
972 send_to_char( Format("Door: %d. To: %d. Key: %
(gdb) list
967 {
968 EXIT_DATA *pexit;
969
970 if ( ( pexit = location->exit[door] ) != NULL )
971 {
972 send_to_char( Format("Door: %d. To: %d. Key: %
973 door, (pexit->u1.to_room == NULL
974 pexit->key, pexit->exit_info, pe
975 }
976 }
(gdb) info local
pexit = 0x82a6e30
buf = "rayal", '\000' <repeats 4090 times>
arg = "7604", '\000' <repeats 251 times>
location = 0x82a6c00
obj = 0x0
rch = 0x0
door = 0
__PRETTY_FUNCTION__ = "do_rstat"


void do_rstat( CHAR_DATA *ch, char *argument )
{
char buf[MSL]={'\0'};
char arg[MAX_INPUT_LENGTH]={'\0'};
ROOM_INDEX_DATA *location;
OBJ_DATA *obj;
CHAR_DATA *rch;
int door;

CheckCH(ch);

one_argument( argument, arg );
location = ( IS_NULLSTR(arg) ) ? ch->in_room : find_location( ch, arg );
if ( location == NULL )
{
send_to_char( "No such location.\n\r", ch );
return;
}

if (!is_room_owner(ch,location) && ch->in_room != location && room_is_private( location ) && !IS_TRUSTED(ch,MASTER))
{
send_to_char( "That room is private right now.\n\r", ch );
return;
}

send_to_char( Format("Name: '%s'\n\rArea: '%s'\n\r", location->name, location->area->name), ch );
send_to_char( Format("Vnum: %d Sector: %d Light: %d Healing: %d Mana: %d\n\r", location->vnum, location->sector_type, location->light, location->heal_rate, location->mana_rate), ch );
send_to_char( Format("Room flags: %d.\n\rDescription:\n\r%s", location->room_flags, location->description), ch );

if ( location->extra_descr != NULL )
{
EXTRA_DESCR_DATA *ed;

send_to_char( "Extra description keywords: '", ch );
for ( ed = location->extra_descr; ed; ed = ed->next )
{
send_to_char( ed->keyword, ch );
if ( ed->next != NULL )
send_to_char( " ", ch );
}
send_to_char( "'.\n\r", ch );
}

send_to_char( "Characters:", ch );
for ( rch = location->people; rch; rch = rch->next_in_room )
{
if (can_see(ch,rch))
{
send_to_char( " ", ch );
one_argument( rch->name, buf );
send_to_char( buf, ch );
}
}

send_to_char( ".\n\rObjects: ", ch );
for ( obj = location->contents; obj; obj = obj->next_content )
{
send_to_char( " ", ch );
one_argument( obj->name, buf );
send_to_char( buf, ch );
}
send_to_char( ".\n\r", ch );

for ( door = 0; door <= 5; door++ )
{
EXIT_DATA *pexit;

if ( ( pexit = location->exit[door] ) != NULL )
{
send_to_char( Format("Door: %d. To: %d. Key: %d. Exit flags: %d.\n\rKeyword: '%s'. Description: %s",
door, (pexit->u1.to_room == NULL ? -1 : pexit->u1.to_room->vnum),
pexit->key, pexit->exit_info, pexit->keyword, pexit->description[0] != '\0' ? pexit->description : "(none).\n\r"), ch );
}
}

return;
}
30 Jan, 2013, Rarva.Riendf wrote in the 2nd comment:
Votes: 0
pexit->description may be NULL instead of having an empty string.

(the pexit->keyword even is null should just insert random value in sprintf, so I doubt it is the culprit there)
31 Jan, 2013, Kaz wrote in the 3rd comment:
Votes: 0
I'm unfamiliar with the codebase, so I might be off tack here. Putting NULL into an sprintf is generally fine, and comes out as "(null)", at least in Debug mode – that might depend on implementation, so you might want to check that. Apart from this, I can see three possibilities:

* Format() is overflowing. Perhaps it has an internal buffer where the sprintf'd contents of the string (is pexit->description huge? Doubtful, but…) … then again, this would move the error to Format(), so I'm probably off (unless Format is a macro).

* pexit->u1 looks like the sort of name you'd give a union (if not, then rename it because it's a sucky name). If the union doesn't have the to_room member active, the pointer may be to something entirely different, and pexit->u1.to_room->vnum may be in the middle of nowhere.

* Something else ;)

What I'd do:

Take every statement out of the arguments to Format() and put them on their own line. Reproduce the bug down to the statement. Fix the statement and reassemble back into Format when you're done.

E.g.
if ( ( pexit = location->exit[door] ) != NULL )
{
ROOM_DATA* proom = pexit->u1.to_room;
int vnum = proom ? -1 : proom->vnum;
/* etc… */

send_to_char( Format("Door: %d. To: %d. Key: %d. Exit flags: %d.\n\rKeyword: '%s'. Description: %s",
door, vnum, pkey, pexit_info, pkeyword, pdesc, /* and so on … */) );
}
01 Feb, 2013, arholly wrote in the 4th comment:
Votes: 0
OK Kaz, I took your suggestions. I changed my code to:
for ( door = 0; door <= 5; door++ )
{
EXIT_DATA *pexit;

if ( ( pexit = location->exit[door] ) != NULL )
{
send_to_char( Format("Door: %d. ", door), ch );
send_to_char( Format("To: %d. ", (pexit->u1.to_room == NULL ? -1 : pexit->u1.to_room->vnum)), ch );
send_to_char( Format("Key: %d. ", pexit->key), ch );
send_to_char( Format("Exit flags: %d.\n\r", pexit->exit_info), ch );
send_to_char( Format("Keywords: %s. ", pexit->keyword), ch );
send_to_char( Format("Description: %s.\n\r", pexit->description[0] != '\0' ? pexit->description : "(none).\n\r"), ch );
}
}

And it crashes in the Description line. However, I am not sure what it means.
Quote
Program received signal SIGSEGV, Segmentation fault.
0x0808c59a in do_rstat (ch=0x8396ae0, argument=0x839441f "10000") at act_wiz.c:977
977 send_to_char( Format("Description: %s.\n\r",pexit->description[0] != '\0' ? pexit->description : "(none).\n\r"), ch );
(gdb) list
972 send_to_char( Format("Door: %d. ", door), ch );
973 send_to_char( Format("To: %d. ", (pexit->u1.to_room == NULL ? -1 : pexit->u1.to_room->vnum)), ch );
974 send_to_char( Format("Key: %d. ", pexit->key), ch );
975 send_to_char( Format("Exit flags: %d.\n\r", pexit->exit_info), ch );
976 send_to_char( Format("Keywords: %s. ", pexit->keyword), ch );
977 send_to_char( Format("Description: %s.\n\r",pexit->description[0] != '\0' ? pexit->description : "(none).\n\r"), ch );
978 }
979 }
980
981 return;
(gdb) info locals
pexit = 0x8345ed8
buf = '\000' <repeats 4095 times>
arg = "10000", '\000' <repeats 250 times>
location = 0x8346388
obj = 0x0
rch = 0x0
door = 0
__PRETTY_FUNCTION__ = "do_rstat"
01 Feb, 2013, Rarva.Riendf wrote in the 5th comment:
Votes: 0
My answer was too short to be taken seriously ? pexit->description is NULL so it crashes…because of pexit->description[0]….
You could just 'print pexit->description' under gdb to check it….
04 Feb, 2013, arholly wrote in the 6th comment:
Votes: 0
Alright, is this an OK way to solve the problem for all the pexit->descriptions which are null? In save_room, I changed the way it saves room exit descriptions to this:
if (!IS_NULLSTR(pExit->description))
{
fprintf( fp, "%s~\n", fix_string( pExit->description ) );
}
else
{
fprintf(fp, "%s~\n", fix_string (pExit->description ="(none)") );
}
04 Feb, 2013, arholly wrote in the 7th comment:
Votes: 0
Ok, realized I needed to change this
fix_string (pExit->description ="(none)")

to in order to put the carriage return in there.
str_dup("None")
04 Feb, 2013, Rarva.Riendf wrote in the 8th comment:
Votes: 0
Why so complicated ?

fprintf( fp, "%s~\n",      fix_string(pExit->description ? pExit->description : "none" ) );


if you strdup your string, you will have to free it as well….
and it is usually not a good idea to set a string with = unless it is a constant.
04 Feb, 2013, arholly wrote in the 9th comment:
Votes: 0
Well that is definitely less complicated.
0.0/9