Thread: problem with.. i don't know what.. :)

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    100

    problem with.. i don't know what.. :)

    Hello there!
    I tried to make this exercise:
    Code:
    /*
    * The father process receives from the command line the name of a file and a (non empty) list of directories where 
    * it has to search the file.
    * It then creates a clone process for every directory whose task is to search (in the directory and all of its subdirectories) for files
    * whose name matches with the string received as a parameter.
    * All the filenames found are returned to the father (NULL is passed in the case no match occourred).
    * The father waits for all the processes to terminate and then displays the result of the search.
    * example of usage: program STRING /home/username
    * example of output: 	/home/username/aSTRINGx.htm 
    *			/home/username/foo/anotherSTRING.txt
    */
    and my program is pretty long.. Actually i'd like to focus your attention on just one aspect which (i cannot understand why) is wrong.
    I defined this struct:
    Code:
    struct arguments{
    
    	char directory[256];
    	char *key;
    	int numMatches;
    	char *matches[];
    };
    
    typedef struct arguments Arguments;
    so directory is an array of char instead of being a char *..
    in the main i take the name of the string to be found (key) and several directories (one or more) from the char *argv[].. the code looks like this (i omit some redundant code which consists mainly of controls):

    Code:
    int main (int argc,char *argv[])
    {
    ...
    	int nclones=argc-2;
    	char *key=argv[1];
    	int i;
    	Arguments *args;
    	args=(Arguments *) malloc (nclones*sizeof(Arguments) );
    ...
    	for (i=0;i<nclones;i++)
    	{	
    		strcpy(args[i].directory,argv[i+2]); //***************************************
    		args[i].key=key;
    		args[i].matches[0]=NULL;
    		args[i].numMatches=0;
    	}
    	pid_t *pid_clones;
    	pid_clones = (pid_t *) malloc (sizeof (pid_t)*nclones);
    ....
    	int *stacks;
    	stacks=(int *)malloc(1024*sizeof(int)*nclones);
    .....
    	//Now it's time to create the clones
    	for (i=0;i<nclones;i++)
    	{
    		pid_clones[i]=clone(search,&stacks[(i+1)*1024],CLONE_VM,&args[i]); //************
    ....
    	}
    now the problem is that in the second clone (in the case i want to search 2 directories) the struct's directory is corrupted.. the search function starts like this:

    Code:
    int search (void *args)
    {
    	Arguments *a = (Arguments *)args;
    	pid_t pid=getpid();
    	printf("I'm clone %d and have to search all the files whose name contains '%s' into the directory '%s'\n",(int)pid,
    	a->key,a->directory);
    ....
    and the beginning of the output, in the case of this command line:
    Code:
    programname time /usr/include/sys /usr/include/
    looks like this:

    Code:
    I'm clone 17093 and have to search all the files whose name contains 'time' into the directory '/usr/include/sys'
    I'm clone 17094 and have to search all the files whose name contains 'time' into the directory 'Xx���'
    what did i wrong?
    thanks x your help!

    PS: just in case, the whole program is this (i have still to solve the recursion on the subdirectories):

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <sched.h>
    #include <dirent.h>
    #include <sys/time.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <wait.h>
    
    struct arguments{
    
    	char directory[256];
    	char *key;
    	int numMatches;
    	char *matches[];
    };
    
    typedef struct arguments Arguments;
    
    int search (void *args)
    {
    	Arguments *a = (Arguments *)args;
    	pid_t pid=getpid();
    	printf("I'm clone %d and have to search all the files whose name contains '%s' into the directory '%s'\n",(int)pid,
    	a->key,a->directory);
    
    	struct stat statbuff;
    	struct dirent *entry;
    	DIR *dirPtr;
    
    	int countMatches=0;
    	size_t lenMatch;
    
    	dirPtr=opendir(a->directory);
    	chdir(a->directory);
    
    	if (dirPtr==NULL)
    	{
    		printf("Directory %s doesn't exist!\n",a->directory);
    		return 1;
    	}
    
    	while ((entry=readdir(dirPtr))!=NULL)
    	{
    		if (lstat(entry->d_name,&statbuff)==-1)
    		{
    			printf("BAD LSTAT\n");
    			return 0;
    		}
    
    		if ( S_ISDIR(statbuff.st_mode) &&	
    		   	(strcmp(entry->d_name,".")!=0 && strcmp(entry->d_name,"..")!=0)) 
    		{
    			//TODO Visit a subdirectory
    		}
    		else if (S_ISREG(statbuff.st_mode))
    		{
    			if (strstr(entry->d_name,a->key)!=NULL)
    			{
    				lenMatch=strlen(entry->d_name);
    				lenMatch+=strlen(a->directory);
    				lenMatch++;
    				a->matches[countMatches]=(char *)malloc(lenMatch*sizeof(char));
    				strcpy(a->matches[countMatches],a->directory);
    				strcat(a->matches[countMatches++],entry->d_name);
    			}
    		}
    	}
    	chdir("..");
    	closedir(dirPtr);
    	a->numMatches+=countMatches;
    	return 0;
    }
    
    int main (int argc,char *argv[])
    {
    	if (argc<3)
    	{
    		printf("Usage: searchClone filename directory1 directory2 ...\n");
    		return 1;
    	}
    	int nclones=argc-2;
    	char *key=argv[1];
    	int i;
    	Arguments *args;
    	args=(Arguments *) malloc (nclones*sizeof(Arguments) );
    	if (args==NULL)
    	{
    		printf ("out of memory\n");
    		return 1;
    	}
    	for (i=0;i<nclones;i++)
    	{	
    		strcpy(args[i].directory,argv[i+2]);
    		args[i].key=key;
    		args[i].matches[0]=NULL;
    		args[i].numMatches=0;
    	}
    	pid_t *pid_clones;
    	pid_clones = (pid_t *) malloc (sizeof (pid_t)*nclones);
    	if (pid_clones==NULL)
    	{
    		printf ("out of memory\n");
    		return 1;
    	}
    	int *stacks;
    	stacks=(int *)malloc(1024*sizeof(int)*nclones);
    	if (stacks==NULL)
    	{
    		printf ("out of memory\n");
    		return 1;
    	}
    	//Now it's time to create the clones
    	for (i=0;i<nclones;i++)
    	{
    		pid_clones[i]=clone(search,&stacks[(i+1)*1024],CLONE_VM,&args[i]);
    		if (pid_clones[i]==-1)
    		{
    			printf("BAD CLONE\n");
    			return 1;
    		}
    	}
    	
    	int clones_ended=0;
    	while (1)
    	{
    		waitpid(-1,NULL,__WCLONE);
    		clones_ended++;
    		if (clones_ended==nclones)
    			break;
    	}
    
    	int j;
    	for (i=0;i<nclones;i++)
    	{
    		printf("Clone %d found %d matches:\n",i+1,args[i].numMatches);
    		for (j=0;j<args[i].numMatches;j++)
    		{
    			printf("%s\n",args[i].matches[j]);
    		}
    		printf("\n");
    	}
    
    	return 0;
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I imagine memory is getting clobbered, but I don't see it. (Note: I have never used clone before, but should that second argument be a valid location (i.e. 1023, 2047, 3071, etc. instead of 1024, 2048, 3072, etc.)? I don't know.)

    Anyway, I would suggest printing out argv[3] at the top, and printing out args[1].directory in some places and see when/if it changes before clone is called.

  3. #3
    Registered User
    Join Date
    Oct 2007
    Posts
    100
    Quote Originally Posted by tabstop View Post
    I imagine memory is getting clobbered, but I don't see it. (Note: I have never used clone before, but should that second argument be a valid location (i.e. 1023, 2047, 3071, etc. instead of 1024, 2048, 3072, etc.)? I don't know.)

    Anyway, I would suggest printing out argv[3] at the top, and printing out args[1].directory in some places and see when/if it changes before clone is called.
    the problem was in the search function while dealing with the char **... I finally fixed it! thanks

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I would suggest that you give each clone a slightly bigger stack than 4KB. It is likely to cause problems sooner or later if your have that small a stack. I'd say a minimum would be about 16KB. Many modern applications use much more than that.

    And the way your stack is made, you won't necessarily get a crash immediately when the stack fails, but rather "undefined behviour" will ensue, and generally weird things will happen.

    --
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM