Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ SMAUG ➜ SMAUG coding ➜ Segmentation Fault

Segmentation Fault

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Kronos   USA  (35 posts)  Bio
Date Sat 25 Dec 2004 06:50 AM (UTC)

Amended on Sat 25 Dec 2004 07:01 AM (UTC) by Kronos

Message
Hello again, I noticed that SWR doesn't have code in the do_refuel command, so I tried to make my own. It compiles fine, and I really don't see any problems, however it causes a segmentation fault when I execute the command. Can anybody see why it's doing this?

void do_refuel(CHAR_DATA *ch, char *argument )
{
SHIP_DATA *ship;
OBJ_INDEX_DATA *obj;
ROOM_INDEX_DATA *in_room;
bool station = FALSE;
int gascan;
int totalneed;
int totalfill;



if ( ship->energy == ship->maxenergy )
{
send_to_char("Your gas tank is already full!\n\r",ch);
return;
}

if ( !IS_SET( in_room->room_flags, ROOM_GAS_STATION ) && !obj )
{
send_to_char( "You're not in a gas station.\n\r", ch );
return;
}

if ( IS_SET( in_room->room_flags, ROOM_GAS_STATION ) )
station = TRUE;


if ( !station && !obj )
{
send_to_char("I do not see that here.\n\r",ch);
return;
}

if ( !station && obj->item_type != ITEM_FUEL )
{
send_to_char("That is not a can of gas.\n\r",ch);
return;
}

if ( !station && obj->item_type == ITEM_FUEL )
{
if ( obj->value[3] == 0 )
{
send_to_char("The can is empty.\n\r",ch);
return;
}

gascan = obj->value[3];
totalneed = ( ship->maxenergy - ship->energy );

if ( gascan <= totalneed )
{
totalfill = gascan;
send_to_char("You put gas in the tank, emptying the can.\n\r",ch);
}

if ( gascan > totalneed )
{
totalfill = ( gascan - ( gascan - totalneed ) );
send_to_char("You fill the tank, leaving some gas in the can.\n\r",ch);
}


obj->value[3] = ( obj->value[3] - totalfill );
ship->energy = ( ship->energy + totalfill );
}

if ( station && argument == '\0' )
{
send_to_char("A gas station employee approaches the vehicle and fills the tank.\n\r",ch);
ship->energy = ship->maxenergy;
}


}

Here's the info from the stack dump.. though I don't know what help it is:

Exception: STATUS_ACCESS_VIOLATION at eip=004F1DCF
eax=00000000 ebx=00000004 ecx=0022DFA0 edx=00000000 esi=610EF060 edi=61005A9C
ebp=0022DF58 esp=0022DF30 program=C:\cygwin\home\jim\pmud\src\swreality.exe, pid 1380, thread main
cs=001B ds=0023 es=0023 fs=0038 gs=0000 ss=0023
Stack trace:
Frame Function Args
0022DF58 004F1DCF (1008FF38, 0022EC26, 10089698, 0022E3C0)
0022EBC8 0047DF54 (1008FF38, 0022EC26, 0022EB44, 0022EB44)
0022F038 004544C8 (00566160, 00000000, 00000066, 6109106A)
0022F068 00453A29 (00000002, 617842C8, 100100A8, 0022F0C0)
0022F0A8 61005F34 (0022F0C0, 00000000, 00000000, 00000000)
0022FF88 6100614B (00000000, 00000000, 00000000, 00000000)
End of stack trace

I'm using SWRFUSS on Cygwin in case it matters. This was done at like 1am so I apologize if any of the code seems unecessary, but I'd like to know what's causing this crash.

Thanks,
Kronos
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #1 on Sat 25 Dec 2004 08:16 AM (UTC)
Message
 SHIP_DATA *ship;
/* ... more declarations ... */
if ( ship->energy == ship->maxenergy )
{
  send_to_char("Your gas tank is already full!\n\r",ch);
  return;
}
You declare ship but never set it to anything. Therefore accessing ship->anything will cause a crash.

You seem to do this with most of the variables you declared, so you'll have to give them all useful values before being able to use them.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Kronos   USA  (35 posts)  Bio
Date Reply #2 on Sat 25 Dec 2004 07:23 PM (UTC)
Message
Alright, the part where the player uses a gas can works like a charm, but when trying to just use the station it generates another segmentation fault, what could it be?

void do_refuel(CHAR_DATA *ch, char *argument )
{
SHIP_DATA *ship;
OBJ_DATA *obj;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
bool station = FALSE;
bool hascan = FALSE;
int gascan = 0;
int totalneed = 0;
int totalfill = 0;


argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );


ship = ship_in_room( ch->in_room , arg1 );




if ( arg1[0] == '\0' )
{
send_to_char("Usage: refuel <vehicle> <gas can>\n\r",ch);
send_to_char("If you are in a gas station, the gas can is optional.\n\r",ch);
return;
}

if ( !ship )
{
act( AT_PLAIN, "I see no $T here.", ch, NULL, arg1, TO_CHAR );
return;
}

if ( ship->energy == ship->maxenergy )
{
send_to_char("Your gas tank is already full!\n\r",ch);
return;
}

if ( !IS_SET( ch->in_room->room_flags, ROOM_GAS_STATION ) && !obj )
{
send_to_char( "You're not in a gas station.\n\r", ch );
return;
}

if ( IS_SET( ch->in_room->room_flags, ROOM_GAS_STATION ) )
station = TRUE;




if ( arg2[0] != '\0' )
{
if ( ms_find_obj(ch) )
return;

if ( ( obj = get_obj_carry( ch, arg2 ) ) == NULL )
{
send_to_char( "You do not have that item.\n\r", ch );
return;
}
}


if ( obj->item_type != ITEM_FUEL )
{
send_to_char("That is not a can of gas.\n\r",ch);
return;
}

if ( obj->item_type == ITEM_FUEL )
{
hascan = TRUE;

if ( obj->value[3] == 0 )
{
send_to_char("The can is empty.\n\r",ch);
return;
}

gascan = obj->value[3];
totalneed = ( ship->maxenergy - ship->energy );

if ( gascan <= totalneed )
{
totalfill = gascan;
send_to_char("You put gas in the tank, emptying the can.\n\r",ch);
}

if ( gascan > totalneed )
{
totalfill = ( gascan - ( gascan - totalneed ) );
send_to_char("You fill the tank, leaving some gas in the can.\n\r",ch);
}


obj->value[3] = ( obj->value[3] - totalfill );
ship->energy = ( ship->energy + totalfill );
return;
}

if ( station && !hascan )
{
send_to_char("You grab the hose and start filling your tank.\n\r",ch);
act( AT_PLAIN, "$n takes the hose and begins filling their tank.", ch, NULL, argument , TO_ROOM );
ship->energy = ship->maxenergy;
send_to_char("You finish filling the tank.\n\r",ch);
act( AT_PLAIN, "$n finishes filling their tank.", ch, NULL, argument , TO_ROOM );
return;
}
return;

}
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #3 on Sat 25 Dec 2004 08:38 PM (UTC)
Message
It would be useful to have a little more info than 'it crashes'. :-) Also, could you indent your code please? (you can use the forum [code] tag for that.)

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Kronos   USA  (35 posts)  Bio
Date Reply #4 on Sat 25 Dec 2004 09:04 PM (UTC)

Amended on Sat 25 Dec 2004 09:05 PM (UTC) by Kronos

Message
alrighty, here is the indented code:

void do_refuel(CHAR_DATA *ch, char *argument )
{
	SHIP_DATA *ship;
	OBJ_DATA *obj;
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
	bool station = FALSE;
	bool hascan = FALSE;
	int gascan = 0;
	int totalneed = 0;
	int totalfill = 0;

	
	argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );


	ship = ship_in_room( ch->in_room , arg1 );


	        if ( arg1[0] == '\0' )
			{
				send_to_char("Usage: refuel <vehicle> <gas can>\n\r",ch);
				send_to_char("If you are in a gas station, the gas can is optional.\n\r",ch);
				return;
			}

			if ( !ship )
			{
				act( AT_PLAIN, "I see no $T here.", ch, NULL, arg1, TO_CHAR );
				return;
			}

			if ( ship->energy == ship->maxenergy )
			{
				send_to_char("Your gas tank is already full!\n\r",ch);
				return;
			}

			if ( !IS_SET( ch->in_room->room_flags, ROOM_GAS_STATION ) && (  arg2[0] == '\0' ) ) 
			{
				send_to_char( "You're not in a gas station.\n\r", ch );
				return;
			}

			if ( IS_SET( ch->in_room->room_flags, ROOM_GAS_STATION ) )
				station = TRUE;

			if (  arg2[0] != '\0' )
			{
				if ( ms_find_obj(ch) )
				return;

				if ( ( obj = get_obj_carry( ch, arg2 ) ) == NULL )
				{
				send_to_char( "You do not have that item.\n\r", ch );
				return;
				}
			}

			if ( obj->item_type != ITEM_FUEL )
			{
				send_to_char("That is not a can of gas.\n\r",ch);
				return;
			}

			if ( obj->item_type == ITEM_FUEL )
			{
				hascan = TRUE;

				if ( obj->value[3] == 0 )
				{
					send_to_char("The can is empty.\n\r",ch);
					return;
				}

				gascan = obj->value[3];
				totalneed = ( ship->maxenergy - ship->energy );

				if ( gascan <= totalneed )
				{
					totalfill = gascan;
					send_to_char("You put gas in the tank, emptying the can.\n\r",ch);
				}

				if ( gascan > totalneed )
				{
					totalfill = ( gascan - ( gascan - totalneed ) );
					send_to_char("You fill the tank, leaving some gas in the can.\n\r",ch);
				}
					

				obj->value[3] = ( obj->value[3] - totalfill );
				ship->energy = ( ship->energy + totalfill );

			}

			if ( station && !hascan )
			{
				send_to_char("You grab the hose and start filling your tank.\n\r",ch);
				act( AT_PLAIN, "$n takes the hose and begins filling their tank.", ch, NULL, argument , TO_ROOM );
				ship->energy = ship->maxenergy;
				send_to_char("You finish filling the tank.\n\r",ch);
				act( AT_PLAIN, "$n finishes filling their tank.", ch, NULL, argument , TO_ROOM );
				return;
			}

return;

}


And here is the stackdump the segmentation fault produces in swreality.exe.stackdump:

Exception: STATUS_ACCESS_VIOLATION at eip=004F1FFD
eax=00000004 ebx=00000004 ecx=1008EB00 edx=1008EB00 esi=610EF060 edi=61005A9C
ebp=0022DF58 esp=0022D710 program=C:\cygwin\home\jim\pmud\src\swreality.exe, pid 1188, thread main
cs=001B ds=0023 es=0023 fs=0038 gs=0000 ss=0023
Stack trace:
Frame Function Args
0022DF58 004F1FFD (1008FF38, 0022EC2B, 10089698, 0022E3C0)
0022EBC8 0047DF54 (1008FF38, 0022EC27, 0022EB44, 0022EB44)
0022F038 004544C8 (00566160, 00000000, 00000066, 6109106A)
0022F068 00453A29 (00000002, 617842C8, 100100A8, 0022F0C0)
0022F0A8 61005F34 (0022F0C0, 00000000, 00000000, 00000000)
0022FF88 6100614B (00000000, 00000000, 00000000, 00000000)
End of stack trace

It generates this segment fault when you type refuel <vehicle> and you are in the gas station with the vehicle, otherwise the if statements catch and it sends the correct message.

I've managed to target one part of the code. It will successfully execute all the code except for this part:

			if ( station && !hascan )
			{
				send_to_char("You grab the hose and start filling your tank.\n\r",ch);
				act( AT_PLAIN, "$n takes the hose and begins filling their tank.", ch, NULL, argument , TO_ROOM );
				ship->energy = ship->maxenergy;
				send_to_char("You finish filling the tank.\n\r",ch);
				act( AT_PLAIN, "$n finishes filling their tank.", ch, NULL, argument , TO_ROOM );
				return;
			}


So it has to do with either the code itself or the if statement, because it's the only part that doesn't work. but I could be wrong, what do you think?

-Kronos
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #5 on Sat 25 Dec 2004 09:21 PM (UTC)
Message
You're on cygwin right? Do you know how to use gdb? Your problem is actually pretty simple, but it would do you good to use gdb and see for yourself exactly where it's dying.

See Nick's guide:
http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=3653

Look at it this way: if you intend to continue coding, you'll need to learn this one day or another. :) Might as well start on simple problems.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Kronos   USA  (35 posts)  Bio
Date Reply #6 on Sat 25 Dec 2004 09:53 PM (UTC)
Message
I followed the directions and it is not generating a core file, just swreality.exe.stackdump in the /area folder. I recall Nick had mentioned that you can't get core files with cygwin. I know the problem is simple, I just can't figure it out..

Thanks,
Kronos
Top

Posted by Kronos   USA  (35 posts)  Bio
Date Reply #7 on Sat 25 Dec 2004 10:04 PM (UTC)
Message
However while messing around in gdb i typed run 5555 and it ran the mud, so i went in and caused the error, and this is what it produced while I was in gdb:

Program received signal SIGSEGV, Segmentation fault.
0x004f1f66 in do_refuel (ch=0x10091368, argument=0x22ebfb "") at space.c:7522
---Type <return> to continue, or q <return> to quit---
7522 if ( obj->item_type != ITEM_FUEL )
(gdb)

all the sigsegv stuff was commented out in the code so i really don't understand why this happend, could you explain this?

Thank you,
Kronos
Top

Posted by Kronos   USA  (35 posts)  Bio
Date Reply #8 on Sat 25 Dec 2004 10:08 PM (UTC)
Message
Waaaiiit a second.. tell me if i am correct..

when I'm not specifying an object, and one is not meant to be specified, and it recieves that if statement, it generates a segment fault because it doesn't know what to do? so would I be right in saying that the solution would be to make sure the if statement is only considered if an object is specified?

-Kronos
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #9 on Sat 25 Dec 2004 10:25 PM (UTC)
Message
That's correct - you only want to access obj->whatever if obj actually points to something. So, you want to initialize obj to NULL at the beginning of the function, and then add into your if statement a check that makes sure obj is not null.

You have another problem like this in your ship-but-no-gascan handling code, I believe. The solution is quite similar.

And yeah, no core files with Cygwin. Kinda stinks - you have to do all debugging "live" by running it as you did.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Kronos   USA  (35 posts)  Bio
Date Reply #10 on Sat 25 Dec 2004 10:52 PM (UTC)
Message
Ah.. thank you for your help, it is greatly appreciated, I have it all in working order now. I'll use gdb more in the future when I have an issue.

Thanks!
Kronos
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


33,230 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.