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 "runtime error: 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 var limitFn funcInfo
1005 if d := gp._defer; d != nil {
1006 limit = d.sp
1007 limitFn = findfunc(d.pc)
1008 }
1009
1010 var u unwinder
1011 u.initAt(p.pc, uintptr(p.sp), 0, gp, 0)
1012 for {
1013 if !u.valid() {
1014 p.pc = 0
1015 return
1016 }
1017
1018
1019
1020
1021
1022
1023 if u.frame.sp == limit && u.frame.fn == limitFn {
1024 break
1025 }
1026
1027 if p.initOpenCodedDefers(u.frame.fn, unsafe.Pointer(u.frame.varp)) {
1028 break
1029 }
1030
1031 if p.link != nil && uintptr(u.frame.sp) == uintptr(p.link.startSP) && uintptr(p.link.sp) > u.frame.sp {
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042 u.initAt(p.link.pc, uintptr(p.link.sp), 0, gp, 0)
1043 continue
1044 }
1045
1046 u.next()
1047 }
1048
1049 p.pc = u.frame.pc
1050 p.sp = unsafe.Pointer(u.frame.sp)
1051 p.fp = u.frame.fp
1052
1053 ok = true
1054 })
1055
1056 return
1057 }
1058
1059 func (p *_panic) initOpenCodedDefers(fn funcInfo, varp unsafe.Pointer) bool {
1060 fd := funcdata(fn, abi.FUNCDATA_OpenCodedDeferInfo)
1061 if fd == nil {
1062 return false
1063 }
1064
1065 if fn.deferreturn == 0 {
1066 throw("missing deferreturn")
1067 }
1068
1069 deferBitsOffset, fd := readvarintUnsafe(fd)
1070 deferBitsPtr := (*uint8)(add(varp, -uintptr(deferBitsOffset)))
1071 if *deferBitsPtr == 0 {
1072 return false
1073 }
1074
1075 slotsOffset, fd := readvarintUnsafe(fd)
1076
1077 p.retpc = fn.entry() + uintptr(fn.deferreturn)
1078 p.deferBitsPtr = deferBitsPtr
1079 p.slotsPtr = add(varp, -uintptr(slotsOffset))
1080
1081 return true
1082 }
1083
1084
1085 func gorecover() any {
1086 p := recoverablePanic(3)
1087 if p == nil {
1088 return nil
1089 }
1090 p.recovered = true
1091 return p.arg
1092 }
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102 func recoverrangefunc() any {
1103 p := recoverablePanic(3)
1104 if p == nil {
1105
1106
1107 return nil
1108 }
1109 return p
1110 }
1111
1112
1113
1114
1115 func gorecoverat(frame any) any {
1116 p, _ := frame.(*_panic)
1117 if p == nil {
1118 return nil
1119 }
1120
1121
1122
1123
1124 if gp := getg(); gp._panic != p || p.goexit || p.recovered {
1125 return nil
1126 }
1127 p.recovered = true
1128 return p.arg
1129 }
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198 func recoverablePanic(skip int) *_panic {
1199 gp := getg()
1200 p := gp._panic
1201 if p == nil || p.goexit || p.recovered {
1202 return nil
1203 }
1204
1205 canRecover := false
1206 systemstack(func() {
1207 var u unwinder
1208 u.init(gp, 0)
1209 for i := 0; i < skip; i++ {
1210 u.next()
1211 }
1212 nonWrapperFrames := 0
1213 loop:
1214 for ; u.valid(); u.next() {
1215 for iu, f := newInlineUnwinder(u.frame.fn, u.symPC()); f.valid(); f = iu.next(f) {
1216 sf := iu.srcFunc(f)
1217 switch sf.funcID {
1218 case abi.FuncIDWrapper:
1219 continue
1220 case abi.FuncID_gopanic:
1221 if u.frame.sp == uintptr(p.startSP) && nonWrapperFrames > 0 {
1222 canRecover = true
1223 }
1224 break loop
1225 default:
1226 nonWrapperFrames++
1227 if nonWrapperFrames > 1 {
1228 break loop
1229 }
1230 }
1231 }
1232 }
1233 })
1234 if !canRecover {
1235 return nil
1236 }
1237 return p
1238 }
1239
1240
1241 func sync_throw(s string) {
1242 throw(s)
1243 }
1244
1245
1246 func sync_fatal(s string) {
1247 fatal(s)
1248 }
1249
1250
1251 func rand_fatal(s string) {
1252 fatal(s)
1253 }
1254
1255
1256 func sysrand_fatal(s string) {
1257 fatal(s)
1258 }
1259
1260
1261 func fips_fatal(s string) {
1262 fatal(s)
1263 }
1264
1265
1266 func maps_fatal(s string) {
1267 fatal(s)
1268 }
1269
1270
1271 func internal_sync_throw(s string) {
1272 throw(s)
1273 }
1274
1275
1276 func internal_sync_fatal(s string) {
1277 fatal(s)
1278 }
1279
1280
1281 func cgroup_throw(s string) {
1282 throw(s)
1283 }
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306 func throw(s string) {
1307
1308
1309 systemstack(func() {
1310 print("fatal error: ")
1311 printindented(s)
1312 print("\n")
1313 })
1314
1315 fatalthrow(throwTypeRuntime)
1316 }
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327 func fatal(s string) {
1328 p := getg()._panic
1329
1330
1331 printlock()
1332 systemstack(func() {
1333 printPreFatalDeferPanic(p)
1334 print("fatal error: ")
1335 printindented(s)
1336 print("\n")
1337 })
1338
1339 fatalthrow(throwTypeUser)
1340 printunlock()
1341 }
1342
1343
1344
1345 func printPreFatalDeferPanic(p *_panic) {
1346
1347
1348
1349
1350 for x := p; x != nil; x = x.link {
1351 if x.link != nil && *efaceOf(&x.link.arg) == *efaceOf(&x.arg) {
1352
1353
1354 x.link.repanicked = true
1355 }
1356 }
1357 if p != nil {
1358 printpanics(p)
1359
1360 print("\t")
1361 }
1362 }
1363
1364
1365
1366 var runningPanicDefers atomic.Uint32
1367
1368
1369 var panicking atomic.Uint32
1370
1371
1372
1373 var paniclk mutex
1374
1375
1376
1377
1378
1379
1380
1381
1382 func recovery(gp *g) {
1383 p := gp._panic
1384 pc, sp, fp := p.retpc, uintptr(p.sp), p.fp
1385 p0, saveOpenDeferState := p, p.deferBitsPtr != nil && *p.deferBitsPtr != 0
1386
1387
1388
1389
1390 f := findfunc(pc)
1391 if f.deferreturn == 0 {
1392 throw("no deferreturn")
1393 }
1394 gotoPc := f.entry() + uintptr(f.deferreturn)
1395
1396
1397 for ; p != nil && uintptr(p.startSP) < sp; p = p.link {
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417 if p.goexit {
1418 gotoPc, sp = p.startPC, uintptr(p.startSP)
1419 saveOpenDeferState = false
1420 break
1421 }
1422
1423 runningPanicDefers.Add(-1)
1424 }
1425 gp._panic = p
1426
1427 if p == nil {
1428 gp.sig = 0
1429 }
1430
1431 if gp.param != nil {
1432 throw("unexpected gp.param")
1433 }
1434 if saveOpenDeferState {
1435
1436
1437
1438 gp.param = unsafe.Pointer(&savedOpenDeferState{
1439 retpc: p0.retpc,
1440
1441
1442
1443
1444 deferBitsOffset: uintptr(unsafe.Pointer(p0.deferBitsPtr)) - uintptr(p0.sp),
1445 slotsOffset: uintptr(p0.slotsPtr) - uintptr(p0.sp),
1446 })
1447 }
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474 if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
1475 print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
1476 throw("bad recovery")
1477 }
1478
1479
1480 gp.sched.sp = sp
1481 gp.sched.pc = gotoPc
1482 gp.sched.lr = 0
1483
1484
1485
1486 switch {
1487 case goarch.IsAmd64 != 0:
1488
1489
1490
1491 gp.sched.bp = fp - 2*goarch.PtrSize
1492 case goarch.IsArm64 != 0:
1493
1494
1495
1496 gp.sched.bp = sp - goarch.PtrSize
1497 }
1498 gogo(&gp.sched)
1499 }
1500
1501
1502
1503
1504
1505
1506 func fatalthrow(t throwType) {
1507 pc := sys.GetCallerPC()
1508 sp := sys.GetCallerSP()
1509 gp := getg()
1510
1511 if gp.m.throwing == throwTypeNone {
1512 gp.m.throwing = t
1513 }
1514
1515
1516
1517 systemstack(func() {
1518 if isSecureMode() {
1519 exit(2)
1520 }
1521
1522 startpanic_m()
1523
1524 if dopanic_m(gp, pc, sp, nil) {
1525
1526
1527
1528 crash()
1529 }
1530
1531 exit(2)
1532 })
1533
1534 *(*int)(nil) = 0
1535 }
1536
1537
1538
1539
1540
1541
1542 func fatalpanic(msgs *_panic) {
1543 pc := sys.GetCallerPC()
1544 sp := sys.GetCallerSP()
1545 gp := getg()
1546 var docrash bool
1547
1548
1549 systemstack(func() {
1550 if startpanic_m() && msgs != nil {
1551
1552
1553
1554
1555
1556
1557 runningPanicDefers.Add(-1)
1558
1559 printpanics(msgs)
1560 }
1561
1562
1563
1564 var bubble *synctestBubble
1565 if de, ok := msgs.arg.(synctestDeadlockError); ok {
1566 bubble = de.bubble
1567 }
1568
1569 docrash = dopanic_m(gp, pc, sp, bubble)
1570 })
1571
1572 if docrash {
1573
1574
1575
1576 crash()
1577 }
1578
1579 systemstack(func() {
1580 exit(2)
1581 })
1582
1583 *(*int)(nil) = 0
1584 }
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598 func startpanic_m() bool {
1599 gp := getg()
1600 if mheap_.cachealloc.size == 0 {
1601 print("runtime: panic before malloc heap initialized\n")
1602 }
1603
1604
1605
1606
1607 gp.m.mallocing++
1608
1609
1610
1611 if gp.m.locks < 0 {
1612 gp.m.locks = 1
1613 }
1614
1615 switch gp.m.dying {
1616 case 0:
1617
1618 gp.m.dying = 1
1619 panicking.Add(1)
1620 lock(&paniclk)
1621 if debug.schedtrace > 0 || debug.scheddetail > 0 {
1622 schedtrace(true)
1623 }
1624 freezetheworld()
1625 return true
1626 case 1:
1627
1628
1629 gp.m.dying = 2
1630 print("panic during panic\n")
1631 return false
1632 case 2:
1633
1634
1635 gp.m.dying = 3
1636 print("stack trace unavailable\n")
1637 exit(4)
1638 fallthrough
1639 default:
1640
1641 exit(5)
1642 return false
1643 }
1644 }
1645
1646 var didothers bool
1647 var deadlock mutex
1648
1649
1650
1651
1652 func dopanic_m(gp *g, pc, sp uintptr, bubble *synctestBubble) bool {
1653 if gp.sig != 0 {
1654 signame := signame(gp.sig)
1655 if signame != "" {
1656 print("[signal ", signame)
1657 } else {
1658 print("[signal ", hex(gp.sig))
1659 }
1660 print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
1661 }
1662
1663 level, all, docrash := gotraceback()
1664 if level > 0 {
1665 if gp != gp.m.curg {
1666 all = true
1667 }
1668 if gp != gp.m.g0 {
1669 print("\n")
1670 goroutineheader(gp)
1671 traceback(pc, sp, 0, gp)
1672 } else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
1673 print("\nruntime stack:\n")
1674 traceback(pc, sp, 0, gp)
1675 }
1676 if !didothers {
1677 if all {
1678 didothers = true
1679 tracebackothers(gp)
1680 } else if bubble != nil {
1681
1682
1683 tracebacksomeothers(gp, func(other *g) bool {
1684 return bubble == other.bubble
1685 })
1686 }
1687 }
1688
1689 }
1690 unlock(&paniclk)
1691
1692 if panicking.Add(-1) != 0 {
1693
1694
1695
1696
1697 lock(&deadlock)
1698 lock(&deadlock)
1699 }
1700
1701 printDebugLog()
1702
1703 return docrash
1704 }
1705
1706
1707
1708
1709
1710 func canpanic() bool {
1711 gp := getg()
1712 mp := acquirem()
1713
1714
1715
1716
1717 if gp != mp.curg {
1718 releasem(mp)
1719 return false
1720 }
1721
1722 if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
1723 releasem(mp)
1724 return false
1725 }
1726 status := readgstatus(gp)
1727 if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
1728 releasem(mp)
1729 return false
1730 }
1731 if GOOS == "windows" && mp.libcallsp != 0 {
1732 releasem(mp)
1733 return false
1734 }
1735 releasem(mp)
1736 return true
1737 }
1738
1739
1740
1741
1742
1743
1744 func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
1745 if pc == 0 {
1746
1747
1748
1749
1750
1751 return false
1752 }
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762 if gp.m.incgo || findfunc(pc).valid() {
1763
1764
1765 return true
1766 }
1767 if findfunc(lr).valid() {
1768
1769
1770 return false
1771 }
1772
1773
1774 return true
1775 }
1776
1777
1778
1779
1780
1781
1782
1783
1784 func isAbortPC(pc uintptr) bool {
1785 f := findfunc(pc)
1786 if !f.valid() {
1787 return false
1788 }
1789 return f.funcID == abi.FuncID_abort
1790 }
1791
1792
1793
1794
1795
1796 func dumpPanicDeferState(where string, gp *g) {
1797 systemstack(func() {
1798 println("DUMPPANICDEFERSTATE", where)
1799 p := gp._panic
1800 d := gp._defer
1801 var u unwinder
1802 for u.init(gp, 0); u.valid(); u.next() {
1803
1804 println(" frame sp=", hex(u.frame.sp), "fp=", hex(u.frame.fp), "pc=", pcName(u.frame.pc), "+", pcOff(u.frame.pc))
1805
1806 for p != nil && uintptr(p.sp) == u.frame.sp {
1807 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))
1808 p = p.link
1809 }
1810
1811
1812 for d != nil && d.sp == u.frame.sp {
1813 println(" defer(link)", "heap=", d.heap, "rangefunc=", d.rangefunc, fnName(d.fn))
1814 d = d.link
1815 }
1816
1817
1818
1819
1820 fd := funcdata(u.frame.fn, abi.FUNCDATA_OpenCodedDeferInfo)
1821 if fd != nil {
1822 deferBitsOffset, fd := readvarintUnsafe(fd)
1823 m := *(*uint8)(unsafe.Pointer(u.frame.varp - uintptr(deferBitsOffset)))
1824 slotsOffset, fd := readvarintUnsafe(fd)
1825 slots := u.frame.varp - uintptr(slotsOffset)
1826 for i := 7; i >= 0; i-- {
1827 if m>>i&1 == 0 {
1828 continue
1829 }
1830 fn := *(*func())(unsafe.Pointer(slots + uintptr(i)*goarch.PtrSize))
1831 println(" defer(open)", fnName(fn))
1832 }
1833 }
1834
1835 }
1836 if p != nil {
1837 println(" REMAINING PANICS!", p)
1838 }
1839 if d != nil {
1840 println(" REMAINING DEFERS!")
1841 }
1842 })
1843 }
1844
1845 func pcName(pc uintptr) string {
1846 fn := findfunc(pc)
1847 if !fn.valid() {
1848 return "<unk>"
1849 }
1850 return funcname(fn)
1851 }
1852 func pcOff(pc uintptr) hex {
1853 fn := findfunc(pc)
1854 if !fn.valid() {
1855 return 0
1856 }
1857 return hex(pc - fn.entry())
1858 }
1859 func fnName(fn func()) string {
1860 return pcName(**(**uintptr)(unsafe.Pointer(&fn)))
1861 }
1862
View as plain text