Bugs item #729695, was opened at 2003-04-29 12:30
Message generated for change (Comment added) made by sfllaw
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=506987&aid=729695&group_id=64301
Category: Output driver problems
>Group: Fixed in CVS for next release
Status: Open
Resolution: Fixed
Priority: 9
Submitted By: Billy Biggs (vektor)
Assigned to: Billy Biggs (vektor)
Summary: assert() causes tvtime to shut down in RH9 ?
Initial Comment:
I still don't entirely understand this, but if an
assert fails in a forked child process, the tvtime
process itself also dies in RH9. How can this be? Is
assert() harmful in this environment?
----------------------------------------------------------------------
>Comment By: Simon Law (sfllaw)
Date: 2003-04-30 12:08
Message:
Logged In: YES
user_id=196021
I am convinced that Scott's fix has fixed it.
----------------------------------------------------------------------
Comment By: Scott Van Wart (silvaran)
Date: 2003-04-29 15:53
Message:
Logged In: YES
user_id=679666
setpgid doesn't seem to have any effect on the signal
propagation...
#include <unistd.h>
#include <stdio.h>
int
main( int argc, char* argv[] ) {
printf( "%d\n", getpgid( 0 ) );
if ( fork() == 0 ) {
printf( "%d\n", getpgid( 0 ) );
setpgid( 0, 0 );
printf( "%d\n", getpgid( 0 ) );
abort(); /* still causes parent to abort */
} else {
sleep( 60 );
}
return 0;
}
Maybe sigaction() from the parent would be better?
----------------------------------------------------------------------
Comment By: Billy Biggs (vektor)
Date: 2003-04-29 15:24
Message:
Logged In: YES
user_id=153320
I think I mean something else, this was suggested to me by a
friend. See 'man setpgid'. It has something to do with how
signals are propagated.
----------------------------------------------------------------------
Comment By: Scott Van Wart (silvaran)
Date: 2003-04-29 15:19
Message:
Logged In: YES
user_id=679666
> Should we be setting the process group?
Do you mean the process group ID, or something else? I
think the group ID is irrelevant anyways, since it should be
suid root, not sgid root...?
----------------------------------------------------------------------
Comment By: Billy Biggs (vektor)
Date: 2003-04-29 15:08
Message:
Logged In: YES
user_id=153320
Should we be setting the process group?
I definitely think that we need to do something more here.
I'm moving this bug back to 'open in cvs tvtime'. I don't
want a SIGABRT sent to the child to kill tvtime.
----------------------------------------------------------------------
Comment By: Billy Biggs (vektor)
Date: 2003-04-29 14:55
Message:
Logged In: YES
user_id=153320
I don't think it's a bug. We link against pthread. fork
gets weird when you're a multithreaded app. I'm going
through libc docs now.
Thanks a ton for tracking this btw.
----------------------------------------------------------------------
Comment By: Scott Van Wart (silvaran)
Date: 2003-04-29 14:47
Message:
Logged In: YES
user_id=679666
Sorry, (dam moz), that last one should be:
# gcc forktest.c -o forktest -lpthread
# LD_ASSUME_KERNEL=2.4.18 ldd ./forktest|grep pthread
libpthread.so.0 => /lib/i686/libpthread.so.0
(0x40027000)
So the NPTL implementation (/lib/tls) of pthread in Red Hat
9.0 must have a bug that aborts parent process on a child
process call to abort().
----------------------------------------------------------------------
Comment By: Scott Van Wart (silvaran)
Date: 2003-04-29 14:44
Message:
Logged In: YES
user_id=679666
For $1 million, my final answer:
----------
#include <unistd.h>
#include <assert.h>
int
main( int argc, char* argv[] ) {
int status;
if ( fork() == 0 ) {
assert( 0 );
} else {
sleep( 60 );
}
return 0;
}
----------
On Red Hat 9:
# gcc forktest.c -o forktest
# ./forktest
forktest: forktest.c:8: main: Assertion `0' failed.
*** (works, and doesn't Abort the parent process)
# gcc forktest.c -o forktest -lpthread
# ldd ./forktest|grep pthread
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x40027000)
# ./forktestforktest: forktest.c:8: main: Assertion `0' failed.
Aborted
*** (fails, aborts the parent process)
# gcc forktest.c -o forktest -lpthread
# LD_ASSUME_KERNEL=2.4.18 ldd ./forktest|grep pthread
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x40027000)
----------------------------------------------------------------------
Comment By: Scott Van Wart (silvaran)
Date: 2003-04-29 14:35
Message:
Logged In: YES
user_id=679666
Yeah the patch does nothing... I got overzealous when I saw
all the negates of integer values... I usually explicitly
test for zero/nonzero status with 0 or != 0 as it makes more
logical sense... but that's all right... I'm still in the
dark in any case...
----------------------------------------------------------------------
Comment By: Billy Biggs (vektor)
Date: 2003-04-29 14:25
Message:
Logged In: YES
user_id=153320
Your patch below does nothing.
if !ping_screensaver_child
is the same as
if ping_screensaver_child == 0
Did you test this, or did you just want to flip the logic ?
----------------------------------------------------------------------
Comment By: Scott Van Wart (silvaran)
Date: 2003-04-29 14:22
Message:
Logged In: YES
user_id=679666
I should note that since assert() is called in the _parent_,
tvtime terminates, as it should logically. So you should
leave in the other asserts with the patch (I had to
copy/paste the patch as I'm not the submitter/assignee so I
can't attach... I think?)
----------------------------------------------------------------------
Comment By: Scott Van Wart (silvaran)
Date: 2003-04-29 14:20
Message:
Logged In: YES
user_id=679666
I got it... the problem is totally unrelated to assert(),
actually. When fork() is called, tvtime checks the return,
naturally. But the process that checks xscreensaver
continues to run as the PARENT, while the main tvtime runs
as the CHILD. I suspect it doesn't fail on other systems
because it's compiled with NDEBUG defined, which disables
the effect of assert.
Submitting a patch that inverts the logic on the fork()
return test:
--- tvtime-0.9.8/src/x11tools.c 2003-04-29
15:16:06.000000000 -0300
+++ tvtime-0.9.8.new/src/x11tools.c 2003-04-29
15:15:28.000000000 -0300
@@ -164,7 +164,8 @@
errno = 0;
printf( "Creating child...\n" );
ping_xscreensaver_child = fork();
- if( !ping_xscreensaver_child ) {
+ /* FIX: '0' indicates a child status */
+ if( ping_xscreensaver_child == 0 ) {
int result;
printf( "Child executing.\n" );
/* We are the child, and we will ping xscreensaver
every minute,
----------------------------------------------------------------------
Comment By: Scott Van Wart (silvaran)
Date: 2003-04-29 14:06
Message:
Logged In: YES
user_id=679666
I'm still going to look at it, because I can't reproduce it
with a skeleton app even with abort(). According to the
manpages, abort() causes a process to terminate, and return
error code 3 to the parent. But it doesn't say anything
about sending a signal or such to the parent process. So in
theory (and documentation), since the abort() (in assert())
occurs _after_ the fork() and _within_ the child process, it
shouldn't terminate tvtime. But it does, and it looks like
only on RH9 with normal linkage (ie: no
LD_ASSUME_KERNEL=2.4.18 or no force preload of the standard
libpthread libraries).
----------------------------------------------------------------------
Comment By: Billy Biggs (vektor)
Date: 2003-04-29 13:53
Message:
Logged In: YES
user_id=153320
I guess it's just that their implementation of assert sends
SIGABRT to the process group. Screw it, I've removed usage
of assert from tvtime.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=506987&aid=729695&group_id=64301
|