Jump to content

Problem with fork and signal

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
12 replies to this topic

#1
eryn

eryn

    Newbie

  • Members
  • Pip
  • 6 posts
Hello all,

I am encountering with a problem here and any help would be very much appreciated.

I was trying to program using fork(). The objective of this code is to
1. I am activating a process A - SubSuctionMotors.
2. Process A is going to stop with either of this condition
a) Switch is activated - swret=1
b) Time allowed has expired
3. Stop the process A.

*Process A is running a motor.

Now, let's see the code.
void usrl_handler( int sig_num )

{

	printf( "Time out(%d), signal received to terminate motor\n", getpid() );

	SubSuctionMotors (0);


} 


int SubFrameVertical ()

{


	int 	swret;

	int 	rc=0;

	int 	timeOut=0;

	pid_t ret;

	int role=-1; 

	    			

	

	ret = fork();

			

	if (ret>0) { 	/*Parent Context*/


	printf( "Parent: This is the parent process (pid %d)\n", getpid() );

	SubSuctionMotors (1);      /*Motor is activated and running.*/

	signal ( SIGUSR1, usrl_handler );

			

	role = 0; 

	

	swret=CheckSwitch(0);      /*Command to check if switch is activated.*/

	while(swret==0)

	{

	    swret=CheckSwitch(0);    /*while loop to continuously check if switch is activated, loop will exit if switch is activated (swret=1).*/

	}

        SubSuctionMotors (0);     /*Stop motor running.*/


	}


	else if (ret == 0) { 	/*Child Context*/

			

	printf( "Child: This is the child process (pid %d)\n", getpid() );

			

	role = 1; 

			

	sleep ( 2 );       /*Start counting time when motor start running, after 2 second, motor should be stopped. This is an additional condition that we add in case the switch did not being activated to protect our application.*/


	printf( "Child: Time Out, Sending SIGUSR1 to pid%d\n", getppid() );

	kill( getppid(), SIGUSR1 );

	}


	SubSuctionMotors (0);


       

        return rc; 									


}

We tried to compile the code and run it.
Now, our problem is
1. We purposely force the switch to be inactive to test the child process (timer), whether after 2 seconds the motor stop. It turns out to be successful in first few attempts. After some while, the program hang, nothing is executed anymore and the program is not exit or terminated. What can cause the program to hang?

2. We tried to stop motor by switch activation (if the switch is to be successfully activated, the time it takes will always be shorter than the timer allowed time). However, the program did not seems like noticing the switch has been activated, and it just stop the motor according to timer. Why it behave this way?

Thank you very much for your help. :)

#2
Guest

Guest

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 3,414 posts
	swret=CheckSwitch(0);      /*Command to check if switch is activated.*/
	while(swret==0)
	{
	    swret=CheckSwitch(0);    /*while loop to continuously check if switch is activated, loop will exit if switch is activated (swret=1).*/
	}
Since this is the only loop in the code, I am pretty sure it hangs here. It could be, for some reason, the switch isn't detected and swret is always 0.
Also, you may want to check this:
	kill( getppid(), SIGUSR1 );
If the return value is -1, kill failed, meaning the program will hang.

One last thing: If possible, try running your code through a debugger to see where the the program hangs and why.
Root Beer == System Administrator's Beer
Download the new operating system programming kit! (some assembly required)

#3
joyo

joyo

    Newbie

  • Members
  • PipPip
  • 17 posts
I can't know the reason by the part of your code .
I suggest that you'd better not to use the kill, it will make your program more complex.

#4
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,717 posts

Quote

After some while, the program hang, nothing is executed anymore and the program is not exit or terminated. What can cause the program to hang?
You never check to see if fork() returns negative. Might want to check that.

Also, where is the switch set?
sudo rm -rf /

#5
eryn

eryn

    Newbie

  • Members
  • Pip
  • 6 posts

Guest said:

Since this is the only loop in the code, I am pretty sure it hangs here. It could be, for some reason, the switch isn't detected and swret is always 0.

But for the first few times of running, it didn't hang. (we have already program this code to automatically repeat for 100 times)
The code is executed around 4 to 5 times (i mean parent and child process is started and ended).

So, I was wondering why does the code act like what we desired to at first few times, but hang after that.

#6
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,717 posts
Did the program exit after each time?
sudo rm -rf /

#7
eryn

eryn

    Newbie

  • Members
  • Pip
  • 6 posts

dargueta said:

You never check to see if fork() returns negative. Might want to check that.

Yup. I think so. Got to check this.

Quote

Also, where is the switch set?

I don't really get the meaning here.

#8
eryn

eryn

    Newbie

  • Members
  • Pip
  • 6 posts

dargueta said:

Did the program exit after each time?

In our testing environment, we do not have any data shown whether the program exit or not.

#9
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,717 posts

Quote

In our testing environment, we do not have any data shown whether the program exit or not.
That's a huge problem. You're likely running out of memory; the system will only allow a certain number of subprocesses before it refuses to create any more. Kinda like how there's a limit on how many threads you can have per process. I would use perror after every fork to see the error message if any.

Quote

We purposely force the switch to be inactive to test the child process...
This is what I'm talking about.
sudo rm -rf /

#10
eryn

eryn

    Newbie

  • Members
  • Pip
  • 6 posts
I just found out the solution to exit the child process as well as the parent process. It is all to be coded in handler function.

This is my code. I hope my code is stable (not hiding any risk of crash or buffer overflow).

void usrl_handler( int sig_num )

{

	printf( "Time out(%d), signal received to terminate motor\n", getpid() );

	SubSuctionMotors (0);

	exit(0); 

}


int SubFrameVertical (int updown)

{


	int 	dir;

	int 	swret;

	pid_t ret;

	int role=-1; 

	    			

	ret = fork();

			

	if (ret>0) { 	/*Parent Context*/


	printf( "Parent: This is the parent process (pid %d)\n", getpid() );

	SubSuctionMotors (1);

		

	signal ( SIGUSR1, usrl_handler );

			

	role = 0; 

	if (returnresult >0) SendStatus();

        else printf("Connection Fail\n");


	swret=CheckSwitch(0);

	while(swret==0)

	{

	    swret=CheckSwitch(0);

	}

        SubSuctionMotors (0);

	

        }


	else if (ret == 0) { 	/*Child Context*/

			

	printf( "Child: This is the child process (pid %d)\n", getpid() );

			

	role = 1; 

			

	sleep ( 2 );


	printf( "Child: Time Out, Sending SIGUSR1 to pid%d\n", getppid() );

	kill( getppid(), SIGUSR1 );

	}


	SubSuctionMotors (0);

	

        if (returnresult >0) SendStatus();

        else printf("Connection Fail\n");


	return rc;										


}

I have add in "exit(0)" in the usrl_handler. This settled my problem and get my sequence right.

However, I think I still encountering with problem of running out of memory after executing this the child code for a few times (this means switch is never being activated and child process--time out take turn to stop motor). Someone suggested that I should just pause the program when time out happen and wait for instruction from user. I am currently studying this problem. Any help or idea will be very welcomed and appreciated. :)

#11
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,717 posts
Did you use perror() after fork() on a failure like I suggested? If so, what was the error message?
sudo rm -rf /

#12
eryn

eryn

    Newbie

  • Members
  • Pip
  • 6 posts
I "printf" the return value of "kill". It return 0 which means no error. however, the time the program hang, and no more status message is display (the program continuously display new status message around once every second), the return value of "kill" cannot be display. No message is seen that time.