<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/60004>60004</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [tools][Unix] LLVM signal handler preventing process from crashing
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            platform:linux
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          jasilvanus
      </td>
    </tr>
</table>

<pre>
    # Summary
If an LLVM tool (e.g. `opt`) receives certain signals (e.g. `SIGTRAP`, `SIGABRT` or `SIGQUIT`), a stacktrace is printed, but then execution resumes instead of crashing.
 
If a signal is received again, the process crashes.

Without signal handlers, the process would directly crash upon the first signal.
This behavior seems both inconsistent (crashing on the second signal) and unexpected (not crashing on the first one).

# Details
The signal handlers seem to exist for things like stacktrace printing.
But why should signal handlers prevent the process from crashing after doing their work?

In `llvm/lib/Support/Unix/Signals.inc`, there are two types of signals defined, `IntSigs` and `KillSigs`:

```c++
 /// Signals that represent requested termination. There's no bug or failure, or
/// if there is, it's not our direct responsibility. For whatever reason, our
/// continued execution is no longer desirable.
static const int IntSigs[] = {SIGHUP, SIGINT, SIGTERM, SIGUSR2};

/// Signals that represent that we have a bug, and our prompt termination has
/// been ordered.
static const int KillSigs[] = {SIGILL,
                               SIGTRAP,
 SIGABRT,
                               SIGFPE,
 SIGBUS,
 SIGSEGV,
                               SIGQUIT
#ifdef SIGSYS
 ,
 SIGSYS
#endif
#ifdef SIGXCPU
                               ,
 SIGXCPU
#endif
#ifdef SIGXFSZ
 ,
 SIGXFSZ
#endif
#ifdef SIGEMT
                               ,
 SIGEMT
#endif
};
```

The observed behavior affects all signals in `KillSigs`. Looking at the implementation, this behavior is expected:  The LLVM signal handler first unregisters signal handlers (thus the behavior of crashing upon the second signal), and re-raises only certain signals to execute the default handler:

```
 bool IsIntSig = llvm::is_contained(IntSigs, Sig);
    [...]

 if (Sig == SIGPIPE || IsIntSig) {
      raise(Sig); // Execute the default handler.
      return;
```

As the above suggests this behavior is intentional,  I'm opening this issue to discuss instead of putting up a patch to change.

We noticed this because certain signals which were supposed to crash the process did not, and
subsequently we had false positive passing tests which were supposed to fail.

# Example
In `opt.cpp`, change the start of the `main` function to:

```c++
int main(int argc, char **argv) {
  InitLLVM X(argc, argv);

  int Sig = SIGABRT;
  printf("try1: raising signal %d\n", Sig);
 raise(Sig);
  printf("try1: executed past signal\n");

 printf("try2: raising signal %d\n", Sig);
  raise(Sig);
 printf("try2: executed past signal\n");
```

Note that `InitLLVM` must come first, because it registers LLVM's signal handlers.

cc @Flakebi @nhaehnle 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUV11z47oN_TX0C-Z6ZDr-yIMf7CROPc3eSdfJ7W1fOpQEWbyRSZUEneTfd0BRie0k290dz46kEIcAcXAAKu_1ziAuxGQlJtcDFai2bvGX8ro5KBP8ILfl60LIMWzDfq_cq8iuRbbcVKAM3N398Q3I2gaEnONwNwQxzWxLYpoJeQkOC9QH9FCgI6UN8F6q8cert5vbh-_L-2hxlT4sV98fxDQD69KHfzxuHjpMXqTAkyqeyKkCQXtonTaEJf8pDwRUowF8wSKQtgYc-rBHD9p4QlWCraBwytfa7IZdLPAeUvKQUZPzJaid0obBqUZonS3Q-w4CfULo_v-nptoG6jFqZcoGnT83fbahKaHUDgtqXjskCK01cVWlne8hEvpDrT3kWKuDtg484t5DbqkGbQprvPaEhvhM-7ggYXksrCkTGCdEmRKCwZcWC8KSTYwlODfrXLAGhbw8CZBZcI2kdON7z_A82ugfkAV80Z6gsg6IwT00-gmPMxfT9p6FVSB4rl_B1_F8zmFbhwcO8_gkK2f3796ritBBafmZatQOnq17EuP1cQgbw5RqmsNeyHWjcyHX29C21pGQ60ejX_hDx9KhNkWiJdXoEJRDoGcL9NqiZx71dC6x0qYjoJhmG0NbvfNMYD5vMc3-rpsmfRLj5cmJTrPuVwi54l8ipFx3P0i-ANWKwGHr0PMpOPxvQM85JHR7bRRTfQgP7KeQMw_GQh52XEGV0k3gr1dgXZ_HHl5XKTYdaaopGRPY4BJHuYJa5lmuG02vQ1hbB8-1IjygA4fK21geNnyALyxnOGB5VI86OtdYs-NsoddO5Q0mEnhSpAu28wTaEPSHGdUJxPgaxGy13dz-7fGe99xubje_P6Snh5vv39Lj4_a7FLNrMV6d8vf_HGt8fUao1QFB8QlGvTFlPI7W2X1LxycOtfLn0DmiAetKdFh-FdUbIc7D2tzdCXmVWPDjf71wvi3vhfPn7df3Nyfmq8ftyfv25vaPX4CLKt0Lha5KrCLIv7ZvrD7G7j8LOUZT6uqj5Z9X948_tfcJ8LvVD5DX239_5tT7969tb749_LpTb0ZnuMcU7aXgmLEssDb36LgRvbUAVVVYkAfVNG8apM2Z0gzhztqnKIydaup92-AeDUXqdrJ23Fi0h74ziPESWEy6Bn8qxak9BONwx62HJf9Mq4WcUx183PUN_qjvvne78w7Vl5vD35zSnmXWcI88mx9ie2FBwYhSYqVCQ70DX2lsSkfO88rGd8oSay-2g_FSjJfa_4c1S3VyPu_Vh0VF79i_Plsxw5PVcDgUk-vj3VhShZwnaEbfbm7vN_c3IGZXYnb1tjP3YzFbHXMphtwZd3ulRgA3Xwc7PAFACs78mFLLLi8qtwcEH3Y79OQ_UoFHKsNE4bxcAWyEnO3Btmi6_spLvA_IuSi1L4I_GbHaQNRlGhS0ioqaFxa1Mjs8HZqQ240uuJV1PhQqePyQ8udaFzU8c6_y3LA9G9g0PR0PBaUuGTExKQlwyD13TMMDV9T3EirVeITWek36gNDyJMyRxeP4YjfupR8mopsXxZV1PF_YloZF26bpoYu64zspR3w-_CKm2Z5Hy2kGVTBFbChkf2pC4CYSbeWcH5XbFWknB0IuhVwqtzucUWxjNMWC_lPIeW-S1p11Sohtqq-PvrO8kz_ObpWQcyEludcRCwazl08wqYGQk1JMroyQ8rP6-cD1H0GnYi85S_1w_Ib9wfczBPnrzn3p3WfQP-vcZ8X4u41VragbHLv8MCH2wRMUdp-m8Xi3SZWheWLppTeu55ntTINPWFoUIC6ydaOeMNf8aGqFtWkQBuViXF6OL9UAF6PpbDwdzeXsYlAvsuIym6pyqsaTcjItcjmVo8uLUTEfTWZyNp8N9EJmcpyNRuPReDKbXAznF7OsHI3y-XieT4qRFBcZ7rleWF2H1u0GUS8W0yzLLgaNyrHx8dYpZdsoqqxjDW60CS98cpPrgVuw6W952HlxkTXak38HI01NvLXy9dOzCE9WcX6fXH_atdL9gTnw6fVhEFyzqIlazwUYZXenqQ75sLDxrpCuDOxR6-xfWPCNIYbkhVzHqP4XAAD__-BqqAs">