Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > ruby bug with fork and signals (SIGTERM)

Reply
Thread Tools

ruby bug with fork and signals (SIGTERM)

 
 
Andreas Otto
Guest
Posts: n/a
 
      10-12-2010
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I writing a C-Extension for ruby using "rb_fork(0,0,0,Qnil)" to create a
new process.

Behaviour:

1) before fork a SIGTERM send to the parent terminate the parent
2) after fork a SIGTERM is ignored

Analyze:

SIGTERM is initialized in "Init_signal" using

#ifdef SIGTERM
install_sighandler(SIGTERM, sighandler);
#endif

but the fork code does in "rb_fork_err"

....
for (; before_fork(), (pid = fork()) < 0; prefork()) {
after_fork();
....
after_fork();
....

The problem is the "after_fork" is called for parent and child:

#define after_fork() (GET_THREAD()->thrown_errinfo = 0, after_exec())

#define after_exec() \
(rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(),
forked_child = 0, rb_disable_interrupt())

void
rb_disable_interrupt(void)
{
#if USE_TRAP_MASK
sigset_t mask;
sigfillset(&mask);
sigdelset(&mask, SIGVTALRM);
sigdelset(&mask, SIGSEGV);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
#endif
}

and all signals are blocked except SIGVTALRM and SIGSEGV

after adding

sigdelset(&mask, SIGTERM);

to rb_disable_interrupt the code is working but a real solution should
save the initial mask and later on enable the mask again ...



mfg

Andreas Otto

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.15 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJMtAi8AAoJEGTcPijNG3/A2s0H/iRGL+1iWvOyxS6fbuEBsWx5
1I0/4IwGVWy40HpwfS+gQ1vZiAK5y9M30FQQqrtiekD1G/12STT0FSuSKFgAE6Y6
KEyCS8SILpVDlAxdVQRlFEyO+BdVPRunJSfnDhyglyqRKmG5Qb THbDrsX0GtI+2c
Ilh8HlAV9MVRzfTUAsPl6s7kK5pvEC82cxl8suEkdpoL6huhXx nfwzdGDBHx8oKE
gEDWY1knMAxc5KrBY2XO4yKuImCivl8KgRz6knryaVNntrjuiI w2DtVXopRBuxFz
EL6ylWQXNJlxPHihkKAVdVzo67oON+olnK2spC8msfTAz4TNjQ pVapJasem8id4=
=YUmn
-----END PGP SIGNATURE-----
 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      10-12-2010
On Tue, Oct 12, 2010 at 9:10 AM, Andreas Otto
<(E-Mail Removed)> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hi,
>
> I writing a C-Extension for ruby using "rb_fork(0,0,0,Qnil)" to create a
> new process.
>
> Behaviour:
>
> 1) before fork a SIGTERM send to the parent terminate the parent
> 2) after fork a SIGTERM is ignored


Only in the parent?

> Analyze:
>
> SIGTERM is initialized in "Init_signal" using
>
> #ifdef SIGTERM
> =A0 =A0install_sighandler(SIGTERM, sighandler);
> #endif
>
> but the fork code does in "rb_fork_err"
>
> ...
> =A0 =A0for (; before_fork(), (pid =3D fork()) < 0; prefork()) {
> =A0 =A0 =A0 =A0after_fork();
> ...
> =A0 =A0after_fork();
> ...
>
> The problem is the "after_fork" is called for parent and child:
>
> #define after_fork() (GET_THREAD()->thrown_errinfo =3D 0, after_exec())
>
> #define after_exec() \
> =A0(rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(),
> forked_child =3D 0, rb_disable_interrupt())
>
> void
> rb_disable_interrupt(void)
> {
> #if USE_TRAP_MASK
> =A0 =A0sigset_t mask;
> =A0 =A0sigfillset(&mask);
> =A0 =A0sigdelset(&mask, SIGVTALRM);
> =A0 =A0sigdelset(&mask, SIGSEGV);
> =A0 =A0pthread_sigmask(SIG_SETMASK, &mask, NULL);
> #endif
> }
>
> and all signals are blocked except SIGVTALRM and SIGSEGV
>
> after adding
>
> sigdelset(&mask, SIGTERM);
>
> to rb_disable_interrupt the code is working but a real solution should
> save the initial mask and later on enable the mask again ...


I doubt it is a good idea to use regular signal handling code to do
this. If at all you should probably use Ruby's methods. Note that
you get the old signal handler back when trapping:

irb(main):010:0> Process.kill "INT", $$
=3D> 1
irb(main):011:0> Got signal 2

irb(main):012:0* Signal.trap("INT", &old)
=3D> #<Proc:0x1020e154@(irb):9>
irb(main):013:0> Process.kill "INT", $$
=3D> 1
irb(main):014:0> ^C
irb(main):014:0> Process.kill "INT", $$
=3D> 1
irb(main):015:0> ^C

I don't know your specific requirements but in Ruby you would probably do

fork do
# whatever client code
end

Signal.trap 'TERM' do
$stderr.puts "Ignoring SIGTERM"
end

Does that help?

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

 
Reply With Quote
 
 
 
 
Andreas Otto
Guest
Posts: n/a
 
      10-12-2010
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am 12.10.2010 09:32, schrieb Robert Klemme:
> On Tue, Oct 12, 2010 at 9:10 AM, Andreas Otto
> <(E-Mail Removed)> wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Hi,
>>
>> I writing a C-Extension for ruby using "rb_fork(0,0,0,Qnil)" to create a
>> new process.
>>
>> Behaviour:
>>
>> 1) before fork a SIGTERM send to the parent terminate the parent
>> 2) after fork a SIGTERM is ignored

>
> Only in the parent?


I just test the parent.

>
>> Analyze:
>>
>> SIGTERM is initialized in "Init_signal" using
>>
>> #ifdef SIGTERM
>> install_sighandler(SIGTERM, sighandler);
>> #endif
>>
>> but the fork code does in "rb_fork_err"
>>
>> ...
>> for (; before_fork(), (pid = fork()) < 0; prefork()) {
>> after_fork();
>> ...
>> after_fork();
>> ...
>>
>> The problem is the "after_fork" is called for parent and child:
>>
>> #define after_fork() (GET_THREAD()->thrown_errinfo = 0, after_exec())
>>
>> #define after_exec() \
>> (rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(),
>> forked_child = 0, rb_disable_interrupt())
>>
>> void
>> rb_disable_interrupt(void)
>> {
>> #if USE_TRAP_MASK
>> sigset_t mask;
>> sigfillset(&mask);
>> sigdelset(&mask, SIGVTALRM);
>> sigdelset(&mask, SIGSEGV);
>> pthread_sigmask(SIG_SETMASK, &mask, NULL);
>> #endif
>> }
>>
>> and all signals are blocked except SIGVTALRM and SIGSEGV
>>
>> after adding
>>
>> sigdelset(&mask, SIGTERM);
>>
>> to rb_disable_interrupt the code is working but a real solution should
>> save the initial mask and later on enable the mask again ...

>
> I doubt it is a good idea to use regular signal handling code to do
> this. If at all you should probably use Ruby's methods. Note that
> you get the old signal handler back when trapping:
>
> irb(main):010:0> Process.kill "INT", $$
> => 1
> irb(main):011:0> Got signal 2
>
> irb(main):012:0* Signal.trap("INT", &old)
> => #<Proc:0x1020e154@(irb):9>
> irb(main):013:0> Process.kill "INT", $$
> => 1
> irb(main):014:0> ^C
> irb(main):014:0> Process.kill "INT", $$
> => 1
> irb(main):015:0> ^C
>
> I don't know your specific requirements but in Ruby you would probably do
>
> fork do
> # whatever client code
> end
>
> Signal.trap 'TERM' do
> $stderr.puts "Ignoring SIGTERM"
> end
>
> Does that help?


My problem is just the opposite

I want that SIGTERM is *not* ignored ...
the original parent does end on SIGTERM
the parent *after* fork does not stop on SIGTERM


mfg, Andreas Otto
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.15 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJMtEKEAAoJEGTcPijNG3/AVBwH/108Gs9xoKoFg92lrIZ0sGQM
EicxDgJ5hzK5M5PAM+agsKaq7Yrq4F3YcbY9TawmoetfTJ8rhy yvBAqAiXXc/jjk
ngR3+Yym7KOSXTZBskGXzwk7eqg5uPM+iufGcv7qVoBT/OhtRIfylbD2M+AMkf5U
U2wO4ZwSwEiI5SxUTm/jffJ4VKkF4MCw6XoDdgImkUsvyZswXjUhqlZy8pyePAl/
BIutY2A0oTprAXEhM3W+JnWsRzaB8Y8cnJu7KTTHKhF0EDW/tdzGetNHa0K08XFV
e/ODkJOQ/id5hDlIuj0LgWkIWpuoKvCNSH3ZixjFweGcV62m2DdPgkTbY0f M22s=
=S+jo
-----END PGP SIGNATURE-----
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
os.fork and pty.fork Eric Snow Python 0 01-08-2009 06:32 AM
Segfaults, other signals, fork, etc. Elliott Hird Ruby 3 04-22-2007 12:05 AM
*bug* *bug* *bug* David Raleigh Arnold Firefox 12 04-02-2007 03:13 AM
Possible bug in 5.8.6: accept/fork/wait/exit ? James Marshall Perl Misc 2 06-06-2005 06:55 AM
Signals interrupt accept() - bug in perldoc perlipc? Peter Valdemar Morch Perl Misc 0 06-22-2004 10:00 AM



Advertisments