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.lr, p.fp = 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.lr == 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.lr, uintptr(p.fp), 0, gp, 0)
1011 for {
1012 if !u.valid() {
1013 p.lr = 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 u.next()
1031 }
1032
1033 p.lr = u.frame.lr
1034 p.sp = unsafe.Pointer(u.frame.sp)
1035 p.fp = unsafe.Pointer(u.frame.fp)
1036
1037 ok = true
1038 })
1039
1040 return
1041 }
1042
1043 func (p *_panic) initOpenCodedDefers(fn funcInfo, varp unsafe.Pointer) bool {
1044 fd := funcdata(fn, abi.FUNCDATA_OpenCodedDeferInfo)
1045 if fd == nil {
1046 return false
1047 }
1048
1049 if fn.deferreturn == 0 {
1050 throw("missing deferreturn")
1051 }
1052
1053 deferBitsOffset, fd := readvarintUnsafe(fd)
1054 deferBitsPtr := (*uint8)(add(varp, -uintptr(deferBitsOffset)))
1055 if *deferBitsPtr == 0 {
1056 return false
1057 }
1058
1059 slotsOffset, fd := readvarintUnsafe(fd)
1060
1061 p.retpc = fn.entry() + uintptr(fn.deferreturn)
1062 p.deferBitsPtr = deferBitsPtr
1063 p.slotsPtr = add(varp, -uintptr(slotsOffset))
1064
1065 return true
1066 }
1067
1068
1069 func gorecover() any {
1070 gp := getg()
1071 p := gp._panic
1072 if p == nil || p.goexit || p.recovered {
1073 return nil
1074 }
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
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 canRecover := false
1120 systemstack(func() {
1121 var u unwinder
1122 u.init(gp, 0)
1123 u.next()
1124 u.next()
1125 nonWrapperFrames := 0
1126 loop:
1127 for ; u.valid(); u.next() {
1128 for iu, f := newInlineUnwinder(u.frame.fn, u.symPC()); f.valid(); f = iu.next(f) {
1129 sf := iu.srcFunc(f)
1130 switch sf.funcID {
1131 case abi.FuncIDWrapper:
1132 continue
1133 case abi.FuncID_gopanic:
1134 if u.frame.fp == uintptr(p.gopanicFP) && nonWrapperFrames > 0 {
1135 canRecover = true
1136 }
1137 break loop
1138 default:
1139 nonWrapperFrames++
1140 if nonWrapperFrames > 1 {
1141 break loop
1142 }
1143 }
1144 }
1145 }
1146 })
1147 if !canRecover {
1148 return nil
1149 }
1150 p.recovered = true
1151 return p.arg
1152 }
1153
1154
1155 func sync_throw(s string) {
1156 throw(s)
1157 }
1158
1159
1160 func sync_fatal(s string) {
1161 fatal(s)
1162 }
1163
1164
1165 func rand_fatal(s string) {
1166 fatal(s)
1167 }
1168
1169
1170 func sysrand_fatal(s string) {
1171 fatal(s)
1172 }
1173
1174
1175 func fips_fatal(s string) {
1176 fatal(s)
1177 }
1178
1179
1180 func maps_fatal(s string) {
1181 fatal(s)
1182 }
1183
1184
1185 func internal_sync_throw(s string) {
1186 throw(s)
1187 }
1188
1189
1190 func internal_sync_fatal(s string) {
1191 fatal(s)
1192 }
1193
1194
1195 func cgroup_throw(s string) {
1196 throw(s)
1197 }
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 func throw(s string) {
1221
1222
1223 systemstack(func() {
1224 print("fatal error: ")
1225 printindented(s)
1226 print("\n")
1227 })
1228
1229 fatalthrow(throwTypeRuntime)
1230 }
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241 func fatal(s string) {
1242 p := getg()._panic
1243
1244
1245 printlock()
1246 systemstack(func() {
1247 printPreFatalDeferPanic(p)
1248 print("fatal error: ")
1249 printindented(s)
1250 print("\n")
1251 })
1252
1253 fatalthrow(throwTypeUser)
1254 printunlock()
1255 }
1256
1257
1258
1259 func printPreFatalDeferPanic(p *_panic) {
1260
1261
1262
1263
1264 for x := p; x != nil; x = x.link {
1265 if x.link != nil && *efaceOf(&x.link.arg) == *efaceOf(&x.arg) {
1266
1267
1268 x.link.repanicked = true
1269 }
1270 }
1271 if p != nil {
1272 printpanics(p)
1273
1274 print("\t")
1275 }
1276 }
1277
1278
1279
1280 var runningPanicDefers atomic.Uint32
1281
1282
1283 var panicking atomic.Uint32
1284
1285
1286
1287 var paniclk mutex
1288
1289
1290
1291
1292
1293
1294
1295
1296 func recovery(gp *g) {
1297 p := gp._panic
1298 pc, sp, fp := p.retpc, uintptr(p.sp), uintptr(p.fp)
1299 p0, saveOpenDeferState := p, p.deferBitsPtr != nil && *p.deferBitsPtr != 0
1300
1301
1302
1303
1304 f := findfunc(pc)
1305 if f.deferreturn == 0 {
1306 throw("no deferreturn")
1307 }
1308 gotoPc := f.entry() + uintptr(f.deferreturn)
1309
1310
1311 for ; p != nil && uintptr(p.startSP) < sp; p = p.link {
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331 if p.goexit {
1332 gotoPc, sp = p.startPC, uintptr(p.startSP)
1333 saveOpenDeferState = false
1334 break
1335 }
1336
1337 runningPanicDefers.Add(-1)
1338 }
1339 gp._panic = p
1340
1341 if p == nil {
1342 gp.sig = 0
1343 }
1344
1345 if gp.param != nil {
1346 throw("unexpected gp.param")
1347 }
1348 if saveOpenDeferState {
1349
1350
1351
1352 gp.param = unsafe.Pointer(&savedOpenDeferState{
1353 retpc: p0.retpc,
1354
1355
1356
1357
1358 deferBitsOffset: uintptr(unsafe.Pointer(p0.deferBitsPtr)) - uintptr(p0.sp),
1359 slotsOffset: uintptr(p0.slotsPtr) - uintptr(p0.sp),
1360 })
1361 }
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388 if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
1389 print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
1390 throw("bad recovery")
1391 }
1392
1393
1394 gp.sched.sp = sp
1395 gp.sched.pc = gotoPc
1396 gp.sched.lr = 0
1397
1398
1399
1400 switch {
1401 case goarch.IsAmd64 != 0:
1402
1403
1404
1405 gp.sched.bp = fp - 2*goarch.PtrSize
1406 case goarch.IsArm64 != 0:
1407
1408
1409
1410 gp.sched.bp = sp - goarch.PtrSize
1411 }
1412 gogo(&gp.sched)
1413 }
1414
1415
1416
1417
1418
1419
1420 func fatalthrow(t throwType) {
1421 pc := sys.GetCallerPC()
1422 sp := sys.GetCallerSP()
1423 gp := getg()
1424
1425 if gp.m.throwing == throwTypeNone {
1426 gp.m.throwing = t
1427 }
1428
1429
1430
1431 systemstack(func() {
1432 if isSecureMode() {
1433 exit(2)
1434 }
1435
1436 startpanic_m()
1437
1438 if dopanic_m(gp, pc, sp, nil) {
1439
1440
1441
1442 crash()
1443 }
1444
1445 exit(2)
1446 })
1447
1448 *(*int)(nil) = 0
1449 }
1450
1451
1452
1453
1454
1455
1456 func fatalpanic(msgs *_panic) {
1457 pc := sys.GetCallerPC()
1458 sp := sys.GetCallerSP()
1459 gp := getg()
1460 var docrash bool
1461
1462
1463 systemstack(func() {
1464 if startpanic_m() && msgs != nil {
1465
1466
1467
1468
1469
1470
1471 runningPanicDefers.Add(-1)
1472
1473 printpanics(msgs)
1474 }
1475
1476
1477
1478 var bubble *synctestBubble
1479 if de, ok := msgs.arg.(synctestDeadlockError); ok {
1480 bubble = de.bubble
1481 }
1482
1483 docrash = dopanic_m(gp, pc, sp, bubble)
1484 })
1485
1486 if docrash {
1487
1488
1489
1490 crash()
1491 }
1492
1493 systemstack(func() {
1494 exit(2)
1495 })
1496
1497 *(*int)(nil) = 0
1498 }
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512 func startpanic_m() bool {
1513 gp := getg()
1514 if mheap_.cachealloc.size == 0 {
1515 print("runtime: panic before malloc heap initialized\n")
1516 }
1517
1518
1519
1520
1521 gp.m.mallocing++
1522
1523
1524
1525 if gp.m.locks < 0 {
1526 gp.m.locks = 1
1527 }
1528
1529 switch gp.m.dying {
1530 case 0:
1531
1532 gp.m.dying = 1
1533 panicking.Add(1)
1534 lock(&paniclk)
1535 if debug.schedtrace > 0 || debug.scheddetail > 0 {
1536 schedtrace(true)
1537 }
1538 freezetheworld()
1539 return true
1540 case 1:
1541
1542
1543 gp.m.dying = 2
1544 print("panic during panic\n")
1545 return false
1546 case 2:
1547
1548
1549 gp.m.dying = 3
1550 print("stack trace unavailable\n")
1551 exit(4)
1552 fallthrough
1553 default:
1554
1555 exit(5)
1556 return false
1557 }
1558 }
1559
1560 var didothers bool
1561 var deadlock mutex
1562
1563
1564
1565
1566 func dopanic_m(gp *g, pc, sp uintptr, bubble *synctestBubble) bool {
1567 if gp.sig != 0 {
1568 signame := signame(gp.sig)
1569 if signame != "" {
1570 print("[signal ", signame)
1571 } else {
1572 print("[signal ", hex(gp.sig))
1573 }
1574 print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
1575 }
1576
1577 level, all, docrash := gotraceback()
1578 if level > 0 {
1579 if gp != gp.m.curg {
1580 all = true
1581 }
1582 if gp != gp.m.g0 {
1583 print("\n")
1584 goroutineheader(gp)
1585 traceback(pc, sp, 0, gp)
1586 } else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
1587 print("\nruntime stack:\n")
1588 traceback(pc, sp, 0, gp)
1589 }
1590 if !didothers {
1591 if all {
1592 didothers = true
1593 tracebackothers(gp)
1594 } else if bubble != nil {
1595
1596
1597 tracebacksomeothers(gp, func(other *g) bool {
1598 return bubble == other.bubble
1599 })
1600 }
1601 }
1602
1603 }
1604 unlock(&paniclk)
1605
1606 if panicking.Add(-1) != 0 {
1607
1608
1609
1610
1611 lock(&deadlock)
1612 lock(&deadlock)
1613 }
1614
1615 printDebugLog()
1616
1617 return docrash
1618 }
1619
1620
1621
1622
1623
1624 func canpanic() bool {
1625 gp := getg()
1626 mp := acquirem()
1627
1628
1629
1630
1631 if gp != mp.curg {
1632 releasem(mp)
1633 return false
1634 }
1635
1636 if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
1637 releasem(mp)
1638 return false
1639 }
1640 status := readgstatus(gp)
1641 if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
1642 releasem(mp)
1643 return false
1644 }
1645 if GOOS == "windows" && mp.libcallsp != 0 {
1646 releasem(mp)
1647 return false
1648 }
1649 releasem(mp)
1650 return true
1651 }
1652
1653
1654
1655
1656
1657
1658 func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
1659 if pc == 0 {
1660
1661
1662
1663
1664
1665 return false
1666 }
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676 if gp.m.incgo || findfunc(pc).valid() {
1677
1678
1679 return true
1680 }
1681 if findfunc(lr).valid() {
1682
1683
1684 return false
1685 }
1686
1687
1688 return true
1689 }
1690
1691
1692
1693
1694
1695
1696
1697
1698 func isAbortPC(pc uintptr) bool {
1699 f := findfunc(pc)
1700 if !f.valid() {
1701 return false
1702 }
1703 return f.funcID == abi.FuncID_abort
1704 }
1705
View as plain text