C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 09-29-2008, 04:49 PM   #1
Registered User
 
Join Date: Sep 2008
Posts: 12
segmentation fault... first time with unix...

I have never programmed in C on UNIX earlier and the first time I did returned some surprising results. I first coded the programmed in Turbo C in Windows and it compiled and executed perfectly well. Then I compiled the program in GCC in UNIX and some surprise I got when I learned a new thing called "Segmentation Fault". The programmed compiled with just a warning against using "gets" function and produced an executable. Running it, I encounter "Segmentation Fault" and the program terminates whenever (as I discovered through running the program couple of times) either the character array is tokenized or the pointer token's string is copied into an empty character array: don't know exactly which one of them is causing the trouble! I have never used UNIX before and have absolutely no idea what to do! Here's my code and also the exact output:-

Code:
//declaring preprocessor directives
#include <stdio.h>
#include <string.h>

//method to validate user's input as  a legal Mynix command
int parseInput(char checkCommand[])
{
	int counter;
	char *inputToken, tempString[30];

	//loop to verify any character in the input is either a small alphabet or a hyphen or a space
	for (counter= 0; counter<strlen(checkCommand); counter++)
	{
		if (checkCommand[counter]<'a' || checkCommand[counter]>'z')
		{
			if (checkCommand[counter]!='-' && checkCommand[counter]!=' ')
			{
				printf("mynix> - No such thing!");
				return 0;
			}
		}
	}//character verification loop ends here

	//checking if input is an exit command
	if (strcmp(checkCommand, "exit")==0)
	{
		return 1;	//returning a non-zero value to exit the do-while loop in main
	}

	//checking for commands that can work without (or do not need) any switch or parameter like 'cd', 'ls', 'pwd' and 'cat'
	else if(strcmp(checkCommand, "cd")==0 || strcmp(checkCommand, "ls")==0 || 
	        strcmp(checkCommand, "pwd")==0 || strcmp(checkCommand, "cat")==0)
	{
		printf("mynix> - Done!");
		return 0;
	}

	//checking for commands that can have (or need) switches or parameters like 'cd', 'ls', 'cat', 'man', 'mkdir', 'whereis'
	else
	{
		inputToken= strtok(checkCommand, " ");	//tokenizing by space for first part
		
		//checking first token for a valid command
		if (strcmp(inputToken, "man")==0 || strcmp(inputToken, "ls")==0 || 
		    strcmp(inputToken, "cd")==0 || strcmp(inputToken, "mkdir")==0 || 
		    strcmp(inputToken, "cat")==0 || strcmp(inputToken, "whereis")==0)
		{
			inputToken= strtok(NULL, " ");	//tokenizing by space for second part
			strcpy(tempString, inputToken);	//storing token's value in a string

			//checking that second part does not start with a hyphen and that its a valid parameter
			if (tempString[0]!='-' && strlen(tempString)>0)
			{

				inputToken= strtok(NULL, " ");	//tokenizing by space for third part
				strcpy(tempString, inputToken); //storing token's value in a string

				//checking that there is no third part after a parameter
				if (strcmp(tempString, NULL)==0)
				{
					printf("mynix> - Done!");
					return 0;
				}

				else
				{
					printf("mynix> - No such thing!");
					return 0;
				}
			}//third part verification ends here

			//checking validity if second part starts with a hyphen
			else
			{
				//checking that there is only one character after a hyphen in the second part
				if (strlen(tempString)==2)
				{
					inputToken= strtok(NULL, " ");	//tokenizing by space for third part
					strcpy(tempString, inputToken);	//storing token's value in a string

					//checking that after a valid switch the third part does not start with a hyphen
					if (tempString[0]!='-' && strcmp(tempString, NULL)!=0)
					{
						inputToken= strtok(NULL, " ");	//tokenizing by space for fourth part
						strcpy(tempString, inputToken);	//storing token's value in a string

						//checking that there is no fourth part
						if (strcmp(tempString, NULL)==0)
						{
							printf("mynix> - Done!");
							return 0;
						}

						//if more than three parts are there in the command
						else
						{
							printf("mynix> - No such thing!");
							return 0;
						}
					}
					
					//if parameter is incorrectly declared
					else
					{
						printf("mynix> - No such thing!");
						return 0;
					}
				}
				
				//if switch is incorrectly delcared
				else
				{
					printf("mynix> - No such thing!");
					return 0;
				}
			}//second part verification if-else ladder ends here
		}
		
		//if first part not valid then
		else
		{
			printf("mynix> - No such thing!");
			return 0;
		}//first part verification if-else ladder ends here
	}//total command verification if-else ladder ends here
}//method parseInput ends here

//main method begins here
int main()
{
	char userInput[30];
	int exitVariable= 0;

	//do-while loop to prompt user for next command till exit command is executed
	do
	{
		printf("\nmynix> ");

		gets(userInput);

		exitVariable= parseInput(userInput);
	}
	while(exitVariable==0);
	//do-while loop ends here
	
	return 0;	//no value required to be returned by main method
}//main method ends here
//program ends here
The output is:-

Code:
mynix> hey
mynix> - No such thing!
mynix> ls
mynix> - Done!
mynix> ls -a
Segmentation fault
Please help! Thanks a lot for taking out some time!

Last edited by Salem; 09-30-2008 at 11:39 AM. Reason: Fold long lines for readability
theMethod is offline   Reply With Quote
Old 09-29-2008, 05:02 PM   #2
Banned
 
master5001's Avatar
 
Join Date: Aug 2001
Location: Visalia, CA, USA
Posts: 3,699
Well I see a lot of little issues with your code. Why not just use strtok()? It would not lead to the buffer overlflow issues you could have with your whole tempString mumbo-jumbo.
master5001 is offline   Reply With Quote
Old 09-29-2008, 05:10 PM   #3
The superheterodyne.
 
twomers's Avatar
 
Join Date: Dec 2005
Location: Ireland
Posts: 2,215
>> gets(userInput);
Not really smiled upon. See here why.
__________________
I blag!
twomers is offline   Reply With Quote
Old 09-29-2008, 05:15 PM   #4
Registered User
 
Join Date: Sep 2008
Posts: 12
master5001 thanks for taking out so much time! Could you please have a chat with me? I'll be really grateful! If you don't mind then please add user "matereality" on gtalk; I am online right now.

Anyway if you are not comfortable with it then no problem. But could you please ellaborate a bit what exactly I need to do? As you can see I have used strtok() couple of times. Please guide a little further and kindly explain what exactly could the issues be with tempString?
Thankyou very much!
theMethod is offline   Reply With Quote
Old 09-29-2008, 05:21 PM   #5
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
You probably should be more careful with the result of strtok() - it can be NULL...
Code:
						inputToken= strtok(NULL, " ");	//tokenizing by space for fourth part
						strcpy(tempString, inputToken);	//storing token's value in a string
--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 09-29-2008, 05:30 PM   #6
Registered User
 
Join Date: Sep 2008
Posts: 12
matsp I tried running the program after removing that part entirely. The string only gets tokenized twice now; and even after inputs with exactly three parts separated by space segmentation fault still shows up!
Here's the output:-

Code:
mynix> cd
mynix> - Done!
mynix> cd -i sdf
Segmentation fault
theMethod is offline   Reply With Quote
Old 09-29-2008, 05:32 PM   #7
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Code:
strcmp(tempString, NULL)
Whilst looking over the code again, this stands out like an "instant" crash line - passing NULL to strcmp will deifnitely not work.

But this should really be a learning experience in debugging. It's not a hard problem to solve, you just need to track down where you are using an invalid pointer - a few minutes with a few added printf shoudl do it.

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 09-29-2008, 10:06 PM   #8
Registered User
 
Join Date: Sep 2008
Posts: 12
Well this is for everyone reading this post... firstly I am seriously grateful for taking some time out to read it!
Now what I wish to do with this program is to develop a kind of Unix shell simulator. Simple enough. This works flawlessly in Turbo C in Windows. These segfaults are only occurring in GCC in Unix and since I have never programmed in Unix before I find these pretty HARD to understand and remove. Moreover, is there any other way to do this program the way I have done it without getting any segfaults? Obviously I am not going to get rid of all string functions and pointers and start making arrays after arrays to compare character by character.

Please help! I am not asking anyone to code the entire program correctly for me. I am just asking to please elaborate your suggestion or advice only after checking yourself that it works; because (please pardon me for saying this) none has worked yet!

Thanks a lot again!
theMethod is offline   Reply With Quote
Old 09-29-2008, 10:16 PM   #9
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,809
If strcmp(whatever, NULL) doesn't crash Turbo C, then Turbo C is more broken than I thought (and I thought it was pretty darn broken). If you want the line that matches the comment //checking that there is no fourth part, then you want strcmp(whatever, ""), not strcmp(whatever, NULL) -- or if whatever is a return from strtok, you can just compare whatever with NULL directly, not using strcmp.
tabstop is offline   Reply With Quote
Old 09-29-2008, 10:24 PM   #10
Registered User
 
Join Date: Sep 2008
Posts: 12
tabstop I replaced strcmp(whatever, NULL) statements with strcmp(whatever, ""). While running through there is no fault at strcmp anymore but the ones with strcpy still exist! Can you help some more please? Thank you!

Code:
mynix> man -s sdf

Program received signal SIGSEGV, Segmentation fault.
0x00c70b40 in strcpy () from /lib/libc.so.6
theMethod is offline   Reply With Quote
Old 09-29-2008, 10:43 PM   #11
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,809
Again, the thing that comes back from strtok could be NULL, so right after you do strtok, you should do something like
Code:
if (inputToken==NULL) {
    // print "Done!" since we've read all the tokens
    // continue; or something similar so that we don't keep trying to read tokens
}
This probably means you also don't have to do the strcmp's with "" either, since I'm guessing that's what that check was for.
tabstop is offline   Reply With Quote
Old 09-29-2008, 10:43 PM   #12
Registered User
 
Join Date: Sep 2008
Posts: 12
Ok here's an update: I replaced all "strcpy(tempString, inputToken);" statements with "strncpy(tempString, inputToken, strlen(inputToken));". Now the program doesn't recognize a string as legal that is supposed to be legal! Plus it pops out the fault here...


Code:
mynix> man -d df
mynix> - No such thing!
mynix> man

Program received signal SIGSEGV, Segmentation fault.
0x080487b6 in parseInput (checkCommand=0xbfc2f572 "man") at mynixTemp.c:54
54                              strncpy(tempString, inputToken, strlen(inputToken));    //storing token's value in a string
theMethod is offline   Reply With Quote
Old 09-29-2008, 10:57 PM   #13
Registered User
 
Join Date: Sep 2008
Posts: 12
tabstop thanks a lot indeed! That REALLY worked! There's just one small trouble left now... the program does not pass legal inputs as legal... here's the run... please check! THANKS A LOT!

Code:
mynix> man
mynix> - No such thing!
mynix> man -p sdf
mynix> - No such thing!
mynix> cd
mynix> - Done!
mynix> cd -d sd
mynix> - No such thing!
mynix> cd -d
mynix> - No such thing!
mynix> ls a
mynix> - No such thing!
mynix> exit

Program exited normally.
theMethod is offline   Reply With Quote
Old 09-29-2008, 11:10 PM   #14
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,809
It could be handy to make your error messages slightly different (at least temporarily) so that you can see how your program flow is going.
tabstop is offline   Reply With Quote
Old 09-29-2008, 11:12 PM   #15
Registered User
 
Join Date: Sep 2008
Posts: 12
I am really grateful to everyone to who has contributed their time to this post! Thank you very much everyone; especially you tabstop! There are NO segfaults now!

Well the only thing is that now the program is not accepting strings that it should! The sweetest part is that I can't figure out what to do!

The output is given in the previous post.

Thanks! It's almost done!
theMethod is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Why am I getting segmentation fault on this? arya6000 C++ Programming 6 10-12-2008 06:32 AM
Re: Segmentation fault turkish_van C Programming 8 01-20-2007 05:50 PM
Simple Structure yet Segmentation Fault! please help Fokus C Programming 7 12-10-2004 01:58 AM
Segmentation fault... alvifarooq C++ Programming 14 09-26-2004 12:53 PM
strcat segmentation fault captain-cat C Programming 3 07-20-2004 10:29 AM


All times are GMT -6. The time now is 11:58 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22