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 = unsafe.Pointer(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 gp := getg()
1087 p := gp._panic
1088 if p == nil || p.goexit || p.recovered {
1089 return nil
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
1135 canRecover := false
1136 systemstack(func() {
1137 var u unwinder
1138 u.init(gp, 0)
1139 u.next()
1140 u.next()
1141 nonWrapperFrames := 0
1142 loop:
1143 for ; u.valid(); u.next() {
1144 for iu, f := newInlineUnwinder(u.frame.fn, u.symPC()); f.valid(); f = iu.next(f) {
1145 sf := iu.srcFunc(f)
1146 switch sf.funcID {
1147 case abi.FuncIDWrapper:
1148 continue
1149 case abi.FuncID_gopanic:
1150 if u.frame.sp == uintptr(p.startSP) && nonWrapperFrames > 0 {
1151 canRecover = true
1152 }
1153 break loop
1154 default:
1155 nonWrapperFrames++
1156 if nonWrapperFrames > 1 {
1157 break loop
1158 }
1159 }
1160 }
1161 }
1162 })
1163 if !canRecover {
1164 return nil
1165 }
1166 p.recovered = true
1167 return p.arg
1168 }
1169
1170
1171 func sync_throw(s string) {
1172 throw(s)
1173 }
1174
1175
1176 func sync_fatal(s string) {
1177 fatal(s)
1178 }
1179
1180
1181 func rand_fatal(s string) {
1182 fatal(s)
1183 }
1184
1185
1186 func sysrand_fatal(s string) {
1187 fatal(s)
1188 }
1189
1190
1191 func fips_fatal(s string) {
1192 fatal(s)
1193 }
1194
1195
1196 func maps_fatal(s string) {
1197 fatal(s)
1198 }
1199
1200
1201 func internal_sync_throw(s string) {
1202 throw(s)
1203 }
1204
1205
1206 func internal_sync_fatal(s string) {
1207 fatal(s)
1208 }
1209
1210
1211 func cgroup_throw(s string) {
1212 throw(s)
1213 }
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236 func throw(s string) {
1237
1238
1239 systemstack(func() {
1240 print("fatal error: ")
1241 printindented(s)
1242 print("\n")
1243 })
1244
1245 fatalthrow(throwTypeRuntime)
1246 }
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257 func fatal(s string) {
1258 p := getg()._panic
1259
1260
1261 printlock()
1262 systemstack(func() {
1263 printPreFatalDeferPanic(p)
1264 print("fatal error: ")
1265 printindented(s)
1266 print("\n")
1267 })
1268
1269 fatalthrow(throwTypeUser)
1270 printunlock()
1271 }
1272
1273
1274
1275 func printPreFatalDeferPanic(p *_panic) {
1276
1277
1278
1279
1280 for x := p; x != nil; x = x.link {
1281 if x.link != nil && *efaceOf(&x.link.arg) == *efaceOf(&x.arg) {
1282
1283
1284 x.link.repanicked = true
1285 }
1286 }
1287 if p != nil {
1288 printpanics(p)
1289
1290 print("\t")
1291 }
1292 }
1293
1294
1295
1296 var runningPanicDefers atomic.Uint32
1297
1298
1299 var panicking atomic.Uint32
1300
1301
1302
1303 var paniclk mutex
1304
1305
1306
1307
1308
1309
1310
1311
1312 func recovery(gp *g) {
1313 p := gp._panic
1314 pc, sp, fp := p.retpc, uintptr(p.sp), uintptr(p.fp)
1315 p0, saveOpenDeferState := p, p.deferBitsPtr != nil && *p.deferBitsPtr != 0
1316
1317
1318
1319
1320 f := findfunc(pc)
1321 if f.deferreturn == 0 {
1322 throw("no deferreturn")
1323 }
1324 gotoPc := f.entry() + uintptr(f.deferreturn)
1325
1326
1327 for ; p != nil && uintptr(p.startSP) < sp; p = p.link {
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347 if p.goexit {
1348 gotoPc, sp = p.startPC, uintptr(p.startSP)
1349 saveOpenDeferState = false
1350 break
1351 }
1352
1353 runningPanicDefers.Add(-1)
1354 }
1355 gp._panic = p
1356
1357 if p == nil {
1358 gp.sig = 0
1359 }
1360
1361 if gp.param != nil {
1362 throw("unexpected gp.param")
1363 }
1364 if saveOpenDeferState {
1365
1366
1367
1368 gp.param = unsafe.Pointer(&savedOpenDeferState{
1369 retpc: p0.retpc,
1370
1371
1372
1373
1374 deferBitsOffset: uintptr(unsafe.Pointer(p0.deferBitsPtr)) - uintptr(p0.sp),
1375 slotsOffset: uintptr(p0.slotsPtr) - uintptr(p0.sp),
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
1404 if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
1405 print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
1406 throw("bad recovery")
1407 }
1408
1409
1410 gp.sched.sp = sp
1411 gp.sched.pc = gotoPc
1412 gp.sched.lr = 0
1413
1414
1415
1416 switch {
1417 case goarch.IsAmd64 != 0:
1418
1419
1420
1421 gp.sched.bp = fp - 2*goarch.PtrSize
1422 case goarch.IsArm64 != 0:
1423
1424
1425
1426 gp.sched.bp = sp - goarch.PtrSize
1427 }
1428 gogo(&gp.sched)
1429 }
1430
1431
1432
1433
1434
1435
1436 func fatalthrow(t throwType) {
1437 pc := sys.GetCallerPC()
1438 sp := sys.GetCallerSP()
1439 gp := getg()
1440
1441 if gp.m.throwing == throwTypeNone {
1442 gp.m.throwing = t
1443 }
1444
1445
1446
1447 systemstack(func() {
1448 if isSecureMode() {
1449 exit(2)
1450 }
1451
1452 startpanic_m()
1453
1454 if dopanic_m(gp, pc, sp, nil) {
1455
1456
1457
1458 crash()
1459 }
1460
1461 exit(2)
1462 })
1463
1464 *(*int)(nil) = 0
1465 }
1466
1467
1468
1469
1470
1471
1472 func fatalpanic(msgs *_panic) {
1473 pc := sys.GetCallerPC()
1474 sp := sys.GetCallerSP()
1475 gp := getg()
1476 var docrash bool
1477
1478
1479 systemstack(func() {
1480 if startpanic_m() && msgs != nil {
1481
1482
1483
1484
1485
1486
1487 runningPanicDefers.Add(-1)
1488
1489 printpanics(msgs)
1490 }
1491
1492
1493
1494 var bubble *synctestBubble
1495 if de, ok := msgs.arg.(synctestDeadlockError); ok {
1496 bubble = de.bubble
1497 }
1498
1499 docrash = dopanic_m(gp, pc, sp, bubble)
1500 })
1501
1502 if docrash {
1503
1504
1505
1506 crash()
1507 }
1508
1509 systemstack(func() {
1510 exit(2)
1511 })
1512
1513 *(*int)(nil) = 0
1514 }
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528 func startpanic_m() bool {
1529 gp := getg()
1530 if mheap_.cachealloc.size == 0 {
1531 print("runtime: panic before malloc heap initialized\n")
1532 }
1533
1534
1535
1536
1537 gp.m.mallocing++
1538
1539
1540
1541 if gp.m.locks < 0 {
1542 gp.m.locks = 1
1543 }
1544
1545 switch gp.m.dying {
1546 case 0:
1547
1548 gp.m.dying = 1
1549 panicking.Add(1)
1550 lock(&paniclk)
1551 if debug.schedtrace > 0 || debug.scheddetail > 0 {
1552 schedtrace(true)
1553 }
1554 freezetheworld()
1555 return true
1556 case 1:
1557
1558
1559 gp.m.dying = 2
1560 print("panic during panic\n")
1561 return false
1562 case 2:
1563
1564
1565 gp.m.dying = 3
1566 print("stack trace unavailable\n")
1567 exit(4)
1568 fallthrough
1569 default:
1570
1571 exit(5)
1572 return false
1573 }
1574 }
1575
1576 var didothers bool
1577 var deadlock mutex
1578
1579
1580
1581
1582 func dopanic_m(gp *g, pc, sp uintptr, bubble *synctestBubble) bool {
1583 if gp.sig != 0 {
1584 signame := signame(gp.sig)
1585 if signame != "" {
1586 print("[signal ", signame)
1587 } else {
1588 print("[signal ", hex(gp.sig))
1589 }
1590 print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
1591 }
1592
1593 level, all, docrash := gotraceback()
1594 if level > 0 {
1595 if gp != gp.m.curg {
1596 all = true
1597 }
1598 if gp != gp.m.g0 {
1599 print("\n")
1600 goroutineheader(gp)
1601 traceback(pc, sp, 0, gp)
1602 } else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
1603 print("\nruntime stack:\n")
1604 traceback(pc, sp, 0, gp)
1605 }
1606 if !didothers {
1607 if all {
1608 didothers = true
1609 tracebackothers(gp)
1610 } else if bubble != nil {
1611
1612
1613 tracebacksomeothers(gp, func(other *g) bool {
1614 return bubble == other.bubble
1615 })
1616 }
1617 }
1618
1619 }
1620 unlock(&paniclk)
1621
1622 if panicking.Add(-1) != 0 {
1623
1624
1625
1626
1627 lock(&deadlock)
1628 lock(&deadlock)
1629 }
1630
1631 printDebugLog()
1632
1633 return docrash
1634 }
1635
1636
1637
1638
1639
1640 func canpanic() bool {
1641 gp := getg()
1642 mp := acquirem()
1643
1644
1645
1646
1647 if gp != mp.curg {
1648 releasem(mp)
1649 return false
1650 }
1651
1652 if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
1653 releasem(mp)
1654 return false
1655 }
1656 status := readgstatus(gp)
1657 if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
1658 releasem(mp)
1659 return false
1660 }
1661 if GOOS == "windows" && mp.libcallsp != 0 {
1662 releasem(mp)
1663 return false
1664 }
1665 releasem(mp)
1666 return true
1667 }
1668
1669
1670
1671
1672
1673
1674 func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
1675 if pc == 0 {
1676
1677
1678
1679
1680
1681 return false
1682 }
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692 if gp.m.incgo || findfunc(pc).valid() {
1693
1694
1695 return true
1696 }
1697 if findfunc(lr).valid() {
1698
1699
1700 return false
1701 }
1702
1703
1704 return true
1705 }
1706
1707
1708
1709
1710
1711
1712
1713
1714 func isAbortPC(pc uintptr) bool {
1715 f := findfunc(pc)
1716 if !f.valid() {
1717 return false
1718 }
1719 return f.funcID == abi.FuncID_abort
1720 }
1721
1722
1723
1724
1725
1726 func dumpPanicDeferState(where string, gp *g) {
1727 systemstack(func() {
1728 println("DUMPPANICDEFERSTATE", where)
1729 p := gp._panic
1730 d := gp._defer
1731 var u unwinder
1732 for u.init(gp, 0); u.valid(); u.next() {
1733
1734 println(" frame sp=", hex(u.frame.sp), "fp=", hex(u.frame.fp), "pc=", pcName(u.frame.pc), "+", pcOff(u.frame.pc))
1735
1736 for p != nil && uintptr(p.sp) == u.frame.sp {
1737 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))
1738 p = p.link
1739 }
1740
1741
1742 for d != nil && d.sp == u.frame.sp {
1743 println(" defer(link)", "heap=", d.heap, "rangefunc=", d.rangefunc, fnName(d.fn))
1744 d = d.link
1745 }
1746
1747
1748
1749
1750 fd := funcdata(u.frame.fn, abi.FUNCDATA_OpenCodedDeferInfo)
1751 if fd != nil {
1752 deferBitsOffset, fd := readvarintUnsafe(fd)
1753 m := *(*uint8)(unsafe.Pointer(u.frame.varp - uintptr(deferBitsOffset)))
1754 slotsOffset, fd := readvarintUnsafe(fd)
1755 slots := u.frame.varp - uintptr(slotsOffset)
1756 for i := 7; i >= 0; i-- {
1757 if m>>i&1 == 0 {
1758 continue
1759 }
1760 fn := *(*func())(unsafe.Pointer(slots + uintptr(i)*goarch.PtrSize))
1761 println(" defer(open)", fnName(fn))
1762 }
1763 }
1764
1765 }
1766 if p != nil {
1767 println(" REMAINING PANICS!", p)
1768 }
1769 if d != nil {
1770 println(" REMAINING DEFERS!")
1771 }
1772 })
1773 }
1774
1775 func pcName(pc uintptr) string {
1776 fn := findfunc(pc)
1777 if !fn.valid() {
1778 return "<unk>"
1779 }
1780 return funcname(fn)
1781 }
1782 func pcOff(pc uintptr) hex {
1783 fn := findfunc(pc)
1784 if !fn.valid() {
1785 return 0
1786 }
1787 return hex(pc - fn.entry())
1788 }
1789 func fnName(fn func()) string {
1790 return pcName(**(**uintptr)(unsafe.Pointer(&fn)))
1791 }
1792
View as plain text