{"id":2979,"date":"2013-05-27T17:15:13","date_gmt":"2013-05-27T15:15:13","guid":{"rendered":"http:\/\/glandium.org\/blog\/?p=2979"},"modified":"2019-09-03T15:26:19","modified_gmt":"2019-09-03T06:26:19","slug":"signal-doubly-considered-harmful","status":"publish","type":"post","link":"https:\/\/glandium.org\/blog\/?p=2979","title":{"rendered":"signal() doubly considered harmful"},"content":{"rendered":"<p>When you want to set signal handlers on UNIX systems, the typical choice is to use <code>signal<\/code> (specified in C89, C99 and POSIX.1-2001) or <code>sigaction<\/code> (specified in POSIX.1-2001 and System V r4).<\/p>\n<p>Quoting the <code>signal<\/code> manual page:<\/p>\n<blockquote><p>The only portable use of <code>signal()<\/code> is to set a signal's disposition to <code>SIG_DFL or SIG_IGN<\/code>. The semantics when using <code>signal()<\/code> to establish a signal handler vary across systems (and POSIX.1 explicitly permits this variation); <strong>do not use it for this purpose<\/strong>.<\/p>\n<p>POSIX.1 solved the portability mess by specifying <code>sigaction(2)<\/code>, which provides explicit control of the semantics when a signal handler is invoked; use that interface instead of <code>signal()<\/code>.<\/p><\/blockquote>\n<p>Then it goes on about the UNIX vs BSD semantics, and how they affect signal delivery, which essentially is the main reason why one would want to stop using <code>signal<\/code> and use <code>sigaction<\/code> instead, with specifically chosen flags.<\/p>\n<p>But this is not really what I wanted to talk about here.<\/p>\n<p>One of the uses of <code>signal<\/code> or <code>sigaction<\/code> is to temporarily set a signal handler and restore the old signal handler once the job is done. Notwithstanding the fact that it's a pretty horrible thing to do in a multi-threaded program, it's also a horrible thing to do at all with <code>signal<\/code> if <code>sigaction<\/code> is used.<\/p>\n<p>The core of the problem is the following: the information you get from <code>signal()<\/code> about the old signal handler is missing all the important pieces about it if it was originally set with <code>sigaction()<\/code>, namely, flags, masks and restorer.<\/p>\n<p>So if you do use <code>signal()<\/code> to temporarily set a signal handler and then restore the previous signal handler, you risk resetting flags, masks and restorer. The first awful thing this means is the previous signal handler might be expecting three arguments, only one of which will be valid when it's invoked. Unexpected things can also happen with the lack of expected flags or masks. This is why you'll see horrible workarounds like <a href=\"https:\/\/breakpad.appspot.com\/download\/issue481002_1003.diff\">this<\/a> or <a href=\"https:\/\/github.com\/android\/platform_bionic\/commit\/f84bc8d6f6368f1c846124a8168761ee8cc589c0\">that<\/a>.<\/p>\n<p>In short, if you do use <code>signal()<\/code> to temporarily set a signal handler and then restore the previous signal handler, you're doing it wrong. And if you do that in a system library or driver, thank you for screwing things up. I'm looking at you <code>libsc-a3xx.so<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you want to set signal handlers on UNIX systems, the typical choice is to use signal (specified in C89, C99 and POSIX.1-2001) or sigaction (specified in POSIX.1-2001 and System V r4). Quoting the signal manual page: The only portable use of signal() is to set a signal&#8217;s disposition to SIG_DFL or SIG_IGN. The semantics [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,25],"tags":[23],"class_list":["post-2979","post","type-post","status-publish","format-standard","hentry","category-pdo","category-planet-mozilla","tag-en"],"_links":{"self":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2979","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2979"}],"version-history":[{"count":10,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2979\/revisions"}],"predecessor-version":[{"id":2989,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2979\/revisions\/2989"}],"wp:attachment":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2979"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2979"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2979"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}