tsan11.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // Copyright 2017 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. package main
  5. // This program hung when run under the C/C++ ThreadSanitizer. TSAN defers
  6. // asynchronous signals until the signaled thread calls into libc. The runtime's
  7. // sysmon goroutine idles itself using direct usleep syscalls, so it could
  8. // run for an arbitrarily long time without triggering the libc interceptors.
  9. // See https://golang.org/issue/18717.
  10. import (
  11. "os"
  12. "os/signal"
  13. "syscall"
  14. )
  15. /*
  16. #cgo CFLAGS: -g -fsanitize=thread
  17. #cgo LDFLAGS: -g -fsanitize=thread
  18. #include <signal.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. static void raise_usr2(int signo) {
  23. raise(SIGUSR2);
  24. }
  25. static void register_handler(int signo) {
  26. struct sigaction sa;
  27. memset(&sa, 0, sizeof(sa));
  28. sigemptyset(&sa.sa_mask);
  29. sa.sa_flags = SA_ONSTACK;
  30. sa.sa_handler = raise_usr2;
  31. if (sigaction(SIGUSR1, &sa, NULL) != 0) {
  32. perror("failed to register SIGUSR1 handler");
  33. exit(EXIT_FAILURE);
  34. }
  35. }
  36. */
  37. import "C"
  38. func main() {
  39. ch := make(chan os.Signal, 1)
  40. signal.Notify(ch, syscall.SIGUSR2)
  41. C.register_handler(C.int(syscall.SIGUSR1))
  42. syscall.Kill(syscall.Getpid(), syscall.SIGUSR1)
  43. <-ch
  44. }