You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.5 KiB

  1. // +build go1.9
  2. package stack_test
  3. import (
  4. "runtime"
  5. "testing"
  6. "github.com/go-stack/stack"
  7. )
  8. func TestCallerInlinedPanic(t *testing.T) {
  9. t.Parallel()
  10. var line int
  11. defer func() {
  12. if recover() != nil {
  13. var pcs [32]uintptr
  14. n := runtime.Callers(1, pcs[:])
  15. frames := runtime.CallersFrames(pcs[:n])
  16. // count frames to runtime.sigpanic
  17. panicIdx := 0
  18. for {
  19. f, more := frames.Next()
  20. if f.Function == "runtime.sigpanic" {
  21. break
  22. }
  23. panicIdx++
  24. if !more {
  25. t.Fatal("no runtime.sigpanic entry on the stack")
  26. }
  27. }
  28. c := stack.Caller(panicIdx)
  29. if got, want := c.Frame().Function, "runtime.sigpanic"; got != want {
  30. t.Errorf("sigpanic frame: got name == %v, want name == %v", got, want)
  31. }
  32. c1 := stack.Caller(panicIdx + 1)
  33. if got, want := c1.Frame().Function, "github.com/go-stack/stack_test.inlinablePanic"; got != want {
  34. t.Errorf("TestCallerInlinedPanic frame: got name == %v, want name == %v", got, want)
  35. }
  36. if got, want := c1.Frame().Line, line; got != want {
  37. t.Errorf("TestCallerInlinedPanic frame: got line == %v, want line == %v", got, want)
  38. }
  39. }
  40. }()
  41. doPanic(t, &line)
  42. t.Fatal("failed to panic")
  43. }
  44. func doPanic(t *testing.T, panicLine *int) {
  45. _, _, line, ok := runtime.Caller(0)
  46. *panicLine = line + 11 // adjust to match line of panic below
  47. if !ok {
  48. t.Fatal("runtime.Caller(0) failed")
  49. }
  50. inlinablePanic()
  51. }
  52. func inlinablePanic() {
  53. // Initiate a sigpanic.
  54. var x *uintptr
  55. _ = *x
  56. }