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 p.gopanicFP = unsafe.Pointer(sys.GetCallerSP())
851
852 runningPanicDefers.Add(1)
853
854 p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
855 for {
856 fn, ok := p.nextDefer()
857 if !ok {
858 break
859 }
860 fn()
861 }
862
863
864
865
866
867
868
869 if traceEnabled() {
870 traceAdvance(false)
871 }
872
873
874
875
876
877 preprintpanics(&p)
878
879 fatalpanic(&p)
880 *(*int)(nil) = 0
881 }
882
883
884
885
886 func (p *_panic) start(pc uintptr, sp unsafe.Pointer) {
887 gp := getg()
888
889
890
891
892
893 p.startPC = sys.GetCallerPC()
894 p.startSP = unsafe.Pointer(sys.GetCallerSP())
895
896 if p.deferreturn {
897 p.sp = sp
898
899 if s := (*savedOpenDeferState)(gp.param); s != nil {
900
901
902
903 gp.param = nil
904
905 p.retpc = s.retpc
906 p.deferBitsPtr = (*byte)(add(sp, s.deferBitsOffset))
907 p.slotsPtr = add(sp, s.slotsOffset)
908 }
909
910 return
911 }
912
913 p.link = gp._panic
914 gp._panic = (*_panic)(noescape(unsafe.Pointer(p)))
915
916
917
918
919
920
921
922
923 p.pc, p.sp = pc, sp
924 p.nextFrame()
925 }
926
927
928
929
930
931 func (p *_panic) nextDefer() (func(), bool) {
932 gp := getg()
933
934 if !p.deferreturn {
935 if gp._panic != p {
936 throw("bad panic stack")
937 }
938
939 if p.recovered {
940 mcall(recovery)
941 throw("recovery failed")
942 }
943 }
944
945 for {
946 for p.deferBitsPtr != nil {
947 bits := *p.deferBitsPtr
948
949
950
951
952
953
954
955
956
957 if bits == 0 {
958 p.deferBitsPtr = nil
959 break
960 }
961
962
963 i := 7 - uintptr(sys.LeadingZeros8(bits))
964
965
966 bits &^= 1 << i
967 *p.deferBitsPtr = bits
968
969 return *(*func())(add(p.slotsPtr, i*goarch.PtrSize)), true
970 }
971
972 Recheck:
973 if d := gp._defer; d != nil && d.sp == uintptr(p.sp) {
974 if d.rangefunc {
975 deferconvert(d)
976 popDefer(gp)
977 goto Recheck
978 }
979
980 fn := d.fn
981
982 p.retpc = d.pc
983
984
985 popDefer(gp)
986
987 return fn, true
988 }
989
990 if !p.nextFrame() {
991 return nil, false
992 }
993 }
994 }
995
996
997 func (p *_panic) nextFrame() (ok bool) {
998 if p.pc == 0 {
999 return false
1000 }
1001
1002 gp := getg()
1003 systemstack(func() {
1004 var limit uintptr
1005 if d := gp._defer; d != nil {
1006 limit = d.sp
1007 }
1008
1009 var u unwinder
1010 u.initAt(p.pc, uintptr(p.sp), 0, gp, 0)
1011 for {
1012 if !u.valid() {
1013 p.pc = 0
1014 return
1015 }
1016
1017
1018
1019
1020
1021
1022 if u.frame.sp == limit {
1023 break
1024 }
1025
1026 if p.initOpenCodedDefers(u.frame.fn, unsafe.Pointer(u.frame.varp)) {
1027 break
1028 }
1029
1030 if p.link != nil && uintptr(u.frame.sp) == uintptr(p.link.startSP) && uintptr(p.link.sp) > u.frame.sp {
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041 u.initAt(p.link.pc, uintptr(p.link.sp), 0, gp, 0)
1042 continue
1043 }
1044
1045 u.next()
1046 }
1047
1048 p.pc = u.frame.pc
1049 p.sp = unsafe.Pointer(u.frame.sp)
1050 p.fp = unsafe.Pointer(u.frame.fp)
1051
1052 ok = true
1053 })
1054
1055 return
1056 }
1057
1058 func (p *_panic) initOpenCodedDefers(fn funcInfo, varp unsafe.Pointer) bool {
1059 fd := funcdata(fn, abi.FUNCDATA_OpenCodedDeferInfo)
1060 if fd == nil {
1061 return false
1062 }
1063
1064 if fn.deferreturn == 0 {
1065 throw("missing deferreturn")
1066 }
1067
1068 deferBitsOffset, fd := readvarintUnsafe(fd)
1069 deferBitsPtr := (*uint8)(add(varp, -uintptr(deferBitsOffset)))
1070 if *deferBitsPtr == 0 {
1071 return false
1072 }
1073
1074 slotsOffset, fd := readvarintUnsafe(fd)
1075
1076 p.retpc = fn.entry() + uintptr(fn.deferreturn)
1077 p.deferBitsPtr = deferBitsPtr
1078 p.slotsPtr = add(varp, -uintptr(slotsOffset))
1079
1080 return true
1081 }
1082
1083
1084 func gorecover() any {
1085 gp := getg()
1086 p := gp._panic
1087 if p == nil || p.goexit || p.recovered {
1088 return nil
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
1134 canRecover := false
1135 systemstack(func() {
1136 var u unwinder
1137 u.init(gp, 0)
1138 u.next()
1139 u.next()
1140 nonWrapperFrames := 0
1141 loop:
1142 for ; u.valid(); u.next() {
1143 for iu, f := newInlineUnwinder(u.frame.fn, u.symPC()); f.valid(); f = iu.next(f) {
1144 sf := iu.srcFunc(f)
1145 switch sf.funcID {
1146 case abi.FuncIDWrapper:
1147 continue
1148 case abi.FuncID_gopanic:
1149 if u.frame.fp == uintptr(p.gopanicFP) && nonWrapperFrames > 0 {
1150 canRecover = true
1151 }
1152 break loop
1153 default:
1154 nonWrapperFrames++
1155 if nonWrapperFrames > 1 {
1156 break loop
1157 }
1158 }
1159 }
1160 }
1161 })
1162 if !canRecover {
1163 return nil
1164 }
1165 p.recovered = true
1166 return p.arg
1167 }
1168
1169
1170 func sync_throw(s string) {
1171 throw(s)
1172 }
1173
1174
1175 func sync_fatal(s string) {
1176 fatal(s)
1177 }
1178
1179
1180 func rand_fatal(s string) {
1181 fatal(s)
1182 }
1183
1184
1185 func sysrand_fatal(s string) {
1186 fatal(s)
1187 }
1188
1189
1190 func fips_fatal(s string) {
1191 fatal(s)
1192 }
1193
1194
1195 func maps_fatal(s string) {
1196 fatal(s)
1197 }
1198
1199
1200 func internal_sync_throw(s string) {
1201 throw(s)
1202 }
1203
1204
1205 func internal_sync_fatal(s string) {
1206 fatal(s)
1207 }
1208
1209
1210 func cgroup_throw(s string) {
1211 throw(s)
1212 }
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235 func throw(s string) {
1236
1237
1238 systemstack(func() {
1239 print("fatal error: ")
1240 printindented(s)
1241 print("\n")
1242 })
1243
1244 fatalthrow(throwTypeRuntime)
1245 }
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256 func fatal(s string) {
1257 p := getg()._panic
1258
1259
1260 printlock()
1261 systemstack(func() {
1262 printPreFatalDeferPanic(p)
1263 print("fatal error: ")
1264 printindented(s)
1265 print("\n")
1266 })
1267
1268 fatalthrow(throwTypeUser)
1269 printunlock()
1270 }
1271
1272
1273
1274 func printPreFatalDeferPanic(p *_panic) {
1275
1276
1277
1278
1279 for x := p; x != nil; x = x.link {
1280 if x.link != nil && *efaceOf(&x.link.arg) == *efaceOf(&x.arg) {
1281
1282
1283 x.link.repanicked = true
1284 }
1285 }
1286 if p != nil {
1287 printpanics(p)
1288
1289 print("\t")
1290 }
1291 }
1292
1293
1294
1295 var runningPanicDefers atomic.Uint32
1296
1297
1298 var panicking atomic.Uint32
1299
1300
1301
1302 var paniclk mutex
1303
1304
1305
1306
1307
1308
1309
1310
1311 func recovery(gp *g) {
1312 p := gp._panic
1313 pc, sp, fp := p.retpc, uintptr(p.sp), uintptr(p.fp)
1314 p0, saveOpenDeferState := p, p.deferBitsPtr != nil && *p.deferBitsPtr != 0
1315
1316
1317
1318
1319 f := findfunc(pc)
1320 if f.deferreturn == 0 {
1321 throw("no deferreturn")
1322 }
1323 gotoPc := f.entry() + uintptr(f.deferreturn)
1324
1325
1326 for ; p != nil && uintptr(p.startSP) < sp; p = p.link {
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346 if p.goexit {
1347 gotoPc, sp = p.startPC, uintptr(p.startSP)
1348 saveOpenDeferState = false
1349 break
1350 }
1351
1352 runningPanicDefers.Add(-1)
1353 }
1354 gp._panic = p
1355
1356 if p == nil {
1357 gp.sig = 0
1358 }
1359
1360 if gp.param != nil {
1361 throw("unexpected gp.param")
1362 }
1363 if saveOpenDeferState {
1364
1365
1366
1367 gp.param = unsafe.Pointer(&savedOpenDeferState{
1368 retpc: p0.retpc,
1369
1370
1371
1372
1373 deferBitsOffset: uintptr(unsafe.Pointer(p0.deferBitsPtr)) - uintptr(p0.sp),
1374 slotsOffset: uintptr(p0.slotsPtr) - uintptr(p0.sp),
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
1403 if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
1404 print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
1405 throw("bad recovery")
1406 }
1407
1408
1409 gp.sched.sp = sp
1410 gp.sched.pc = gotoPc
1411 gp.sched.lr = 0
1412
1413
1414
1415 switch {
1416 case goarch.IsAmd64 != 0:
1417
1418
1419
1420 gp.sched.bp = fp - 2*goarch.PtrSize
1421 case goarch.IsArm64 != 0:
1422
1423
1424
1425 gp.sched.bp = sp - goarch.PtrSize
1426 }
1427 gogo(&gp.sched)
1428 }
1429
1430
1431
1432
1433
1434
1435 func fatalthrow(t throwType) {
1436 pc := sys.GetCallerPC()
1437 sp := sys.GetCallerSP()
1438 gp := getg()
1439
1440 if gp.m.throwing == throwTypeNone {
1441 gp.m.throwing = t
1442 }
1443
1444
1445
1446 systemstack(func() {
1447 if isSecureMode() {
1448 exit(2)
1449 }
1450
1451 startpanic_m()
1452
1453 if dopanic_m(gp, pc, sp, nil) {
1454
1455
1456
1457 crash()
1458 }
1459
1460 exit(2)
1461 })
1462
1463 *(*int)(nil) = 0
1464 }
1465
1466
1467
1468
1469
1470
1471 func fatalpanic(msgs *_panic) {
1472 pc := sys.GetCallerPC()
1473 sp := sys.GetCallerSP()
1474 gp := getg()
1475 var docrash bool
1476
1477
1478 systemstack(func() {
1479 if startpanic_m() && msgs != nil {
1480
1481
1482
1483
1484
1485
1486 runningPanicDefers.Add(-1)
1487
1488 printpanics(msgs)
1489 }
1490
1491
1492
1493 var bubble *synctestBubble
1494 if de, ok := msgs.arg.(synctestDeadlockError); ok {
1495 bubble = de.bubble
1496 }
1497
1498 docrash = dopanic_m(gp, pc, sp, bubble)
1499 })
1500
1501 if docrash {
1502
1503
1504
1505 crash()
1506 }
1507
1508 systemstack(func() {
1509 exit(2)
1510 })
1511
1512 *(*int)(nil) = 0
1513 }
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527 func startpanic_m() bool {
1528 gp := getg()
1529 if mheap_.cachealloc.size == 0 {
1530 print("runtime: panic before malloc heap initialized\n")
1531 }
1532
1533
1534
1535
1536 gp.m.mallocing++
1537
1538
1539
1540 if gp.m.locks < 0 {
1541 gp.m.locks = 1
1542 }
1543
1544 switch gp.m.dying {
1545 case 0:
1546
1547 gp.m.dying = 1
1548 panicking.Add(1)
1549 lock(&paniclk)
1550 if debug.schedtrace > 0 || debug.scheddetail > 0 {
1551 schedtrace(true)
1552 }
1553 freezetheworld()
1554 return true
1555 case 1:
1556
1557
1558 gp.m.dying = 2
1559 print("panic during panic\n")
1560 return false
1561 case 2:
1562
1563
1564 gp.m.dying = 3
1565 print("stack trace unavailable\n")
1566 exit(4)
1567 fallthrough
1568 default:
1569
1570 exit(5)
1571 return false
1572 }
1573 }
1574
1575 var didothers bool
1576 var deadlock mutex
1577
1578
1579
1580
1581 func dopanic_m(gp *g, pc, sp uintptr, bubble *synctestBubble) bool {
1582 if gp.sig != 0 {
1583 signame := signame(gp.sig)
1584 if signame != "" {
1585 print("[signal ", signame)
1586 } else {
1587 print("[signal ", hex(gp.sig))
1588 }
1589 print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
1590 }
1591
1592 level, all, docrash := gotraceback()
1593 if level > 0 {
1594 if gp != gp.m.curg {
1595 all = true
1596 }
1597 if gp != gp.m.g0 {
1598 print("\n")
1599 goroutineheader(gp)
1600 traceback(pc, sp, 0, gp)
1601 } else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
1602 print("\nruntime stack:\n")
1603 traceback(pc, sp, 0, gp)
1604 }
1605 if !didothers {
1606 if all {
1607 didothers = true
1608 tracebackothers(gp)
1609 } else if bubble != nil {
1610
1611
1612 tracebacksomeothers(gp, func(other *g) bool {
1613 return bubble == other.bubble
1614 })
1615 }
1616 }
1617
1618 }
1619 unlock(&paniclk)
1620
1621 if panicking.Add(-1) != 0 {
1622
1623
1624
1625
1626 lock(&deadlock)
1627 lock(&deadlock)
1628 }
1629
1630 printDebugLog()
1631
1632 return docrash
1633 }
1634
1635
1636
1637
1638
1639 func canpanic() bool {
1640 gp := getg()
1641 mp := acquirem()
1642
1643
1644
1645
1646 if gp != mp.curg {
1647 releasem(mp)
1648 return false
1649 }
1650
1651 if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
1652 releasem(mp)
1653 return false
1654 }
1655 status := readgstatus(gp)
1656 if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
1657 releasem(mp)
1658 return false
1659 }
1660 if GOOS == "windows" && mp.libcallsp != 0 {
1661 releasem(mp)
1662 return false
1663 }
1664 releasem(mp)
1665 return true
1666 }
1667
1668
1669
1670
1671
1672
1673 func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
1674 if pc == 0 {
1675
1676
1677
1678
1679
1680 return false
1681 }
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691 if gp.m.incgo || findfunc(pc).valid() {
1692
1693
1694 return true
1695 }
1696 if findfunc(lr).valid() {
1697
1698
1699 return false
1700 }
1701
1702
1703 return true
1704 }
1705
1706
1707
1708
1709
1710
1711
1712
1713 func isAbortPC(pc uintptr) bool {
1714 f := findfunc(pc)
1715 if !f.valid() {
1716 return false
1717 }
1718 return f.funcID == abi.FuncID_abort
1719 }
1720
1721
1722
1723
1724 func dumpPanicDeferState(where string, gp *g) {
1725 systemstack(func() {
1726 println("DUMPPANICDEFERSTATE", where)
1727 p := gp._panic
1728 d := gp._defer
1729 var u unwinder
1730 for u.init(gp, 0); u.valid(); u.next() {
1731
1732 println(" frame sp=", hex(u.frame.sp), "fp=", hex(u.frame.fp), "pc=", pcName(u.frame.pc), "+", pcOff(u.frame.pc))
1733
1734 for p != nil && uintptr(p.sp) == u.frame.sp {
1735 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, "gopanicfp=", p.gopanicFP, "startPC=", hex(p.startPC), pcName(p.startPC), "+", pcOff(p.startPC))
1736 p = p.link
1737 }
1738
1739
1740 for d != nil && d.sp == u.frame.sp {
1741 println(" defer(link)", "heap=", d.heap, "rangefunc=", d.rangefunc, fnName(d.fn))
1742 d = d.link
1743 }
1744
1745
1746
1747
1748 fd := funcdata(u.frame.fn, abi.FUNCDATA_OpenCodedDeferInfo)
1749 if fd != nil {
1750 deferBitsOffset, fd := readvarintUnsafe(fd)
1751 m := *(*uint8)(unsafe.Pointer(u.frame.varp - uintptr(deferBitsOffset)))
1752 slotsOffset, fd := readvarintUnsafe(fd)
1753 slots := u.frame.varp - uintptr(slotsOffset)
1754 for i := 7; i >= 0; i-- {
1755 if m>>i&1 == 0 {
1756 continue
1757 }
1758 fn := *(*func())(unsafe.Pointer(slots + uintptr(i)*goarch.PtrSize))
1759 println(" defer(open)", fnName(fn))
1760 }
1761 }
1762
1763 }
1764 if p != nil {
1765 println(" REMAINING PANICS!", p)
1766 }
1767 if d != nil {
1768 println(" REMAINING DEFERS!")
1769 }
1770 })
1771 }
1772
1773 func pcName(pc uintptr) string {
1774 fn := findfunc(pc)
1775 if !fn.valid() {
1776 return "<unk>"
1777 }
1778 return funcname(fn)
1779 }
1780 func pcOff(pc uintptr) hex {
1781 fn := findfunc(pc)
1782 if !fn.valid() {
1783 return 0
1784 }
1785 return hex(pc - fn.entry())
1786 }
1787 func fnName(fn func()) string {
1788 return pcName(**(**uintptr)(unsafe.Pointer(&fn)))
1789 }
1790
View as plain text