Bug 234814

Summary: Valgrind handles signals on Linux and Mac OS differently.
Product: [Developer tools] valgrind Reporter: Alexander Potapenko <glider>
Component: generalAssignee: Rhys Kidd <rhyskidd>
Status: CONFIRMED ---    
Severity: normal CC: n.nethercote, pjfloyd, rhyskidd
Priority: NOR    
Version: 3.10 SVN   
Target Milestone: ---   
Platform: Unlisted Binaries   
OS: macOS   
See Also: https://bugs.kde.org/show_bug.cgi?id=192607
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Alexander Potapenko 2010-04-19 16:29:21 UTC
The following code is handled differently on Linux and Mac OS 10.5:

$ cat sigbus.c 
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

const char kSigbus[] = "I caught the SIGBUS signal!\n";

int GLOB = 3;

void mysigbus() {
    write(2, kSigbus, sizeof(kSigbus));
    GLOB--;
    return;    
}

int main() {
  struct sigaction sa;
  sa.sa_handler = mysigbus;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;
  if (sigaction(SIGBUS, &sa, NULL) == -1) {
    perror("ERROR:");
  }
  while(GLOB) {
    kill(getpid(), SIGBUS);
  };
  return 0;
} 


$ gcc sigbus.c -o sigbus
$ ./sigbus 
I caught the SIGBUS signal!
I caught the SIGBUS signal!
I caught the SIGBUS signal!

$ uname -a
Darwin mcgrind 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386

$ valgrind --tool=none ./sigbus
==82856== Nulgrind, the minimal Valgrind tool
...
--82856-- VALGRIND INTERNAL ERROR: Valgrind received a signal 10 (SIGBUS) - exiting
--82856-- si_code=2;  Faulting address: 0xF00EFDA0;  sp: 0xf7573c9c

valgrind: the 'impossible' happened:
   Killed by fatal signal
==82856==    at 0xF009B940: ???
==82856==    by 0xF00EFED6: ???
==82856==    by 0xF00E64EB: ???
==82856==    by 0xF00E20A3: ???
==82856==    by 0xF00E31EB: ???
==82856==    by 0xF01099DF: ???

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable
==82856==    at 0x264E42: __kill (in /usr/lib/libSystem.B.dylib)
==82856==    by 0x1FC2: main (in ./sigbus)


As one can see, sending a signal to self crashes Valgrind on Mac OS, whereas it behaves correctly on Linux:
$ uname -a
Linux glider-box.msk 2.6.24-generic #1 SMP Tue Dec 22 15:27:33 PST 2009 x86_64 GNU/Linux

$ valgrind --tool=none ./sigbus
==14118== Nulgrind, the minimal Valgrind tool
...
==14118== Command: ./sigbus
==14118== 
I caught the SIGBUS signal!
I caught the SIGBUS signal!
I caught the SIGBUS signal!
==14118==
Comment 1 Rhys Kidd 2015-05-07 14:08:45 UTC
Confirmed still present through OS X 10.9 (and likely OS X 10.10).
Comment 2 Rhys Kidd 2015-05-23 10:21:14 UTC
Added presently failing test case in r15282.
Comment 3 Rhys Kidd 2015-05-25 14:45:36 UTC
Can be reliably reproduced with the following regression test:

$ perl tests/vg_regtest none/tests/bug234814
bug234814:       valgrind   ./bug234814 
*** bug234814 failed (stdout) ***
*** bug234814 failed (stderr) ***

== 1 test, 1 stderr failure, 1 stdout failure, 0 stderrB failures, 0 stdoutB failures, 0 post failures ==
none/tests/bug234814                     (stdout)
none/tests/bug234814                     (stderr)
Comment 4 Paul Floyd 2020-04-13 17:51:19 UTC
I see this on FreeBSD as well. Traces

==12920== Command: ./bug234814
==12920== 
--12920-- Max kernel-supported signal is 128, VG_SIGVGKILL is 128
--12920-- sync signal handler: signal=11, si_code=1, EIP=0x4018013, eip=0x4026a3de3, from kernel
--12920-- SIGSEGV: si_code=1 faultaddr=0x7feffeb30 tid=1 ESP=0x7feffeb30 seg=0x7fe001000-0x7feffefff
--12920--        -> extended stack base to 0x7feffe000
--12920-- sync signal handler: signal=11, si_code=1, EIP=0x4018013, eip=0x4026a3de3, from kernel
--12920-- SIGSEGV: si_code=1 faultaddr=0x7feffddb0 tid=1 ESP=0x7feffddb0 seg=0x7fe001000-0x7feffdfff
--12920--        -> extended stack base to 0x7feffd000
--12920-- do_setmask: tid = 1 how = 1 (SIG_BLOCK), newset = 0x4025C80 (fffffffffffffffffffffffffffff107)
--12920--       oldset=0x7FEFFF990 00000000000000000000000000000000
--12920-- do_setmask: tid = 1 how = 3 (SIG_SETMASK), newset = 0x4025C94 (00000000000000000000000000000000)
--12920-- do_setmask: tid = 1 how = 1 (SIG_BLOCK), newset = 0x4025C80 (fffffffffffffffffffffffffffff107)
--12920--       oldset=0x7FEFFF900 00000000000000000000000000000000
--12920-- do_setmask: tid = 1 how = 3 (SIG_SETMASK), newset = 0x4025C94 (00000000000000000000000000000000)
--12920-- do_setmask: tid = 1 how = 1 (SIG_BLOCK), newset = 0x4025C80 (fffffffffffffffffffffffffffff107)
--12920--       oldset=0x7FEFFF510 00000000000000000000000000000000
--12920-- do_setmask: tid = 1 how = 3 (SIG_SETMASK), newset = 0x4025C94 (00000000000000000000000000000000)
--12920-- do_setmask: tid = 1 how = 1 (SIG_BLOCK), newset = 0x4025C80 (fffffffffffffffffffffffffffff107)
--12920--       oldset=0x7FEFFF510 00000000000000000000000000000000
--12920-- do_setmask: tid = 1 how = 3 (SIG_SETMASK), newset = 0x4025C94 (00000000000000000000000000000000)
--12920-- do_setmask: tid = 1 how = 1 (SIG_BLOCK), newset = 0x4025C80 (fffffffffffffffffffffffffffff107)
--12920--       oldset=0x7FEFFF510 00000000000000000000000000000000
--12920-- do_setmask: tid = 1 how = 3 (SIG_SETMASK), newset = 0x4025C94 (00000000000000000000000000000000)
--12920-- sys_sigaction: sigNo 10, new 0x7ff000470, old 0x0, new flags 0x0
--12920-- sync signal handler: signal=10, si_code=65537, EIP=0x4b946ca, eip=0x38071bc6, from kernel
--12920-- VALGRIND INTERNAL ERROR: Valgrind received a signal 10 (SIGBUS) - exiting
--12920-- si_code=65537;  Faulting address: 0x0;  sp: 0x40268db88

valgrind: the 'impossible' happened:
   Killed by fatal signal

host stacktrace:
==12920==    at 0x38071BC6: ??? (in /usr/home/paulf/scratch/valgrind/none/none-amd64-freebsd)
==12920==    by 0x38071C61: ??? (in /usr/home/paulf/scratch/valgrind/none/none-amd64-freebsd)
==12920==    by 0x3801D2F1: ??? (in /usr/home/paulf/scratch/valgrind/none/none-amd64-freebsd)
==12920==    by 0xDEADBEEFDEADBEEE: ???