Source file
src/runtime/panic.go
1
2
3
4
5 package runtime
6
7 import (
8 "internal/abi"
9 "internal/goarch"
10 "internal/runtime/atomic"
11 "internal/runtime/sys"
12 "internal/stringslite"
13 "unsafe"
14 )
15
16
17
18 type throwType uint32
19
20 const (
21
22 throwTypeNone throwType = iota
23
24
25
26
27
28 throwTypeUser
29
30
31
32
33
34
35 throwTypeRuntime
36 )
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 func panicCheck1(pc uintptr, msg string) {
57 if goarch.IsWasm == 0 && stringslite.HasPrefix(funcname(findfunc(pc)), "runtime.") {
58
59 throw(msg)
60 }
61
62
63 gp := getg()
64 if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
65 throw(msg)
66 }
67 }
68
69
70
71
72
73
74 func panicCheck2(err string) {
75
76
77 gp := getg()
78 if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
79 throw(err)
80 }
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 func goPanicIndex(x int, y int) {
113 panicCheck1(sys.GetCallerPC(), "index out of range")
114 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsIndex})
115 }
116
117
118 func goPanicIndexU(x uint, y int) {
119 panicCheck1(sys.GetCallerPC(), "index out of range")
120 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsIndex})
121 }
122
123
124
125
126 func goPanicSliceAlen(x int, y int) {
127 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
128 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceAlen})
129 }
130
131
132 func goPanicSliceAlenU(x uint, y int) {
133 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
134 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceAlen})
135 }
136
137
138 func goPanicSliceAcap(x int, y int) {
139 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
140 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceAcap})
141 }
142
143
144 func goPanicSliceAcapU(x uint, y int) {
145 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
146 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceAcap})
147 }
148
149
150
151
152 func goPanicSliceB(x int, y int) {
153 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
154 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceB})
155 }
156
157
158 func goPanicSliceBU(x uint, y int) {
159 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
160 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceB})
161 }
162
163
164 func goPanicSlice3Alen(x int, y int) {
165 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
166 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3Alen})
167 }
168 func goPanicSlice3AlenU(x uint, y int) {
169 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
170 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3Alen})
171 }
172 func goPanicSlice3Acap(x int, y int) {
173 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
174 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3Acap})
175 }
176 func goPanicSlice3AcapU(x uint, y int) {
177 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
178 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3Acap})
179 }
180
181
182 func goPanicSlice3B(x int, y int) {
183 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
184 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3B})
185 }
186 func goPanicSlice3BU(x uint, y int) {
187 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
188 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3B})
189 }
190
191
192 func goPanicSlice3C(x int, y int) {
193 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
194 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3C})
195 }
196 func goPanicSlice3CU(x uint, y int) {
197 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
198 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3C})
199 }
200
201
202 func goPanicSliceConvert(x int, y int) {
203 panicCheck1(sys.GetCallerPC(), "slice length too short to convert to array or pointer to array")
204 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsConvert})
205 }
206
207
208 func panicBounds()
209 func panicExtend()
210
211 func panicBounds64(pc uintptr, regs *[16]int64) {
212 f := findfunc(pc)
213 v := pcdatavalue(f, abi.PCDATA_PanicBounds, pc-1)
214
215 code, signed, xIsReg, yIsReg, xVal, yVal := abi.BoundsDecode(int(v))
216
217 if code == abi.BoundsIndex {
218 panicCheck1(pc, "index out of range")
219 } else {
220 panicCheck1(pc, "slice bounds out of range")
221 }
222
223 var e boundsError
224 e.code = code
225 e.signed = signed
226 if xIsReg {
227 e.x = regs[xVal]
228 } else {
229 e.x = int64(xVal)
230 }
231 if yIsReg {
232 e.y = int(regs[yVal])
233 } else {
234 e.y = yVal
235 }
236 panic(e)
237 }
238
239 func panicBounds32(pc uintptr, regs *[16]int32) {
240 f := findfunc(pc)
241 v := pcdatavalue(f, abi.PCDATA_PanicBounds, pc-1)
242
243 code, signed, xIsReg, yIsReg, xVal, yVal := abi.BoundsDecode(int(v))
244
245 if code == abi.BoundsIndex {
246 panicCheck1(pc, "index out of range")
247 } else {
248 panicCheck1(pc, "slice bounds out of range")
249 }
250
251 var e boundsError
252 e.code = code
253 e.signed = signed
254 if xIsReg {
255 if signed {
256 e.x = int64(regs[xVal])
257 } else {
258 e.x = int64(uint32(regs[xVal]))
259 }
260 } else {
261 e.x = int64(xVal)
262 }
263 if yIsReg {
264 e.y = int(regs[yVal])
265 } else {
266 e.y = yVal
267 }
268 panic(e)
269 }
270
271 func panicBounds32X(pc uintptr, regs *[16]int32) {
272 f := findfunc(pc)
273 v := pcdatavalue(f, abi.PCDATA_PanicBounds, pc-1)
274
275 code, signed, xIsReg, yIsReg, xVal, yVal := abi.BoundsDecode(int(v))
276
277 if code == abi.BoundsIndex {
278 panicCheck1(pc, "index out of range")
279 } else {
280 panicCheck1(pc, "slice bounds out of range")
281 }
282
283 var e boundsError
284 e.code = code
285 e.signed = signed
286 if xIsReg {
287
288 lo := xVal & 3
289 hi := xVal >> 2
290 e.x = int64(regs[hi])<<32 + int64(uint32(regs[lo]))
291 } else {
292 e.x = int64(xVal)
293 }
294 if yIsReg {
295 e.y = int(regs[yVal])
296 } else {
297 e.y = yVal
298 }
299 panic(e)
300 }
301
302 var shiftError = error(errorString("negative shift amount"))
303
304
305 func panicshift() {
306 panicCheck1(sys.GetCallerPC(), "negative shift amount")
307 panic(shiftError)
308 }
309
310 var divideError = error(errorString("integer divide by zero"))
311
312
313 func panicdivide() {
314 panicCheck2("integer divide by zero")
315 panic(divideError)
316 }
317
318 var overflowError = error(errorString("integer overflow"))
319
320 func panicoverflow() {
321 panicCheck2("integer overflow")
322 panic(overflowError)
323 }
324
325 var floatError = error(errorString("floating point error"))
326
327 func panicfloat() {
328 panicCheck2("floating point error")
329 panic(floatError)
330 }
331
332 var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
333
334 func panicmem() {
335 panicCheck2("invalid memory address or nil pointer dereference")
336 panic(memoryError)
337 }
338
339 func panicmemAddr(addr uintptr) {
340 panicCheck2("invalid memory address or nil pointer dereference")
341 panic(errorAddressString{msg: "invalid memory address or nil pointer dereference", addr: addr})
342 }
343
344 var simdImmError = error(errorString("out-of-range immediate for simd intrinsic"))
345
346 func panicSimdImm() {
347 panicCheck2("simd immediate error")
348 panic(simdImmError)
349 }
350
351
352
353 func deferproc(fn func()) {
354 gp := getg()
355 if gp.m.curg != gp {
356
357 throw("defer on system stack")
358 }
359
360 d := newdefer()
361 d.link = gp._defer
362 gp._defer = d
363 d.fn = fn
364 d.pc = sys.GetCallerPC()
365
366
367
368 d.sp = sys.GetCallerSP()
369 }
370
371 var rangeDoneError = error(errorString("range function continued iteration after function for loop body returned false"))
372 var rangePanicError = error(errorString("range function continued iteration after loop body panic"))
373 var rangeExhaustedError = error(errorString("range function continued iteration after whole loop exit"))
374 var rangeMissingPanicError = error(errorString("range function recovered a loop body panic and did not resume panicking"))
375
376
377 func panicrangestate(state int) {
378 switch abi.RF_State(state) {
379 case abi.RF_DONE:
380 panic(rangeDoneError)
381 case abi.RF_PANIC:
382 panic(rangePanicError)
383 case abi.RF_EXHAUSTED:
384 panic(rangeExhaustedError)
385 case abi.RF_MISSING_PANIC:
386 panic(rangeMissingPanicError)
387 }
388 throw("unexpected state passed to panicrangestate")
389 }
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458 func deferrangefunc() any {
459 gp := getg()
460 if gp.m.curg != gp {
461
462 throw("defer on system stack")
463 }
464
465 d := newdefer()
466 d.link = gp._defer
467 gp._defer = d
468 d.pc = sys.GetCallerPC()
469
470
471
472 d.sp = sys.GetCallerSP()
473
474 d.rangefunc = true
475 d.head = new(atomic.Pointer[_defer])
476
477 return d.head
478 }
479
480
481 func badDefer() *_defer {
482 return (*_defer)(unsafe.Pointer(uintptr(1)))
483 }
484
485
486
487 func deferprocat(fn func(), frame any) {
488 head := frame.(*atomic.Pointer[_defer])
489 if raceenabled {
490 racewritepc(unsafe.Pointer(head), sys.GetCallerPC(), abi.FuncPCABIInternal(deferprocat))
491 }
492 d1 := newdefer()
493 d1.fn = fn
494 for {
495 d1.link = head.Load()
496 if d1.link == badDefer() {
497 throw("defer after range func returned")
498 }
499 if head.CompareAndSwap(d1.link, d1) {
500 break
501 }
502 }
503 }
504
505
506
507
508 func deferconvert(d0 *_defer) {
509 head := d0.head
510 if raceenabled {
511 racereadpc(unsafe.Pointer(head), sys.GetCallerPC(), abi.FuncPCABIInternal(deferconvert))
512 }
513 tail := d0.link
514 d0.rangefunc = false
515
516 var d *_defer
517 for {
518 d = head.Load()
519 if head.CompareAndSwap(d, badDefer()) {
520 break
521 }
522 }
523 if d == nil {
524 return
525 }
526 for d1 := d; ; d1 = d1.link {
527 d1.sp = d0.sp
528 d1.pc = d0.pc
529 if d1.link == nil {
530 d1.link = tail
531 break
532 }
533 }
534 d0.link = d
535 return
536 }
537
538
539
540
541
542
543
544 func deferprocStack(d *_defer) {
545 gp := getg()
546 if gp.m.curg != gp {
547
548 throw("defer on system stack")
549 }
550
551
552
553
554 d.heap = false
555 d.rangefunc = false
556 d.sp = sys.GetCallerSP()
557 d.pc = sys.GetCallerPC()
558
559
560
561
562
563
564
565
566
567
568 *(*uintptr)(unsafe.Pointer(&d.link)) = uintptr(unsafe.Pointer(gp._defer))
569 *(*uintptr)(unsafe.Pointer(&d.head)) = 0
570 *(*uintptr)(unsafe.Pointer(&gp._defer)) = uintptr(unsafe.Pointer(d))
571 }
572
573
574
575
576
577
578 func newdefer() *_defer {
579 var d *_defer
580 mp := acquirem()
581 pp := mp.p.ptr()
582 if len(pp.deferpool) == 0 && sched.deferpool != nil {
583 lock(&sched.deferlock)
584 for len(pp.deferpool) < cap(pp.deferpool)/2 && sched.deferpool != nil {
585 d := sched.deferpool
586 sched.deferpool = d.link
587 d.link = nil
588 pp.deferpool = append(pp.deferpool, d)
589 }
590 unlock(&sched.deferlock)
591 }
592 if n := len(pp.deferpool); n > 0 {
593 d = pp.deferpool[n-1]
594 pp.deferpool[n-1] = nil
595 pp.deferpool = pp.deferpool[:n-1]
596 }
597 releasem(mp)
598 mp, pp = nil, nil
599
600 if d == nil {
601
602 d = new(_defer)
603 }
604 d.heap = true
605 return d
606 }
607
608
609 func popDefer(gp *g) {
610 d := gp._defer
611 d.fn = nil
612
613
614
615
616 gp._defer = d.link
617 d.link = nil
618
619
620 if !d.heap {
621 return
622 }
623
624 mp := acquirem()
625 pp := mp.p.ptr()
626 if len(pp.deferpool) == cap(pp.deferpool) {
627
628 var first, last *_defer
629 for len(pp.deferpool) > cap(pp.deferpool)/2 {
630 n := len(pp.deferpool)
631 d := pp.deferpool[n-1]
632 pp.deferpool[n-1] = nil
633 pp.deferpool = pp.deferpool[:n-1]
634 if first == nil {
635 first = d
636 } else {
637 last.link = d
638 }
639 last = d
640 }
641 lock(&sched.deferlock)
642 last.link = sched.deferpool
643 sched.deferpool = first
644 unlock(&sched.deferlock)
645 }
646
647 *d = _defer{}
648
649 pp.deferpool = append(pp.deferpool, d)
650
651 releasem(mp)
652 mp, pp = nil, nil
653 }
654
655
656
657
658 func deferreturn() {
659 var p _panic
660 p.deferreturn = true
661
662 p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
663 for {
664 fn, ok := p.nextDefer()
665 if !ok {
666 break
667 }
668 fn()
669 }
670 }
671
672
673
674
675
676
677
678
679
680
681
682 func Goexit() {
683
684
685 var p _panic
686 p.goexit = true
687
688 p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
689 for {
690 fn, ok := p.nextDefer()
691 if !ok {
692 break
693 }
694 fn()
695 }
696
697 goexit1()
698 }
699
700
701
702 func preprintpanics(p *_panic) {
703 defer func() {
704 text := "panic while printing panic value"
705 switch r := recover().(type) {
706 case nil:
707
708 case string:
709 throw(text + ": " + r)
710 default:
711 throw(text + ": type " + toRType(efaceOf(&r)._type).string())
712 }
713 }()
714 for p != nil {
715 if p.link != nil && *efaceOf(&p.link.arg) == *efaceOf(&p.arg) {
716
717
718 p.link.repanicked = true
719 p = p.link
720 continue
721 }
722 switch v := p.arg.(type) {
723 case error:
724 p.arg = v.Error()
725 case stringer:
726 p.arg = v.String()
727 }
728 p = p.link
729 }
730 }
731
732
733
734 func printpanics(p *_panic) {
735 if p.link != nil {
736 printpanics(p.link)
737 if p.link.repanicked {
738 return
739 }
740 if !p.link.goexit {
741 print("\t")
742 }
743 }
744 if p.goexit {
745 return
746 }
747 print("panic: ")
748 printpanicval(p.arg)
749 if p.recovered && p.repanicked {
750 print(" [recovered, repanicked]")
751 } else if p.recovered {
752 print(" [recovered]")
753 }
754 print("\n")
755 }
756
757
758
759
760
761
762 func readvarintUnsafe(fd unsafe.Pointer) (uint32, unsafe.Pointer) {
763 var r uint32
764 var shift int
765 for {
766 b := *(*uint8)(fd)
767 fd = add(fd, unsafe.Sizeof(b))
768 if b < 128 {
769 return r + uint32(b)<<shift, fd
770 }
771 r += uint32(b&0x7F) << (shift & 31)
772 shift += 7
773 if shift > 28 {
774 panic("Bad varint")
775 }
776 }
777 }
778
779
780
781
782
783
784 type PanicNilError struct {
785
786
787
788
789
790
791 _ [0]*PanicNilError
792 }
793
794 func (*PanicNilError) Error() string { return "panic called with nil argument" }
795 func (*PanicNilError) RuntimeError() {}
796
797 var panicnil = &godebugInc{name: "panicnil"}
798
799
800
801
802
803
804
805
806
807
808
809 func gopanic(e any) {
810 if e == nil {
811 if debug.panicnil.Load() != 1 {
812 e = new(PanicNilError)
813 } else {
814 panicnil.IncNonDefault()
815 }
816 }
817
818 gp := getg()
819 if gp.m.curg != gp {
820 print("panic: ")
821 printpanicval(e)
822 print("\n")
823 throw("panic on system stack")
824 }
825
826 if gp.m.mallocing != 0 {
827 print("panic: ")
828 printpanicval(e)
829 print("\n")
830 throw("panic during malloc")
831 }
832 if gp.m.preemptoff != "" {
833 print("panic: ")
834 printpanicval(e)
835 print("\n")
836 print("preempt off reason: ")
837 print(gp.m.preemptoff)
838 print("\n")
839 throw("panic during preemptoff")
840 }
841 if gp.m.locks != 0 {
842 print("panic: ")
843 printpanicval(e)
844 print("\n")
845 throw("panic holding locks")
846 }
847
848 var p _panic
849 p.arg = e
850
851 runningPanicDefers.Add(1)
852
853 p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
854 for {
855 fn, ok := p.nextDefer()
856 if !ok {
857 break
858 }
859 fn()
860 }
861
862
863
864
865
866
867
868 if traceEnabled() {
869 traceAdvance(false)
870 }
871
872
873
874
875
876 preprintpanics(&p)
877
878 fatalpanic(&p)
879 *(*int)(nil) = 0
880 }
881
882
883
884
885 func (p *_panic) start(pc uintptr, sp unsafe.Pointer) {
886 gp := getg()
887
888
889
890
891
892 p.startPC = sys.GetCallerPC()
893 p.startSP = unsafe.Pointer(sys.GetCallerSP())
894
895 if p.deferreturn {
896 p.sp = sp
897
898 if s := (*savedOpenDeferState)(gp.param); s != nil {
899
900
901
902 gp.param = nil
903
904 p.retpc = s.retpc
905 p.deferBitsPtr = (*byte)(add(sp, s.deferBitsOffset))
906 p.slotsPtr = add(sp, s.slotsOffset)
907 }
908
909 return
910 }
911
912 p.link = gp._panic
913 gp._panic = (*_panic)(noescape(unsafe.Pointer(p)))
914
915
916
917
918
919
920
921
922 p.pc, p.sp = pc, sp
923 p.nextFrame()
924 }
925
926
927
928
929
930 func (p *_panic) nextDefer() (func(), bool) {
931 gp := getg()
932
933 if !p.deferreturn {
934 if gp._panic != p {
935 throw("bad panic stack")
936 }
937
938 if p.recovered {
939 mcall(recovery)
940 throw("recovery failed")
941 }
942 }
943
944 for {
945 for p.deferBitsPtr != nil {
946 bits := *p.deferBitsPtr
947
948
949
950
951
952
953
954
955
956 if bits == 0 {
957 p.deferBitsPtr = nil
958 break
959 }
960
961
962 i := 7 - uintptr(sys.LeadingZeros8(bits))
963
964
965 bits &^= 1 << i
966 *p.deferBitsPtr = bits
967
968 return *(*func())(add(p.slotsPtr, i*goarch.PtrSize)), true
969 }
970
971 Recheck:
972 if d := gp._defer; d != nil && d.sp == uintptr(p.sp) {
973 if d.rangefunc {
974 deferconvert(d)
975 popDefer(gp)
976 goto Recheck
977 }
978
979 fn := d.fn
980
981 p.retpc = d.pc
982
983
984 popDefer(gp)
985
986 return fn, true
987 }
988
989 if !p.nextFrame() {
990 return nil, false
991 }
992 }
993 }
994
995
996 func (p *_panic) nextFrame() (ok bool) {
997 if p.pc == 0 {
998 return false
999 }
1000
1001 gp := getg()
1002 systemstack(func() {
1003 var limit uintptr
1004 if d := gp._defer; d != nil {
1005 limit = d.sp
1006 }
1007
1008 var u unwinder
1009 u.initAt(p.pc, uintptr(p.sp), 0, gp, 0)
1010 for {
1011 if !u.valid() {
1012 p.pc = 0
1013 return
1014 }
1015
1016
1017
1018
1019
1020
1021 if u.frame.sp == limit {
1022 break
1023 }
1024
1025 if p.initOpenCodedDefers(u.frame.fn, unsafe.Pointer(u.frame.varp)) {
1026 break
1027 }
1028
1029 if p.link != nil && uintptr(u.frame.sp) == uintptr(p.link.startSP) && uintptr(p.link.sp) > u.frame.sp {
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040 u.initAt(p.link.pc, uintptr(p.link.sp), 0, gp, 0)
1041 continue
1042 }
1043
1044 u.next()
1045 }
1046
1047 p.pc = u.frame.pc
1048 p.sp = unsafe.Pointer(u.frame.sp)
1049 p.fp = unsafe.Pointer(u.frame.fp)
1050
1051 ok = true
1052 })
1053
1054 return
1055 }
1056
1057 func (p *_panic) initOpenCodedDefers(fn funcInfo, varp unsafe.Pointer) bool {
1058 fd := funcdata(fn, abi.FUNCDATA_OpenCodedDeferInfo)
1059 if fd == nil {
1060 return false
1061 }
1062
1063 if fn.deferreturn == 0 {
1064 throw("missing deferreturn")
1065 }
1066
1067 deferBitsOffset, fd := readvarintUnsafe(fd)
1068 deferBitsPtr := (*uint8)(add(varp, -uintptr(deferBitsOffset)))
1069 if *deferBitsPtr == 0 {
1070 return false
1071 }
1072
1073 slotsOffset, fd := readvarintUnsafe(fd)
1074
1075 p.retpc = fn.entry() + uintptr(fn.deferreturn)
1076 p.deferBitsPtr = deferBitsPtr
1077 p.slotsPtr = add(varp, -uintptr(slotsOffset))
1078
1079 return true
1080 }
1081
1082
1083 func gorecover() any {
1084 gp := getg()
1085 p := gp._panic
1086 if p == nil || p.goexit || p.recovered {
1087 return nil
1088 }
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133 canRecover := false
1134 systemstack(func() {
1135 var u unwinder
1136 u.init(gp, 0)
1137 u.next()
1138 u.next()
1139 nonWrapperFrames := 0
1140 loop:
1141 for ; u.valid(); u.next() {
1142 for iu, f := newInlineUnwinder(u.frame.fn, u.symPC()); f.valid(); f = iu.next(f) {
1143 sf := iu.srcFunc(f)
1144 switch sf.funcID {
1145 case abi.FuncIDWrapper:
1146 continue
1147 case abi.FuncID_gopanic:
1148 if u.frame.sp == uintptr(p.startSP) && nonWrapperFrames > 0 {
1149 canRecover = true
1150 }
1151 break loop
1152 default:
1153 nonWrapperFrames++
1154 if nonWrapperFrames > 1 {
1155 break loop
1156 }
1157 }
1158 }
1159 }
1160 })
1161 if !canRecover {
1162 return nil
1163 }
1164 p.recovered = true
1165 return p.arg
1166 }
1167
1168
1169 func sync_throw(s string) {
1170 throw(s)
1171 }
1172
1173
1174 func sync_fatal(s string) {
1175 fatal(s)
1176 }
1177
1178
1179 func rand_fatal(s string) {
1180 fatal(s)
1181 }
1182
1183
1184 func sysrand_fatal(s string) {
1185 fatal(s)
1186 }
1187
1188
1189 func fips_fatal(s string) {
1190 fatal(s)
1191 }
1192
1193
1194 func maps_fatal(s string) {
1195 fatal(s)
1196 }
1197
1198
1199 func internal_sync_throw(s string) {
1200 throw(s)
1201 }
1202
1203
1204 func internal_sync_fatal(s string) {
1205 fatal(s)
1206 }
1207
1208
1209 func cgroup_throw(s string) {
1210 throw(s)
1211 }
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234 func throw(s string) {
1235
1236
1237 systemstack(func() {
1238 print("fatal error: ")
1239 printindented(s)
1240 print("\n")
1241 })
1242
1243 fatalthrow(throwTypeRuntime)
1244 }
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255 func fatal(s string) {
1256 p := getg()._panic
1257
1258
1259 printlock()
1260 systemstack(func() {
1261 printPreFatalDeferPanic(p)
1262 print("fatal error: ")
1263 printindented(s)
1264 print("\n")
1265 })
1266
1267 fatalthrow(throwTypeUser)
1268 printunlock()
1269 }
1270
1271
1272
1273 func printPreFatalDeferPanic(p *_panic) {
1274
1275
1276
1277
1278 for x := p; x != nil; x = x.link {
1279 if x.link != nil && *efaceOf(&x.link.arg) == *efaceOf(&x.arg) {
1280
1281
1282 x.link.repanicked = true
1283 }
1284 }
1285 if p != nil {
1286 printpanics(p)
1287
1288 print("\t")
1289 }
1290 }
1291
1292
1293
1294 var runningPanicDefers atomic.Uint32
1295
1296
1297 var panicking atomic.Uint32
1298
1299
1300
1301 var paniclk mutex
1302
1303
1304
1305
1306
1307
1308
1309
1310 func recovery(gp *g) {
1311 p := gp._panic
1312 pc, sp, fp := p.retpc, uintptr(p.sp), uintptr(p.fp)
1313 p0, saveOpenDeferState := p, p.deferBitsPtr != nil && *p.deferBitsPtr != 0
1314
1315
1316
1317
1318 f := findfunc(pc)
1319 if f.deferreturn == 0 {
1320 throw("no deferreturn")
1321 }
1322 gotoPc := f.entry() + uintptr(f.deferreturn)
1323
1324
1325 for ; p != nil && uintptr(p.startSP) < sp; p = p.link {
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345 if p.goexit {
1346 gotoPc, sp = p.startPC, uintptr(p.startSP)
1347 saveOpenDeferState = false
1348 break
1349 }
1350
1351 runningPanicDefers.Add(-1)
1352 }
1353 gp._panic = p
1354
1355 if p == nil {
1356 gp.sig = 0
1357 }
1358
1359 if gp.param != nil {
1360 throw("unexpected gp.param")
1361 }
1362 if saveOpenDeferState {
1363
1364
1365
1366 gp.param = unsafe.Pointer(&savedOpenDeferState{
1367 retpc: p0.retpc,
1368
1369
1370
1371
1372 deferBitsOffset: uintptr(unsafe.Pointer(p0.deferBitsPtr)) - uintptr(p0.sp),
1373 slotsOffset: uintptr(p0.slotsPtr) - uintptr(p0.sp),
1374 })
1375 }
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402 if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
1403 print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
1404 throw("bad recovery")
1405 }
1406
1407
1408 gp.sched.sp = sp
1409 gp.sched.pc = gotoPc
1410 gp.sched.lr = 0
1411
1412
1413
1414 switch {
1415 case goarch.IsAmd64 != 0:
1416
1417
1418
1419 gp.sched.bp = fp - 2*goarch.PtrSize
1420 case goarch.IsArm64 != 0:
1421
1422
1423
1424 gp.sched.bp = sp - goarch.PtrSize
1425 }
1426 gogo(&gp.sched)
1427 }
1428
1429
1430
1431
1432
1433
1434 func fatalthrow(t throwType) {
1435 pc := sys.GetCallerPC()
1436 sp := sys.GetCallerSP()
1437 gp := getg()
1438
1439 if gp.m.throwing == throwTypeNone {
1440 gp.m.throwing = t
1441 }
1442
1443
1444
1445 systemstack(func() {
1446 if isSecureMode() {
1447 exit(2)
1448 }
1449
1450 startpanic_m()
1451
1452 if dopanic_m(gp, pc, sp, nil) {
1453
1454
1455
1456 crash()
1457 }
1458
1459 exit(2)
1460 })
1461
1462 *(*int)(nil) = 0
1463 }
1464
1465
1466
1467
1468
1469
1470 func fatalpanic(msgs *_panic) {
1471 pc := sys.GetCallerPC()
1472 sp := sys.GetCallerSP()
1473 gp := getg()
1474 var docrash bool
1475
1476
1477 systemstack(func() {
1478 if startpanic_m() && msgs != nil {
1479
1480
1481
1482
1483
1484
1485 runningPanicDefers.Add(-1)
1486
1487 printpanics(msgs)
1488 }
1489
1490
1491
1492 var bubble *synctestBubble
1493 if de, ok := msgs.arg.(synctestDeadlockError); ok {
1494 bubble = de.bubble
1495 }
1496
1497 docrash = dopanic_m(gp, pc, sp, bubble)
1498 })
1499
1500 if docrash {
1501
1502
1503
1504 crash()
1505 }
1506
1507 systemstack(func() {
1508 exit(2)
1509 })
1510
1511 *(*int)(nil) = 0
1512 }
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526 func startpanic_m() bool {
1527 gp := getg()
1528 if mheap_.cachealloc.size == 0 {
1529 print("runtime: panic before malloc heap initialized\n")
1530 }
1531
1532
1533
1534
1535 gp.m.mallocing++
1536
1537
1538
1539 if gp.m.locks < 0 {
1540 gp.m.locks = 1
1541 }
1542
1543 switch gp.m.dying {
1544 case 0:
1545
1546 gp.m.dying = 1
1547 panicking.Add(1)
1548 lock(&paniclk)
1549 if debug.schedtrace > 0 || debug.scheddetail > 0 {
1550 schedtrace(true)
1551 }
1552 freezetheworld()
1553 return true
1554 case 1:
1555
1556
1557 gp.m.dying = 2
1558 print("panic during panic\n")
1559 return false
1560 case 2:
1561
1562
1563 gp.m.dying = 3
1564 print("stack trace unavailable\n")
1565 exit(4)
1566 fallthrough
1567 default:
1568
1569 exit(5)
1570 return false
1571 }
1572 }
1573
1574 var didothers bool
1575 var deadlock mutex
1576
1577
1578
1579
1580 func dopanic_m(gp *g, pc, sp uintptr, bubble *synctestBubble) bool {
1581 if gp.sig != 0 {
1582 signame := signame(gp.sig)
1583 if signame != "" {
1584 print("[signal ", signame)
1585 } else {
1586 print("[signal ", hex(gp.sig))
1587 }
1588 print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
1589 }
1590
1591 level, all, docrash := gotraceback()
1592 if level > 0 {
1593 if gp != gp.m.curg {
1594 all = true
1595 }
1596 if gp != gp.m.g0 {
1597 print("\n")
1598 goroutineheader(gp)
1599 traceback(pc, sp, 0, gp)
1600 } else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
1601 print("\nruntime stack:\n")
1602 traceback(pc, sp, 0, gp)
1603 }
1604 if !didothers {
1605 if all {
1606 didothers = true
1607 tracebackothers(gp)
1608 } else if bubble != nil {
1609
1610
1611 tracebacksomeothers(gp, func(other *g) bool {
1612 return bubble == other.bubble
1613 })
1614 }
1615 }
1616
1617 }
1618 unlock(&paniclk)
1619
1620 if panicking.Add(-1) != 0 {
1621
1622
1623
1624
1625 lock(&deadlock)
1626 lock(&deadlock)
1627 }
1628
1629 printDebugLog()
1630
1631 return docrash
1632 }
1633
1634
1635
1636
1637
1638 func canpanic() bool {
1639 gp := getg()
1640 mp := acquirem()
1641
1642
1643
1644
1645 if gp != mp.curg {
1646 releasem(mp)
1647 return false
1648 }
1649
1650 if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
1651 releasem(mp)
1652 return false
1653 }
1654 status := readgstatus(gp)
1655 if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
1656 releasem(mp)
1657 return false
1658 }
1659 if GOOS == "windows" && mp.libcallsp != 0 {
1660 releasem(mp)
1661 return false
1662 }
1663 releasem(mp)
1664 return true
1665 }
1666
1667
1668
1669
1670
1671
1672 func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
1673 if pc == 0 {
1674
1675
1676
1677
1678
1679 return false
1680 }
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690 if gp.m.incgo || findfunc(pc).valid() {
1691
1692
1693 return true
1694 }
1695 if findfunc(lr).valid() {
1696
1697
1698 return false
1699 }
1700
1701
1702 return true
1703 }
1704
1705
1706
1707
1708
1709
1710
1711
1712 func isAbortPC(pc uintptr) bool {
1713 f := findfunc(pc)
1714 if !f.valid() {
1715 return false
1716 }
1717 return f.funcID == abi.FuncID_abort
1718 }
1719
1720
1721
1722
1723 func dumpPanicDeferState(where string, gp *g) {
1724 systemstack(func() {
1725 println("DUMPPANICDEFERSTATE", where)
1726 p := gp._panic
1727 d := gp._defer
1728 var u unwinder
1729 for u.init(gp, 0); u.valid(); u.next() {
1730
1731 println(" frame sp=", hex(u.frame.sp), "fp=", hex(u.frame.fp), "pc=", pcName(u.frame.pc), "+", pcOff(u.frame.pc))
1732
1733 for p != nil && uintptr(p.sp) == u.frame.sp {
1734 println(" panic", p, "sp=", p.sp, "fp=", p.fp, "arg=", p.arg, "recovered=", p.recovered, "pc=", pcName(p.pc), "+", pcOff(p.pc), "retpc=", pcName(p.retpc), "+", pcOff(p.retpc), "startsp=", p.startSP, "startPC=", hex(p.startPC), pcName(p.startPC), "+", pcOff(p.startPC))
1735 p = p.link
1736 }
1737
1738
1739 for d != nil && d.sp == u.frame.sp {
1740 println(" defer(link)", "heap=", d.heap, "rangefunc=", d.rangefunc, fnName(d.fn))
1741 d = d.link
1742 }
1743
1744
1745
1746
1747 fd := funcdata(u.frame.fn, abi.FUNCDATA_OpenCodedDeferInfo)
1748 if fd != nil {
1749 deferBitsOffset, fd := readvarintUnsafe(fd)
1750 m := *(*uint8)(unsafe.Pointer(u.frame.varp - uintptr(deferBitsOffset)))
1751 slotsOffset, fd := readvarintUnsafe(fd)
1752 slots := u.frame.varp - uintptr(slotsOffset)
1753 for i := 7; i >= 0; i-- {
1754 if m>>i&1 == 0 {
1755 continue
1756 }
1757 fn := *(*func())(unsafe.Pointer(slots + uintptr(i)*goarch.PtrSize))
1758 println(" defer(open)", fnName(fn))
1759 }
1760 }
1761
1762 }
1763 if p != nil {
1764 println(" REMAINING PANICS!", p)
1765 }
1766 if d != nil {
1767 println(" REMAINING DEFERS!")
1768 }
1769 })
1770 }
1771
1772 func pcName(pc uintptr) string {
1773 fn := findfunc(pc)
1774 if !fn.valid() {
1775 return "<unk>"
1776 }
1777 return funcname(fn)
1778 }
1779 func pcOff(pc uintptr) hex {
1780 fn := findfunc(pc)
1781 if !fn.valid() {
1782 return 0
1783 }
1784 return hex(pc - fn.entry())
1785 }
1786 func fnName(fn func()) string {
1787 return pcName(**(**uintptr)(unsafe.Pointer(&fn)))
1788 }
1789
View as plain text