Hi,
Please find the below test code...
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
int x = 0;
typedef void (*sighandler_t)(int);
void fun()
{
printf("SIGNAL CAUGHT\n");
}
int main()
{
int pid;
signal(SIGINT, (sighandler_t)fun);
signal(SIGSEGV, (sighandler_t)fun);
pid = vfork();
if ( pid == 0 ) {
printf(" I am child - %d \n", pid);
x++;
raise(SIGINT);
printf("x = %d\n", x);
exit(0);
}
else {
printf(" I am parent - %d\n", pid);
raise(SIGSEGV);
printf("x = %d\n", x);
}
}
Why the parent process is not able to handle/respond the signals, when a child
once handles the signal, child is created using vfork().
In vfork() man page -
"Signals to the parent arrive after the child releases the parent's
memory."
How to make sure that child has released the parent memory..??
Thanks,
Halesh
Hi,
Check this test
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
int x = 0;
typedef void (*sighandler_t)(int);
void fun()
{
printf("SIGNAL CAUGHT\n");
}
int main()
{
int pid;
char *s = "HELLO";
signal(SIGINT, (sighandler_t)fun);
signal(SIGSEGV, (sighandler_t)fun);
pid = vfork();
if ( pid == 0 ) {
printf(" I am child - %d \n", getpid());
x++;
//kill(getpid(), SIGINT);
raise(SIGINT);
printf("x = %d\n", x);
exit(0);
}
else {
sleep(2);
printf(" I am parent - %d\n", getpid());
raise(SIGSEGV);
//kill(getpid(), SIGSEGV);
printf("x = %d\n", x);
}
}
Just little analysis
If I use kill() to send the signal,it works fine, but not with raise().
O/p with raise()
I am child - 15014
SIGNAL CAUGHT
x = 1
I am parent - 15014 (** Child pid o/p in parent getpid)
x = 1
O/p with kill()
I am child - 15016
SIGNAL CAUGHT
x = 1
I am parent - 15015
SIGNAL CAUGHT
x = 1
checked that getpid() function is not working fine when used after raise().
It is still getting its child's pid in parent.
Is it a expected behaviour...Please let me know.
Thanks,
Halesh
On Tue, Oct 28, 2008 at 1:43 AM, Halesh S <[email protected]> wrote:
> Hi,
>
> Please find the below test code...
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <signal.h>
> #include <unistd.h>
> int x = 0;
> typedef void (*sighandler_t)(int);
> void fun()
> {
> printf("SIGNAL CAUGHT\n");
> }
>
> int main()
> {
> int pid;
>
> signal(SIGINT, (sighandler_t)fun);
> signal(SIGSEGV, (sighandler_t)fun);
> pid = vfork();
>
> if ( pid == 0 ) {
> printf(" I am child - %d \n", pid);
> x++;
> raise(SIGINT);
> printf("x = %d\n", x);
> exit(0);
> }
> else {
> printf(" I am parent - %d\n", pid);
> raise(SIGSEGV);
> printf("x = %d\n", x);
> }
> }
>
> Why the parent process is not able to handle/respond the signals, when a child
> once handles the signal, child is created using vfork().
>
> In vfork() man page -
> "Signals to the parent arrive after the child releases the parent's
> memory."
>
> How to make sure that child has released the parent memory..??
That happens when the child does execve(2) or _exit(2). The man-page could be a little clearer on that point (it implies it, but not very clearly). For man-pages-3.12, I've made the change below.
Cheers,
Michael
diff --git a/man2/vfork.2 b/man2/vfork.2
index 55044ad..8a7ed50 100644
--- a/man2/vfork.2
+++ b/man2/vfork.2
@@ -94,7 +94,10 @@ but may call
.PP
Signal handlers are inherited, but not shared.
Signals to the parent
-arrive after the child releases the parent's memory.
+arrive after the child releases the parent's memory (i.e., after the child calls
+.BR _exit (2)
+or
+.BR execve (2)).
.SS "Historic Description"
Under Linux,
.BR fork (2)
--
Michael Kerrisk Linux man-pages maintainer;
http://www.kernel.org/doc/man-pages/ Found a documentation bug?
http://www.kernel.org/doc/man-pages/reporting_bugs.html
On Wed, 29 Oct 2008 08:17:36 CDT, Michael Kerrisk said:
> diff --git a/man2/vfork.2 b/man2/vfork.2
> index 55044ad..8a7ed50 100644
> --- a/man2/vfork.2
> +++ b/man2/vfork.2
> @@ -94,7 +94,10 @@ but may call
> .PP
> Signal handlers are inherited, but not shared.
> Signals to the parent
> -arrive after the child releases the parent's memory.
> +arrive after the child releases the parent's memory (i.e., after the child calls
> +.BR _exit (2)
> +or
> +.BR execve (2)).
OK, I'll bite - when is the parent's memory released if the child doesn't
depart by calling _exit() or execve(), but manages to get killed by an
unhandled signal or the OOM killer or similar?
(That's the generic problem with adding itemized lists to an explanation - it's
rarely clear if the list is an exhaustive list, or a non-complete list of
examples. Note how often we have flame wars regarding which EQUUX should be
returned in a corner case that hinge on whether Posix says "Only FOO, BAR,
and BAZ can be returned" or "FOO, BAR, BAZ are among the errors that can be
returned")
Hi Valdis,
On Thu, Oct 30, 2008 at 12:38 AM, <[email protected]> wrote:
> On Wed, 29 Oct 2008 08:17:36 CDT, Michael Kerrisk said:
>
>> diff --git a/man2/vfork.2 b/man2/vfork.2
>> index 55044ad..8a7ed50 100644
>> --- a/man2/vfork.2
>> +++ b/man2/vfork.2
>> @@ -94,7 +94,10 @@ but may call
>> .PP
>> Signal handlers are inherited, but not shared.
>> Signals to the parent
>> -arrive after the child releases the parent's memory.
>> +arrive after the child releases the parent's memory (i.e., after the child calls
>> +.BR _exit (2)
>> +or
>> +.BR execve (2)).
>
> OK, I'll bite - when is the parent's memory released if the child doesn't
> depart by calling _exit() or execve(), but manages to get killed by an
> unhandled signal or the OOM killer or similar?
Yes, thanks for catching that. The wording really should say, until
the child does execve(2) or it terminates.
> (That's the generic problem with adding itemized lists to an explanation - it's
> rarely clear if the list is an exhaustive list, or a non-complete list of
> examples. Note how often we have flame wars regarding which EQUUX should be
> returned in a corner case that hinge on whether Posix says "Only FOO, BAR,
> and BAZ can be returned" or "FOO, BAR, BAZ are among the errors that can be
> returned")
I agree that this is sometime true, but examples need to be looked at
on a case-by-case basis. Sometimes using deliberately vague language
is appropriate. But sometimes, the solution is just better, more
precise language, and I think that's the case here. For
man-pages-3.13, I applied the patch below.
Cheers,
Michael
Oops -- forgot the patch. Here it is:
--- a/man2/vfork.2
+++ b/man2/vfork.2
@@ -80,13 +80,15 @@ where a child will be created which then
immediately issues an
.BR vfork ()
differs from
.BR fork (2)
-in that the parent is suspended until the child makes a call to
-.BR execve (2)
-or
-.BR _exit (2).
-The child shares all memory with its parent, including the stack, until
-.BR execve (2)
-is issued by the child.
+in that the parent is suspended until the child terminates
+(either normally,
+by calling
+.BR exit (2),
+or abnormally, after delivery of a fatal signal),
+or it makes a call to
+.BR execve (2).
+Until that point, the child shares all memory with its parent,
+including the stack.
The child must not return from the current function or call
.BR exit (3),
but may call
@@ -95,9 +97,8 @@ but may call
Signal handlers are inherited, but not shared.
Signals to the parent
arrive after the child releases the parent's memory
-(i.e., after the child calls
-.BR _exit (2)
-or
+(i.e., after the child terminates
+or calls
.BR execve (2)).
.SS "Historic Description"
Under Linux,
@@ -135,11 +136,9 @@ The requirements put on
by the standards are weaker than those put on
.BR fork (2),
so an implementation where the two are synonymous is compliant.
-In particular, the programmer cannot
-rely on the parent remaining blocked until a call of
-.BR execve (2)
-or
-.BR _exit (2)
+In particular, the programmer cannot rely on the parent
+remaining blocked until the child either terminates or calls
+.BR execve (2),
and cannot rely on any specific behavior with respect to shared memory.
.\" In AIXv3.1 vfork is equivalent to fork.
.SH NOTES