# Ruby bug with fork and signals (SIGTERM)

**URL:** <https://www.ruby-forum.com/t/ruby-bug-with-fork-and-signals-sigterm/196365>\
**Category:** Ruby\
**Created:** [October 12, 2010, 9:10am UTC](https://www.ruby-forum.com/t/ruby-bug-with-fork-and-signals-sigterm/196365 "2010-10-12T09:10:55Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![rantanplan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@rantanplan](https://www.ruby-forum.com/u/rantanplan)\
**Post date:** [October 12, 2010, 9:10am UTC](https://www.ruby-forum.com/t/ruby-bug-with-fork-and-signals-sigterm/196365/1 "2010-10-12T09:10:55Z")

</div>

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

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

iQEcBAEBAgAGBQJMtAi8AAoJEGTcPijNG3/A2s0H/iRGL+1iWvOyxS6fbuEBsWx5  
1I0/4IwGVWy40HpwfS+gQ1vZiAK5y9M30FQQqrtiekD1G/12STT0FSuSKFgAE6Y6  
KEyCS8SILpVDlAxdVQRlFEyO+BdVPRunJSfnDhyglyqRKmG5QbTHbDrsX0GtI+2c  
Ilh8HlAV9MVRzfTUAsPl6s7kK5pvEC82cxl8suEkdpoL6huhXxnfwzdGDBHx8oKE  
gEDWY1knMAxc5KrBY2XO4yKuImCivl8KgRz6knryaVNntrjuiIw2DtVXopRBuxFz  
EL6ylWQXNJlxPHihkKAVdVzo67oON+olnK2spC8msfTAz4TNjQpVapJasem8id4=  
=YUmn  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![rantanplan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@rantanplan](https://www.ruby-forum.com/u/rantanplan)\
**Post date:** [October 12, 2010, 9:32am UTC](https://www.ruby-forum.com/t/ruby-bug-with-fork-and-signals-sigterm/196365/2 "2010-10-12T09:32:47Z")

</div>

On Tue, Oct 12, 2010 at 9:10 AM, Andreas O.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

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

Only in the parent?

> …  
> #define after\_exec()   
> sigdelset(&mask, SIGSEGV);  
> 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@:9(irb)  
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?

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![rantanplan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@rantanplan](https://www.ruby-forum.com/u/rantanplan)\
**Post date:** [October 12, 2010, 1:20pm UTC](https://www.ruby-forum.com/t/ruby-bug-with-fork-and-signals-sigterm/196365/3 "2010-10-12T13:20:59Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Am 12.10.2010 09:32, schrieb Robert K.:

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

> > sigdelset(&mask, SIGVTALRM);
> 
> 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 O.  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v2.0.15 (GNU/Linux)  
Comment: Using GnuPG with SUSE - [http://enigmail.mozdev.org/](http://enigmail.mozdev.org/)

iQEcBAEBAgAGBQJMtEKEAAoJEGTcPijNG3/AVBwH/108Gs9xoKoFg92lrIZ0sGQM  
EicxDgJ5hzK5M5PAM+agsKaq7Yrq4F3YcbY9TawmoetfTJ8rhyyvBAqAiXXc/jjk  
ngR3+Yym7KOSXTZBskGXzwk7eqg5uPM+iufGcv7qVoBT/OhtRIfylbD2M+AMkf5U  
U2wO4ZwSwEiI5SxUTm/jffJ4VKkF4MCw6XoDdgImkUsvyZswXjUhqlZy8pyePAl/  
BIutY2A0oTprAXEhM3W+JnWsRzaB8Y8cnJu7KTTHKhF0EDW/tdzGetNHa0K08XFV  
e/ODkJOQ/id5hDlIuj0LgWkIWpuoKvCNSH3ZixjFweGcV62m2DdPgkTbY0fM22s=  
=S+jo  
-----END PGP SIGNATURE-----
