I was performing a simple demonstration of signal handlers as an exercise when I noticed some odd behaviour. The following code works unchanged on ubuntu 14.04 LTS but not on macOS Sierra 10.12.6. That is on macOS the program hangs forever with no output. However, it works on both platforms with printf
commented out in the signal handlers or with an extra printf
added in the main function anywhere before the posix_memalign
call. I don't understand this behaviour, what's going on?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <signal.h>
//Has to be global for signal handler
char* mem_spot = NULL;
const char* copy_from = "hello";
const int mem_req = 5;
//signal handler prototype
void handle_seg(int fault);
int
main(int argc, char const *argv[])
{
//On macOS this must be placed uncommented somewhere before
//posix_memalign or the signal handler printing removed:
//printf("Strange fixing code!");
//setup signal handlers
signal(SIGSEGV,handle_seg);
signal(SIGBUS,handle_seg);
//get memory aligned to the page and protect it
posix_memalign((void**) &mem_spot, getpagesize(), mem_req);
mprotect(mem_spot,mem_req,PROT_READ);
//Copying into the memory slot (it's protected so should break!)
strcpy(mem_spot,copy_from);
//Output my results
printf("Write of string '%s' to memory giving '%s' complete!\n",copy_from, mem_spot);
return 0;
}
void handle_seg(int fault)
{
if (fault == SIGSEGV){
printf(" (Handled a segmentation fault!) ");
mprotect(mem_spot,mem_req,PROT_READ | PROT_WRITE);
}
else if (fault == SIGBUS){
printf(" (Handled a bus fault!) ");
mprotect(mem_spot,mem_req,PROT_READ | PROT_WRITE);
}
}