Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion doc/sphinx_source/using/tcl-commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3487,7 +3487,6 @@ The following is a list of bind types and how they work. Below each bind type is

sighup - called on a kill -HUP <pid>
sigterm - called on a kill -TERM <pid>
sigill - called on a kill -ILL <pid>
sigquit - called on a kill -QUIT <pid>
save - called when the userfile is saved
rehash - called just after a rehash
Expand Down
1 change: 0 additions & 1 deletion doc/tcl-commands.doc
Original file line number Diff line number Diff line change
Expand Up @@ -3743,7 +3743,6 @@ the Tcl proc, and an explanation.

sighup - called on a kill -HUP <pid>
sigterm - called on a kill -TERM <pid>
sigill - called on a kill -ILL <pid>
sigquit - called on a kill -QUIT <pid>
save - called when the userfile is saved
rehash - called just after a rehash
Expand Down
33 changes: 24 additions & 9 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,16 +401,31 @@ static void got_alarm(int z)
/* -Never reached- */
}

/* Got ILL signal -- log context and continue
/* Got ILL signal -- log context and crash. Returning from a SIGILL
* handler would re-execute the faulting instruction, triggering the
* signal over and over in an endless loop, so die with a core dump
* like SIGBUS/SIGSEGV instead.
*/
static void got_ill(int z)
{
check_tcl_signal("sigill");
#ifdef DEBUG_CONTEXT
putlog(LOG_MISC, "*", "* Please REPORT this BUG!");
putlog(LOG_MISC, "*", "* Check doc/BUG-REPORT on how to do so.");
putlog(LOG_MISC, "*", "* Last bind (may not be related): %s", last_bind_called);
#endif
struct sigaction sv;
sigset_t set;

write_debug();
fatal("ILLEGAL INSTRUCTION -- CRASHING!", 1);
/* SA_RESETHAND should already have restored the default action, but
* that cannot be relied upon on every platform (e.g. macOS keeps the
* handler installed), so restore it explicitly, unblock the signal
* and re-raise it to die with a core dump.
*/
sv.sa_handler = SIG_DFL;
sigemptyset(&sv.sa_mask);
sv.sa_flags = 0;
sigaction(SIGILL, &sv, NULL);
sigemptyset(&set);
sigaddset(&set, SIGILL);
sigprocmask(SIG_UNBLOCK, &set, NULL);
kill(getpid(), SIGILL);
}

#ifdef DEBUG_ASSERT
Expand Down Expand Up @@ -1010,6 +1025,8 @@ int main(int arg_c, char **arg_v)
sigaction(SIGBUS, &sv, NULL);
sv.sa_handler = got_segv;
sigaction(SIGSEGV, &sv, NULL);
sv.sa_handler = got_ill;
sigaction(SIGILL, &sv, NULL);
#ifdef SA_RESETHAND
sv.sa_flags = 0;
#endif
Expand All @@ -1023,8 +1040,6 @@ int main(int arg_c, char **arg_v)
sigaction(SIGQUIT, &sv, NULL);
sv.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sv, NULL);
sv.sa_handler = got_ill;
sigaction(SIGILL, &sv, NULL);
sv.sa_handler = got_alarm;
sigaction(SIGALRM, &sv, NULL);
// Added for python.mod because the _signal handler otherwise overwrites it
Expand Down
Loading