runtime_unix.c raw

   1  //go:build none
   2  
   3  // This file is included on Darwin and Linux (despite the //go:build line above).
   4  
   5  #define _GNU_SOURCE
   6  #define _XOPEN_SOURCE
   7  #include <signal.h>
   8  #include <unistd.h>
   9  #include <stdint.h>
  10  #include <ucontext.h>
  11  #include <string.h>
  12  
  13  void moxie_handle_fatal_signal(int sig, uintptr_t addr);
  14  
  15  static void signal_handler(int sig, siginfo_t *info, void *context) {
  16  	ucontext_t* uctx = context;
  17  	uintptr_t addr = 0;
  18  	#if __APPLE__
  19  		#if __arm64__
  20  			addr = uctx->uc_mcontext->__ss.__pc;
  21  		#elif __x86_64__
  22  			addr = uctx->uc_mcontext->__ss.__rip;
  23  		#else
  24  			#error unknown architecture
  25  		#endif
  26  	#elif __linux__
  27  		// Note: this can probably be simplified using the MC_PC macro in musl,
  28  		// but this works for now.
  29  		#if __arm__
  30  			addr = uctx->uc_mcontext.arm_pc;
  31  		#elif __i386__
  32  			addr = uctx->uc_mcontext.gregs[REG_EIP];
  33  		#elif __x86_64__
  34  			addr = uctx->uc_mcontext.gregs[REG_RIP];
  35  		#else // aarch64, mips, maybe others
  36  			addr = uctx->uc_mcontext.pc;
  37  		#endif
  38  	#else
  39  		#error unknown platform
  40  	#endif
  41  	moxie_handle_fatal_signal(sig, addr);
  42  }
  43  
  44  void moxie_register_fatal_signals(void) {
  45  	// Ignore SIGPIPE — network servers must not die on write-to-closed-socket.
  46  	// Go's runtime does this; moxie must too.
  47  	signal(SIGPIPE, SIG_IGN);
  48  
  49  	struct sigaction act = { 0 };
  50  	// SA_SIGINFO:   we want the 2 extra parameters
  51  	// SA_RESETHAND: only catch the signal once (the handler will re-raise the signal)
  52  	act.sa_flags = SA_SIGINFO | SA_RESETHAND;
  53  	act.sa_sigaction = &signal_handler;
  54  
  55  	// Register the signal handler for common issues. There are more signals,
  56  	// which can be added if needed.
  57  	sigaction(SIGBUS, &act, NULL);
  58  	sigaction(SIGILL, &act, NULL);
  59  	sigaction(SIGSEGV, &act, NULL);
  60  }
  61