Description of problem: ksh crashes when last script command also crashes Version-Release number of selected component (if applicable): ksh-20120801-31.fc25.x86_64 How reproducible: Every time Steps to Reproduce: 1. compile c program that 100% crashes $ cat crash.c int main(){ int i = 1; int j = 0; int x = 0; x = i/j; return 2; } gcc -o crash crash.c 2. create ksh script where last command must crash $ cat test.ksh #!/bin/ksh echo "crash test" ./crash 3. run ksh script Actual results: ksh crashes $ ./test.ksh crash test ./test.ksh: line 4: 29810: Floating exception(coredump) Floating point exception (core dumped) Expected results: No crash - as for example in this case $ cat test.ksh #!/bin/ksh echo "crash test" ./crash echo "finish" $ ./test.ksh crash test ./test.ksh: line 4: 29829: Floating exception(coredump) finish Additional info:
http://rainbow.chard.org/2017/03/21/ksh-deliberately-segfaults-if-the-last-command-in-a-script-crashes/ ksh deliberately segfaults if the last command in a script crashes
ksh did not crash, it is just putting wrong error message while exiting.
(In reply to Siteshwar Vashisht from comment #3) > ksh did not crash, it is just putting wrong error message while exiting. In my testing scenario, ksh printed a correct error message for the command that was terminated by a signal, but then it killed itself, instead of calling exit() as it is common with other shells. Minimal example: % ksh -c 'echo kill -11 \$\$ | ksh' ksh: 1812: Memory fault(coredump) % strace -f ksh -c 'echo kill -11 \$\$ | ksh' [...] [pid 1853] kill(1853, SIGSEGV) = 0 [pid 1853] --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_USER, si_pid=1853, si_uid=1000} --- [pid 1853] +++ killed by SIGSEGV (core dumped) +++ <... wait4 resumed> [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV && WCOREDUMP(s)}], WSTOPPED|WCONTINUED, NULL) = 1853 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_DUMPED, si_pid=1853, si_uid=1000, si_status=SIGSEGV, si_utime=0, si_stime=0} --- [...] getpid() = 1851 kill(1851, SIGSEGV) = 0 --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_USER, si_pid=1851, si_uid=1000} --- +++ killed by SIGSEGV (core dumped) +++
ksh incorrectly picks up the signal number from exit status here[1]. [1] https://github.com/att/ast/blob/beta/src/cmd/ksh93/sh/fault.c#L674-L675
I believe ksh kills itself instead of exiting with a status code because it uses non-posix exit codes for signals. POSIX exit codes: 128 + signal number Korn Shell: 256 + signal number so it looks like korn shell works around this situation by killing itself with the signal number to remain compliant with other posix shells.
This patch[1] fixes the issue, however it changes exit status code as exit() is being used instead of kill() for exiting ksh : Before the patch : [situ@localhost tmp]$ /usr/bin/ksh crash.sh crash test crash.sh: line 2: 10407: Floating exception(coredump) Floating point exception (core dumped) [situ@localhost tmp]$ echo $? 136 After the patch : [situ@localhost tmp]$ /home/situ/upstream/ast/arch/linux.i386-64/bin/ksh crash.sh crash test crash.sh: line 2: 10359: Floating exception(coredump) [situ@localhost tmp]$ echo $? 8 [1] https://github.com/att/ast/pull/57
(In reply to Siteshwar Vashisht from comment #7) > After the patch : > > [situ@localhost tmp]$ /home/situ/upstream/ast/arch/linux.i386-64/bin/ksh > crash.sh > crash test > crash.sh: line 2: 10359: Floating exception(coredump) > [situ@localhost tmp]$ echo $? > 8 This does not look correct to me. Both bash and zsh exit with 136 for the given example, so I presume the exit code 136 is correct. The only difference (without the patch) is that bash and zsh exits whereas ksh is killed.
I updated the PR[1] to return correct POSIX exit codes if last process in script exits due a signal. [1] https://github.com/att/ast/pull/57
*** This bug has been marked as a duplicate of bug 1471874 ***
(In reply to Siteshwar Vashisht from comment #9) > I updated the PR[1] to return correct POSIX exit codes if last process in > script exits due a signal. > > [1] https://github.com/att/ast/pull/57 POSIX intends to specify and recommend ksh93's behaviour there. See http://www.austingroupbugs.net/view.php?id=51 approved for the next major release. In any case, no version of POSIX specifies that $? be 128+signum. See also yash where it's $?+128+256. All it specifies is that it should be greater than 128 (and kill -l "$?" can tell what signal killed the process). See also https://unix.stackexchange.com/questions/99112/default-exit-code-when-process-is-terminated/99134#99134