main_unix.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. #include <signal.h>
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. struct sigaction sa;
  10. struct sigaction osa;
  11. static void (*oldHandler)(int, siginfo_t*, void*);
  12. static void handler(int signo, siginfo_t* info, void* ctxt) {
  13. if (oldHandler) {
  14. oldHandler(signo, info, ctxt);
  15. }
  16. }
  17. int install_handler() {
  18. // Install our own signal handler.
  19. memset(&sa, 0, sizeof sa);
  20. sa.sa_sigaction = handler;
  21. sigemptyset(&sa.sa_mask);
  22. sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
  23. memset(&osa, 0, sizeof osa);
  24. sigemptyset(&osa.sa_mask);
  25. if (sigaction(SIGSEGV, &sa, &osa) < 0) {
  26. perror("sigaction");
  27. return 2;
  28. }
  29. if (osa.sa_handler == SIG_DFL) {
  30. fprintf(stderr, "Go runtime did not install signal handler\n");
  31. return 2;
  32. }
  33. // gccgo does not set SA_ONSTACK for SIGSEGV.
  34. if (getenv("GCCGO") == NULL && (osa.sa_flags&SA_ONSTACK) == 0) {
  35. fprintf(stderr, "Go runtime did not install signal handler\n");
  36. return 2;
  37. }
  38. oldHandler = osa.sa_sigaction;
  39. return 0;
  40. }
  41. int check_handler() {
  42. if (sigaction(SIGSEGV, NULL, &sa) < 0) {
  43. perror("sigaction check");
  44. return 2;
  45. }
  46. if (sa.sa_sigaction != handler) {
  47. fprintf(stderr, "ERROR: wrong signal handler: %p != %p\n", sa.sa_sigaction, handler);
  48. return 2;
  49. }
  50. return 0;
  51. }