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
345
346 func deferproc(fn func()) {
347 gp := getg()
348 if gp.m.curg != gp {
349
350 throw("defer on system stack")
351 }
352
353 d := newdefer()
354 d.link = gp._defer
355 gp._defer = d
356 d.fn = fn
357
358
359
360 d.sp = sys.GetCallerSP()
361 }
362
363 var rangeDoneError = error(errorString("range function continued iteration after function for loop body returned false"))
364 var rangePanicError = error(errorString("range function continued iteration after loop body panic"))
365 var rangeExhaustedError = error(errorString("range function continued iteration after whole loop exit"))
366 var rangeMissingPanicError = error(errorString("range function recovered a loop body panic and did not resume panicking"))
367
368
369 func panicrangestate(state int) {
370 switch abi.RF_State(state) {
371 case abi.RF_DONE:
372 panic(rangeDoneError)
373 case abi.RF_PANIC:
374 panic(rangePanicError)
375 case abi.RF_EXHAUSTED:
376 panic(rangeExhaustedError)
377 case abi.RF_MISSING_PANIC:
378 panic(rangeMissingPanicError)
379 }
380 throw("unexpected state passed to panicrangestate")
381 }
382
383
384
385
386
387
388
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 func deferrangefunc() any {
451 gp := getg()
452 if gp.m.curg != gp {
453
454 throw("defer on system stack")
455 }
456
457 d := newdefer()
458 d.link = gp._defer
459 gp._defer = d
460
461
462
463 d.sp = sys.GetCallerSP()
464
465 d.rangefunc = true
466 d.head = new(atomic.Pointer[_defer])
467
468 return d.head
469 }
470
471
472 func badDefer() *_defer {
473 return (*_defer)(unsafe.Pointer(uintptr(1)))
474 }
475
476
477
478 func deferprocat(fn func(), frame any) {
479 head := frame.(*atomic.Pointer[_defer])
480 if raceenabled {
481 racewritepc(unsafe.Pointer(head), sys.GetCallerPC(), abi.FuncPCABIInternal(deferprocat))
482 }
483 d1 := newdefer()
484 d1.fn = fn
485 for {
486 d1.link = head.Load()
487 if d1.link == badDefer() {
488 throw("defer after range func returned")
489 }
490 if head.CompareAndSwap(d1.link, d1) {
491 break
492 }
493 }
494 }
495
496
497
498
499 func deferconvert(d0 *_defer) {
500 head := d0.head
501 if raceenabled {
502 racereadpc(unsafe.Pointer(head), sys.GetCallerPC(), abi.FuncPCABIInternal(deferconvert))
503 }
504 tail := d0.link
505 d0.rangefunc = false
506
507 var d *_defer
508 for {
509 d = head.Load()
510 if head.CompareAndSwap(d, badDefer()) {
511 break
512 }
513 }
514 if d == nil {
515 return
516 }
517 for d1 := d; ; d1 = d1.link {
518 d1.sp = d0.sp
519 if d1.link == nil {
520 d1.link = tail
521 break
522 }
523 }
524 d0.link = d
525 return
526 }
527
528
529
530
531
532
533
534 func deferprocStack(d *_defer) {
535 gp := getg()
536 if gp.m.curg != gp {
537
538 throw("defer on system stack")
539 }
540
541
542
543
544 d.heap = false
545 d.rangefunc = false
546 d.sp = sys.GetCallerSP()
547
548
549
550
551
552
553
554
555
556
557 *(*uintptr)(unsafe.Pointer(&d.link)) = uintptr(unsafe.Pointer(gp._defer))
558 *(*uintptr)(unsafe.Pointer(&d.head)) = 0
559 *(*uintptr)(unsafe.Pointer(&gp._defer)) = uintptr(unsafe.Pointer(d))
560 }
561
562
563
564
565
566
567 func newdefer() *_defer {
568 var d *_defer
569 mp := acquirem()
570 pp := mp.p.ptr()
571 if len(pp.deferpool) == 0 && sched.deferpool != nil {
572 lock(&sched.deferlock)
573 for len(pp.deferpool) < cap(pp.deferpool)/2 && sched.deferpool != nil {
574 d := sched.deferpool
575 sched.deferpool = d.link
576 d.link = nil
577 pp.deferpool = append(pp.deferpool, d)
578 }
579 unlock(&sched.deferlock)
580 }
581 if n := len(pp.deferpool); n > 0 {
582 d = pp.deferpool[n-1]
583 pp.deferpool[n-1] = nil
584 pp.deferpool = pp.deferpool[:n-1]
585 }
586 releasem(mp)
587 mp, pp = nil, nil
588
589 if d == nil {
590
591 d = new(_defer)
592 }
593 d.heap = true
594 return d
595 }
596
597
598 func popDefer(gp *g) {
599 d := gp._defer
600 d.fn = nil
601
602
603
604
605 gp._defer = d.link
606 d.link = nil
607
608
609 if !d.heap {
610 return
611 }
612
613 mp := acquirem()
614 pp := mp.p.ptr()
615 if len(pp.deferpool) == cap(pp.deferpool) {
616
617 var first, last *_defer
618 for len(pp.deferpool) > cap(pp.deferpool)/2 {
619 n := len(pp.deferpool)
620 d := pp.deferpool[n-1]
621 pp.deferpool[n-1] = nil
622 pp.deferpool = pp.deferpool[:n-1]
623 if first == nil {
624 first = d
625 } else {
626 last.link = d
627 }
628 last = d
629 }
630 lock(&sched.deferlock)
631 last.link = sched.deferpool
632 sched.deferpool = first
633 unlock(&sched.deferlock)
634 }
635
636 *d = _defer{}
637
638 pp.deferpool = append(pp.deferpool, d)
639
640 releasem(mp)
641 mp, pp = nil, nil
642 }
643
644
645
646
647 func deferreturn() {
648 var p _panic
649 p.deferreturn = true
650
651 p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
652 for {
653 fn, ok := p.nextDefer()
654 if !ok {
655 break
656 }
657 fn()
658 }
659 }
660
661
662
663
664
665
666
667
668
669
670
671 func Goexit() {
672
673
674 var p _panic
675 p.goexit = true
676
677 p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
678 for {
679 fn, ok := p.nextDefer()
680 if !ok {
681 break
682 }
683 fn()
684 }
685
686 goexit1()
687 }
688
689
690
691 func preprintpanics(p *_panic) {
692 defer func() {
693 text := "panic while printing panic value"
694 switch r := recover().(type) {
695 case nil:
696
697 case string:
698 throw(text + ": " + r)
699 default:
700 throw(text + ": type " + toRType(efaceOf(&r)._type).string())
701 }
702 }()
703 for p != nil {
704 if p.link != nil && *efaceOf(&p.link.arg) == *efaceOf(&p.arg) {
705
706
707 p.link.repanicked = true
708 p = p.link
709 continue
710 }
711 switch v := p.arg.(type) {
712 case error:
713 p.arg = v.Error()
714 case stringer:
715 p.arg = v.String()
716 }
717 p = p.link
718 }
719 }
720
721
722
723 func printpanics(p *_panic) {
724 if p.link != nil {
725 printpanics(p.link)
726 if p.link.repanicked {
727 return
728 }
729 if !p.link.goexit {
730 print("\t")
731 }
732 }
733 if p.goexit {
734 return
735 }
736 print("panic: ")
737 printpanicval(p.arg)
738 if p.repanicked {
739 print(" [recovered, repanicked]")
740 } else if p.recovered {
741 print(" [recovered]")
742 }
743 print("\n")
744 }
745
746
747
748
749
750
751 func readvarintUnsafe(fd unsafe.Pointer) (uint32, unsafe.Pointer) {
752 var r uint32
753 var shift int
754 for {
755 b := *(*uint8)(fd)
756 fd = add(fd, unsafe.Sizeof(b))
757 if b < 128 {
758 return r + uint32(b)<<shift, fd
759 }
760 r += uint32(b&0x7F) << (shift & 31)
761 shift += 7
762 if shift > 28 {
763 panic("Bad varint")
764 }
765 }
766 }
767
768
769
770
771
772
773 type PanicNilError struct {
774
775
776
777
778
779
780 _ [0]*PanicNilError
781 }
782
783 func (*PanicNilError) Error() string { return "panic called with nil argument" }
784 func (*PanicNilError) RuntimeError() {}
785
786 var panicnil = &godebugInc{name: "panicnil"}
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801 func gopanic(e any) {
802 if e == nil {
803 if debug.panicnil.Load() != 1 {
804 e = new(PanicNilError)
805 } else {
806 panicnil.IncNonDefault()
807 }
808 }
809
810 gp := getg()
811 if gp.m.curg != gp {
812 print("panic: ")
813 printpanicval(e)
814 print("\n")
815 throw("panic on system stack")
816 }
817
818 if gp.m.mallocing != 0 {
819 print("panic: ")
820 printpanicval(e)
821 print("\n")
822 throw("panic during malloc")
823 }
824 if gp.m.preemptoff != "" {
825 print("panic: ")
826 printpanicval(e)
827 print("\n")
828 print("preempt off reason: ")
829 print(gp.m.preemptoff)
830 print("\n")
831 throw("panic during preemptoff")
832 }
833 if gp.m.locks != 0 {
834 print("panic: ")
835 printpanicval(e)
836 print("\n")
837 throw("panic holding locks")
838 }
839
840 var p _panic
841 p.arg = e
842 p.gopanicFP = unsafe.Pointer(sys.GetCallerSP())
843
844 runningPanicDefers.Add(1)
845
846 p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
847 for {
848 fn, ok := p.nextDefer()
849 if !ok {
850 break
851 }
852 fn()
853 }
854
855
856
857
858
859
860
861 if traceEnabled() {
862 traceAdvance(false)
863 }
864
865
866
867
868
869 preprintpanics(&p)
870
871 fatalpanic(&p)
872 *(*int)(nil) = 0
873 }
874
875
876
877
878 func (p *_panic) start(pc uintptr, sp unsafe.Pointer) {
879 gp := getg()
880
881
882
883
884
885 p.startPC = sys.GetCallerPC()
886 p.startSP = unsafe.Pointer(sys.GetCallerSP())
887
888 if p.deferreturn {
889 p.sp = sp
890
891 if s := (*savedOpenDeferState)(gp.param); s != nil {
892
893
894
895 gp.param = nil
896
897 p.retpc = s.retpc
898 p.deferBitsPtr = (*byte)(add(sp, s.deferBitsOffset))
899 p.slotsPtr = add(sp, s.slotsOffset)
900 }
901
902 return
903 }
904
905 p.link = gp._panic
906 gp._panic = (*_panic)(noescape(unsafe.Pointer(p)))
907
908
909
910
911
912
913
914
915 p.lr, p.fp = pc, sp
916 p.nextFrame()
917 }
918
919
920
921
922
923 func (p *_panic) nextDefer() (func(), bool) {
924 gp := getg()
925
926 if !p.deferreturn {
927 if gp._panic != p {
928 throw("bad panic stack")
929 }
930
931 if p.recovered {
932 mcall(recovery)
933 throw("recovery failed")
934 }
935 }
936
937 for {
938 for p.deferBitsPtr != nil {
939 bits := *p.deferBitsPtr
940
941
942
943
944
945
946
947
948
949 if bits == 0 {
950 p.deferBitsPtr = nil
951 break
952 }
953
954
955 i := 7 - uintptr(sys.LeadingZeros8(bits))
956
957
958 bits &^= 1 << i
959 *p.deferBitsPtr = bits
960
961 return *(*func())(add(p.slotsPtr, i*goarch.PtrSize)), true
962 }
963
964 Recheck:
965 if d := gp._defer; d != nil && d.sp == uintptr(p.sp) {
966 if d.rangefunc {
967 deferconvert(d)
968 popDefer(gp)
969 goto Recheck
970 }
971
972 fn := d.fn
973
974
975 popDefer(gp)
976
977 return fn, true
978 }
979
980 if !p.nextFrame() {
981 return nil, false
982 }
983 }
984 }
985
986
987 func (p *_panic) nextFrame() (ok bool) {
988 if p.lr == 0 {
989 return false
990 }
991
992 gp := getg()
993 systemstack(func() {
994 var limit uintptr
995 if d := gp._defer; d != nil {
996 limit = d.sp
997 }
998
999 var u unwinder
1000 u.initAt(p.lr, uintptr(p.fp), 0, gp, 0)
1001 for {
1002 if !u.valid() {
1003 p.lr = 0
1004 return
1005 }
1006
1007
1008
1009
1010
1011
1012 if u.frame.sp == limit {
1013 f := u.frame.fn
1014 if f.deferreturn == 0 {
1015 throw("no deferreturn")
1016 }
1017 p.retpc = f.entry() + uintptr(f.deferreturn)
1018
1019 break
1020 }
1021
1022 if p.initOpenCodedDefers(u.frame.fn, unsafe.Pointer(u.frame.varp)) {
1023 break
1024 }
1025
1026 u.next()
1027 }
1028
1029 p.lr = u.frame.lr
1030 p.sp = unsafe.Pointer(u.frame.sp)
1031 p.fp = unsafe.Pointer(u.frame.fp)
1032
1033 ok = true
1034 })
1035
1036 return
1037 }
1038
1039 func (p *_panic) initOpenCodedDefers(fn funcInfo, varp unsafe.Pointer) bool {
1040 fd := funcdata(fn, abi.FUNCDATA_OpenCodedDeferInfo)
1041 if fd == nil {
1042 return false
1043 }
1044
1045 if fn.deferreturn == 0 {
1046 throw("missing deferreturn")
1047 }
1048
1049 deferBitsOffset, fd := readvarintUnsafe(fd)
1050 deferBitsPtr := (*uint8)(add(varp, -uintptr(deferBitsOffset)))
1051 if *deferBitsPtr == 0 {
1052 return false
1053 }
1054
1055 slotsOffset, fd := readvarintUnsafe(fd)
1056
1057 p.retpc = fn.entry() + uintptr(fn.deferreturn)
1058 p.deferBitsPtr = deferBitsPtr
1059 p.slotsPtr = add(varp, -uintptr(slotsOffset))
1060
1061 return true
1062 }
1063
1064
1065 func gorecover() any {
1066 gp := getg()
1067 p := gp._panic
1068 if p == nil || p.goexit || p.recovered {
1069 return nil
1070 }
1071
1072
1073
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 canRecover := false
1116 systemstack(func() {
1117 var u unwinder
1118 u.init(gp, 0)
1119 u.next()
1120 u.next()
1121 nonWrapperFrames := 0
1122 loop:
1123 for ; u.valid(); u.next() {
1124 for iu, f := newInlineUnwinder(u.frame.fn, u.symPC()); f.valid(); f = iu.next(f) {
1125 sf := iu.srcFunc(f)
1126 switch sf.funcID {
1127 case abi.FuncIDWrapper:
1128 continue
1129 case abi.FuncID_gopanic:
1130 if u.frame.fp == uintptr(p.gopanicFP) && nonWrapperFrames > 0 {
1131 canRecover = true
1132 }
1133 break loop
1134 default:
1135 nonWrapperFrames++
1136 if nonWrapperFrames > 1 {
1137 break loop
1138 }
1139 }
1140 }
1141 }
1142 })
1143 if !canRecover {
1144 return nil
1145 }
1146 p.recovered = true
1147 return p.arg
1148 }
1149
1150
1151 func sync_throw(s string) {
1152 throw(s)
1153 }
1154
1155
1156 func sync_fatal(s string) {
1157 fatal(s)
1158 }
1159
1160
1161 func rand_fatal(s string) {
1162 fatal(s)
1163 }
1164
1165
1166 func sysrand_fatal(s string) {
1167 fatal(s)
1168 }
1169
1170
1171 func fips_fatal(s string) {
1172 fatal(s)
1173 }
1174
1175
1176 func maps_fatal(s string) {
1177 fatal(s)
1178 }
1179
1180
1181 func internal_sync_throw(s string) {
1182 throw(s)
1183 }
1184
1185
1186 func internal_sync_fatal(s string) {
1187 fatal(s)
1188 }
1189
1190
1191 func cgroup_throw(s string) {
1192 throw(s)
1193 }
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216 func throw(s string) {
1217
1218
1219 systemstack(func() {
1220 print("fatal error: ")
1221 printindented(s)
1222 print("\n")
1223 })
1224
1225 fatalthrow(throwTypeRuntime)
1226 }
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237 func fatal(s string) {
1238
1239
1240 printlock()
1241 systemstack(func() {
1242 print("fatal error: ")
1243 printindented(s)
1244 print("\n")
1245 })
1246
1247 fatalthrow(throwTypeUser)
1248 printunlock()
1249 }
1250
1251
1252
1253 var runningPanicDefers atomic.Uint32
1254
1255
1256 var panicking atomic.Uint32
1257
1258
1259
1260 var paniclk mutex
1261
1262
1263
1264
1265
1266
1267
1268
1269 func recovery(gp *g) {
1270 p := gp._panic
1271 pc, sp, fp := p.retpc, uintptr(p.sp), uintptr(p.fp)
1272 p0, saveOpenDeferState := p, p.deferBitsPtr != nil && *p.deferBitsPtr != 0
1273
1274
1275 for ; p != nil && uintptr(p.startSP) < sp; p = p.link {
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295 if p.goexit {
1296 pc, sp = p.startPC, uintptr(p.startSP)
1297 saveOpenDeferState = false
1298 break
1299 }
1300
1301 runningPanicDefers.Add(-1)
1302 }
1303 gp._panic = p
1304
1305 if p == nil {
1306 gp.sig = 0
1307 }
1308
1309 if gp.param != nil {
1310 throw("unexpected gp.param")
1311 }
1312 if saveOpenDeferState {
1313
1314
1315
1316 gp.param = unsafe.Pointer(&savedOpenDeferState{
1317 retpc: p0.retpc,
1318
1319
1320
1321
1322 deferBitsOffset: uintptr(unsafe.Pointer(p0.deferBitsPtr)) - uintptr(p0.sp),
1323 slotsOffset: uintptr(p0.slotsPtr) - uintptr(p0.sp),
1324 })
1325 }
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352 if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
1353 print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
1354 throw("bad recovery")
1355 }
1356
1357
1358 gp.sched.sp = sp
1359 gp.sched.pc = pc
1360 gp.sched.lr = 0
1361
1362
1363
1364 switch {
1365 case goarch.IsAmd64 != 0:
1366
1367
1368
1369 gp.sched.bp = fp - 2*goarch.PtrSize
1370 case goarch.IsArm64 != 0:
1371
1372
1373
1374 gp.sched.bp = sp - goarch.PtrSize
1375 }
1376 gogo(&gp.sched)
1377 }
1378
1379
1380
1381
1382
1383
1384 func fatalthrow(t throwType) {
1385 pc := sys.GetCallerPC()
1386 sp := sys.GetCallerSP()
1387 gp := getg()
1388
1389 if gp.m.throwing == throwTypeNone {
1390 gp.m.throwing = t
1391 }
1392
1393
1394
1395 systemstack(func() {
1396 if isSecureMode() {
1397 exit(2)
1398 }
1399
1400 startpanic_m()
1401
1402 if dopanic_m(gp, pc, sp, nil) {
1403
1404
1405
1406 crash()
1407 }
1408
1409 exit(2)
1410 })
1411
1412 *(*int)(nil) = 0
1413 }
1414
1415
1416
1417
1418
1419
1420 func fatalpanic(msgs *_panic) {
1421 pc := sys.GetCallerPC()
1422 sp := sys.GetCallerSP()
1423 gp := getg()
1424 var docrash bool
1425
1426
1427 systemstack(func() {
1428 if startpanic_m() && msgs != nil {
1429
1430
1431
1432
1433
1434
1435 runningPanicDefers.Add(-1)
1436
1437 printpanics(msgs)
1438 }
1439
1440
1441
1442 var bubble *synctestBubble
1443 if de, ok := msgs.arg.(synctestDeadlockError); ok {
1444 bubble = de.bubble
1445 }
1446
1447 docrash = dopanic_m(gp, pc, sp, bubble)
1448 })
1449
1450 if docrash {
1451
1452
1453
1454 crash()
1455 }
1456
1457 systemstack(func() {
1458 exit(2)
1459 })
1460
1461 *(*int)(nil) = 0
1462 }
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476 func startpanic_m() bool {
1477 gp := getg()
1478 if mheap_.cachealloc.size == 0 {
1479 print("runtime: panic before malloc heap initialized\n")
1480 }
1481
1482
1483
1484
1485 gp.m.mallocing++
1486
1487
1488
1489 if gp.m.locks < 0 {
1490 gp.m.locks = 1
1491 }
1492
1493 switch gp.m.dying {
1494 case 0:
1495
1496 gp.m.dying = 1
1497 panicking.Add(1)
1498 lock(&paniclk)
1499 if debug.schedtrace > 0 || debug.scheddetail > 0 {
1500 schedtrace(true)
1501 }
1502 freezetheworld()
1503 return true
1504 case 1:
1505
1506
1507 gp.m.dying = 2
1508 print("panic during panic\n")
1509 return false
1510 case 2:
1511
1512
1513 gp.m.dying = 3
1514 print("stack trace unavailable\n")
1515 exit(4)
1516 fallthrough
1517 default:
1518
1519 exit(5)
1520 return false
1521 }
1522 }
1523
1524 var didothers bool
1525 var deadlock mutex
1526
1527
1528
1529
1530 func dopanic_m(gp *g, pc, sp uintptr, bubble *synctestBubble) bool {
1531 if gp.sig != 0 {
1532 signame := signame(gp.sig)
1533 if signame != "" {
1534 print("[signal ", signame)
1535 } else {
1536 print("[signal ", hex(gp.sig))
1537 }
1538 print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
1539 }
1540
1541 level, all, docrash := gotraceback()
1542 if level > 0 {
1543 if gp != gp.m.curg {
1544 all = true
1545 }
1546 if gp != gp.m.g0 {
1547 print("\n")
1548 goroutineheader(gp)
1549 traceback(pc, sp, 0, gp)
1550 } else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
1551 print("\nruntime stack:\n")
1552 traceback(pc, sp, 0, gp)
1553 }
1554 if !didothers {
1555 if all {
1556 didothers = true
1557 tracebackothers(gp)
1558 } else if bubble != nil {
1559
1560
1561 tracebacksomeothers(gp, func(other *g) bool {
1562 return bubble == other.bubble
1563 })
1564 }
1565 }
1566
1567 }
1568 unlock(&paniclk)
1569
1570 if panicking.Add(-1) != 0 {
1571
1572
1573
1574
1575 lock(&deadlock)
1576 lock(&deadlock)
1577 }
1578
1579 printDebugLog()
1580
1581 return docrash
1582 }
1583
1584
1585
1586
1587
1588 func canpanic() bool {
1589 gp := getg()
1590 mp := acquirem()
1591
1592
1593
1594
1595 if gp != mp.curg {
1596 releasem(mp)
1597 return false
1598 }
1599
1600 if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
1601 releasem(mp)
1602 return false
1603 }
1604 status := readgstatus(gp)
1605 if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
1606 releasem(mp)
1607 return false
1608 }
1609 if GOOS == "windows" && mp.libcallsp != 0 {
1610 releasem(mp)
1611 return false
1612 }
1613 releasem(mp)
1614 return true
1615 }
1616
1617
1618
1619
1620
1621
1622 func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
1623 if pc == 0 {
1624
1625
1626
1627
1628
1629 return false
1630 }
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640 if gp.m.incgo || findfunc(pc).valid() {
1641
1642
1643 return true
1644 }
1645 if findfunc(lr).valid() {
1646
1647
1648 return false
1649 }
1650
1651
1652 return true
1653 }
1654
1655
1656
1657
1658
1659
1660
1661
1662 func isAbortPC(pc uintptr) bool {
1663 f := findfunc(pc)
1664 if !f.valid() {
1665 return false
1666 }
1667 return f.funcID == abi.FuncID_abort
1668 }
1669
View as plain text