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
113 func goPanicIndex(x int, y int) {
114 panicCheck1(sys.GetCallerPC(), "index out of range")
115 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsIndex})
116 }
117
118
119 func goPanicIndexU(x uint, y int) {
120 panicCheck1(sys.GetCallerPC(), "index out of range")
121 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsIndex})
122 }
123
124
125
126
127 func goPanicSliceAlen(x int, y int) {
128 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
129 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceAlen})
130 }
131
132
133 func goPanicSliceAlenU(x uint, y int) {
134 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
135 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceAlen})
136 }
137
138
139 func goPanicSliceAcap(x int, y int) {
140 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
141 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceAcap})
142 }
143
144
145 func goPanicSliceAcapU(x uint, y int) {
146 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
147 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceAcap})
148 }
149
150
151
152
153 func goPanicSliceB(x int, y int) {
154 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
155 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceB})
156 }
157
158
159 func goPanicSliceBU(x uint, y int) {
160 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
161 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceB})
162 }
163
164
165 func goPanicSlice3Alen(x int, y int) {
166 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
167 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3Alen})
168 }
169 func goPanicSlice3AlenU(x uint, y int) {
170 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
171 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3Alen})
172 }
173 func goPanicSlice3Acap(x int, y int) {
174 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
175 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3Acap})
176 }
177 func goPanicSlice3AcapU(x uint, y int) {
178 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
179 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3Acap})
180 }
181
182
183 func goPanicSlice3B(x int, y int) {
184 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
185 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3B})
186 }
187 func goPanicSlice3BU(x uint, y int) {
188 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
189 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3B})
190 }
191
192
193 func goPanicSlice3C(x int, y int) {
194 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
195 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3C})
196 }
197 func goPanicSlice3CU(x uint, y int) {
198 panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
199 panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3C})
200 }
201
202
203 func goPanicSliceConvert(x int, y int) {
204 panicCheck1(sys.GetCallerPC(), "slice length too short to convert to array or pointer to array")
205 panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsConvert})
206 }
207
208
209
210 func panicIndex(x int, y int)
211 func panicIndexU(x uint, y int)
212 func panicSliceAlen(x int, y int)
213 func panicSliceAlenU(x uint, y int)
214 func panicSliceAcap(x int, y int)
215 func panicSliceAcapU(x uint, y int)
216 func panicSliceB(x int, y int)
217 func panicSliceBU(x uint, y int)
218 func panicSlice3Alen(x int, y int)
219 func panicSlice3AlenU(x uint, y int)
220 func panicSlice3Acap(x int, y int)
221 func panicSlice3AcapU(x uint, y int)
222 func panicSlice3B(x int, y int)
223 func panicSlice3BU(x uint, y int)
224 func panicSlice3C(x int, y int)
225 func panicSlice3CU(x uint, y int)
226 func panicSliceConvert(x int, y int)
227
228 func panicBounds()
229 func panicExtend()
230 func panicBounds64(pc uintptr, regs *[16]int64) {
231 f := findfunc(pc)
232 v := pcdatavalue(f, abi.PCDATA_PanicBounds, pc-1)
233
234 code, signed, xIsReg, yIsReg, xVal, yVal := abi.BoundsDecode(int(v))
235
236 if code == abi.BoundsIndex {
237 panicCheck1(pc, "index out of range")
238 } else {
239 panicCheck1(pc, "slice bounds out of range")
240 }
241
242 var e boundsError
243 e.code = code
244 e.signed = signed
245 if xIsReg {
246 e.x = regs[xVal]
247 } else {
248 e.x = int64(xVal)
249 }
250 if yIsReg {
251 e.y = int(regs[yVal])
252 } else {
253 e.y = yVal
254 }
255 panic(e)
256 }
257
258 func panicBounds32(pc uintptr, regs *[16]int32) {
259 f := findfunc(pc)
260 v := pcdatavalue(f, abi.PCDATA_PanicBounds, pc-1)
261
262 code, signed, xIsReg, yIsReg, xVal, yVal := abi.BoundsDecode(int(v))
263
264 if code == abi.BoundsIndex {
265 panicCheck1(pc, "index out of range")
266 } else {
267 panicCheck1(pc, "slice bounds out of range")
268 }
269
270 var e boundsError
271 e.code = code
272 e.signed = signed
273 if xIsReg {
274 if signed {
275 e.x = int64(regs[xVal])
276 } else {
277 e.x = int64(uint32(regs[xVal]))
278 }
279 } else {
280 e.x = int64(xVal)
281 }
282 if yIsReg {
283 e.y = int(regs[yVal])
284 } else {
285 e.y = yVal
286 }
287 panic(e)
288 }
289
290 func panicBounds32X(pc uintptr, regs *[16]int32) {
291 f := findfunc(pc)
292 v := pcdatavalue(f, abi.PCDATA_PanicBounds, pc-1)
293
294 code, signed, xIsReg, yIsReg, xVal, yVal := abi.BoundsDecode(int(v))
295
296 if code == abi.BoundsIndex {
297 panicCheck1(pc, "index out of range")
298 } else {
299 panicCheck1(pc, "slice bounds out of range")
300 }
301
302 var e boundsError
303 e.code = code
304 e.signed = signed
305 if xIsReg {
306
307 lo := xVal & 3
308 hi := xVal >> 2
309 e.x = int64(regs[hi])<<32 + int64(uint32(regs[lo]))
310 } else {
311 e.x = int64(xVal)
312 }
313 if yIsReg {
314 e.y = int(regs[yVal])
315 } else {
316 e.y = yVal
317 }
318 panic(e)
319 }
320
321 var shiftError = error(errorString("negative shift amount"))
322
323
324 func panicshift() {
325 panicCheck1(sys.GetCallerPC(), "negative shift amount")
326 panic(shiftError)
327 }
328
329 var divideError = error(errorString("integer divide by zero"))
330
331
332 func panicdivide() {
333 panicCheck2("integer divide by zero")
334 panic(divideError)
335 }
336
337 var overflowError = error(errorString("integer overflow"))
338
339 func panicoverflow() {
340 panicCheck2("integer overflow")
341 panic(overflowError)
342 }
343
344 var floatError = error(errorString("floating point error"))
345
346 func panicfloat() {
347 panicCheck2("floating point error")
348 panic(floatError)
349 }
350
351 var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
352
353 func panicmem() {
354 panicCheck2("invalid memory address or nil pointer dereference")
355 panic(memoryError)
356 }
357
358 func panicmemAddr(addr uintptr) {
359 panicCheck2("invalid memory address or nil pointer dereference")
360 panic(errorAddressString{msg: "invalid memory address or nil pointer dereference", addr: addr})
361 }
362
363
364
365 func deferproc(fn func()) {
366 gp := getg()
367 if gp.m.curg != gp {
368
369 throw("defer on system stack")
370 }
371
372 d := newdefer()
373 d.link = gp._defer
374 gp._defer = d
375 d.fn = fn
376 d.pc = sys.GetCallerPC()
377
378
379
380 d.sp = sys.GetCallerSP()
381 }
382
383 var rangeDoneError = error(errorString("range function continued iteration after function for loop body returned false"))
384 var rangePanicError = error(errorString("range function continued iteration after loop body panic"))
385 var rangeExhaustedError = error(errorString("range function continued iteration after whole loop exit"))
386 var rangeMissingPanicError = error(errorString("range function recovered a loop body panic and did not resume panicking"))
387
388
389 func panicrangestate(state int) {
390 switch abi.RF_State(state) {
391 case abi.RF_DONE:
392 panic(rangeDoneError)
393 case abi.RF_PANIC:
394 panic(rangePanicError)
395 case abi.RF_EXHAUSTED:
396 panic(rangeExhaustedError)
397 case abi.RF_MISSING_PANIC:
398 panic(rangeMissingPanicError)
399 }
400 throw("unexpected state passed to panicrangestate")
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
459
460
461
462
463
464
465
466
467
468
469
470 func deferrangefunc() any {
471 gp := getg()
472 if gp.m.curg != gp {
473
474 throw("defer on system stack")
475 }
476
477 d := newdefer()
478 d.link = gp._defer
479 gp._defer = d
480 d.pc = sys.GetCallerPC()
481
482
483
484 d.sp = sys.GetCallerSP()
485
486 d.rangefunc = true
487 d.head = new(atomic.Pointer[_defer])
488
489 return d.head
490 }
491
492
493 func badDefer() *_defer {
494 return (*_defer)(unsafe.Pointer(uintptr(1)))
495 }
496
497
498
499 func deferprocat(fn func(), frame any) {
500 head := frame.(*atomic.Pointer[_defer])
501 if raceenabled {
502 racewritepc(unsafe.Pointer(head), sys.GetCallerPC(), abi.FuncPCABIInternal(deferprocat))
503 }
504 d1 := newdefer()
505 d1.fn = fn
506 for {
507 d1.link = head.Load()
508 if d1.link == badDefer() {
509 throw("defer after range func returned")
510 }
511 if head.CompareAndSwap(d1.link, d1) {
512 break
513 }
514 }
515 }
516
517
518
519
520 func deferconvert(d0 *_defer) {
521 head := d0.head
522 if raceenabled {
523 racereadpc(unsafe.Pointer(head), sys.GetCallerPC(), abi.FuncPCABIInternal(deferconvert))
524 }
525 tail := d0.link
526 d0.rangefunc = false
527
528 var d *_defer
529 for {
530 d = head.Load()
531 if head.CompareAndSwap(d, badDefer()) {
532 break
533 }
534 }
535 if d == nil {
536 return
537 }
538 for d1 := d; ; d1 = d1.link {
539 d1.sp = d0.sp
540 d1.pc = d0.pc
541 if d1.link == nil {
542 d1.link = tail
543 break
544 }
545 }
546 d0.link = d
547 return
548 }
549
550
551
552
553
554
555
556 func deferprocStack(d *_defer) {
557 gp := getg()
558 if gp.m.curg != gp {
559
560 throw("defer on system stack")
561 }
562
563
564
565
566 d.heap = false
567 d.rangefunc = false
568 d.sp = sys.GetCallerSP()
569 d.pc = sys.GetCallerPC()
570
571
572
573
574
575
576
577
578
579
580
581
582 *(*uintptr)(unsafe.Pointer(&d.link)) = uintptr(unsafe.Pointer(gp._defer))
583 *(*uintptr)(unsafe.Pointer(&d.head)) = 0
584 *(*uintptr)(unsafe.Pointer(&gp._defer)) = uintptr(unsafe.Pointer(d))
585 }
586
587
588
589
590
591
592 func newdefer() *_defer {
593 var d *_defer
594 mp := acquirem()
595 pp := mp.p.ptr()
596 if len(pp.deferpool) == 0 && sched.deferpool != nil {
597 lock(&sched.deferlock)
598 for len(pp.deferpool) < cap(pp.deferpool)/2 && sched.deferpool != nil {
599 d := sched.deferpool
600 sched.deferpool = d.link
601 d.link = nil
602 pp.deferpool = append(pp.deferpool, d)
603 }
604 unlock(&sched.deferlock)
605 }
606 if n := len(pp.deferpool); n > 0 {
607 d = pp.deferpool[n-1]
608 pp.deferpool[n-1] = nil
609 pp.deferpool = pp.deferpool[:n-1]
610 }
611 releasem(mp)
612 mp, pp = nil, nil
613
614 if d == nil {
615
616 d = new(_defer)
617 }
618 d.heap = true
619 return d
620 }
621
622
623 func popDefer(gp *g) {
624 d := gp._defer
625 d.fn = nil
626
627
628
629
630 gp._defer = d.link
631 d.link = nil
632
633
634 if !d.heap {
635 return
636 }
637
638 mp := acquirem()
639 pp := mp.p.ptr()
640 if len(pp.deferpool) == cap(pp.deferpool) {
641
642 var first, last *_defer
643 for len(pp.deferpool) > cap(pp.deferpool)/2 {
644 n := len(pp.deferpool)
645 d := pp.deferpool[n-1]
646 pp.deferpool[n-1] = nil
647 pp.deferpool = pp.deferpool[:n-1]
648 if first == nil {
649 first = d
650 } else {
651 last.link = d
652 }
653 last = d
654 }
655 lock(&sched.deferlock)
656 last.link = sched.deferpool
657 sched.deferpool = first
658 unlock(&sched.deferlock)
659 }
660
661 *d = _defer{}
662
663 pp.deferpool = append(pp.deferpool, d)
664
665 releasem(mp)
666 mp, pp = nil, nil
667 }
668
669
670
671
672 func deferreturn() {
673 var p _panic
674 p.deferreturn = true
675
676 p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
677 for {
678 fn, ok := p.nextDefer()
679 if !ok {
680 break
681 }
682 fn()
683 }
684 }
685
686
687
688
689
690
691
692
693
694
695
696 func Goexit() {
697
698
699 var p _panic
700 p.goexit = true
701
702 p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
703 for {
704 fn, ok := p.nextDefer()
705 if !ok {
706 break
707 }
708 fn()
709 }
710
711 goexit1()
712 }
713
714
715
716 func preprintpanics(p *_panic) {
717 defer func() {
718 text := "panic while printing panic value"
719 switch r := recover().(type) {
720 case nil:
721
722 case string:
723 throw(text + ": " + r)
724 default:
725 throw(text + ": type " + toRType(efaceOf(&r)._type).string())
726 }
727 }()
728 for p != nil {
729 if p.link != nil && *efaceOf(&p.link.arg) == *efaceOf(&p.arg) {
730
731
732 p.link.repanicked = true
733 p = p.link
734 continue
735 }
736 switch v := p.arg.(type) {
737 case error:
738 p.arg = v.Error()
739 case stringer:
740 p.arg = v.String()
741 }
742 p = p.link
743 }
744 }
745
746
747
748 func printpanics(p *_panic) {
749 if p.link != nil {
750 printpanics(p.link)
751 if p.link.repanicked {
752 return
753 }
754 if !p.link.goexit {
755 print("\t")
756 }
757 }
758 if p.goexit {
759 return
760 }
761 print("panic: ")
762 printpanicval(p.arg)
763 if p.repanicked {
764 print(" [recovered, repanicked]")
765 } else if p.recovered {
766 print(" [recovered]")
767 }
768 print("\n")
769 }
770
771
772
773
774
775
776 func readvarintUnsafe(fd unsafe.Pointer) (uint32, unsafe.Pointer) {
777 var r uint32
778 var shift int
779 for {
780 b := *(*uint8)(fd)
781 fd = add(fd, unsafe.Sizeof(b))
782 if b < 128 {
783 return r + uint32(b)<<shift, fd
784 }
785 r += uint32(b&0x7F) << (shift & 31)
786 shift += 7
787 if shift > 28 {
788 panic("Bad varint")
789 }
790 }
791 }
792
793
794
795
796
797
798 type PanicNilError struct {
799
800
801
802
803
804
805 _ [0]*PanicNilError
806 }
807
808 func (*PanicNilError) Error() string { return "panic called with nil argument" }
809 func (*PanicNilError) RuntimeError() {}
810
811 var panicnil = &godebugInc{name: "panicnil"}
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826 func gopanic(e any) {
827 if e == nil {
828 if debug.panicnil.Load() != 1 {
829 e = new(PanicNilError)
830 } else {
831 panicnil.IncNonDefault()
832 }
833 }
834
835 gp := getg()
836 if gp.m.curg != gp {
837 print("panic: ")
838 printpanicval(e)
839 print("\n")
840 throw("panic on system stack")
841 }
842
843 if gp.m.mallocing != 0 {
844 print("panic: ")
845 printpanicval(e)
846 print("\n")
847 throw("panic during malloc")
848 }
849 if gp.m.preemptoff != "" {
850 print("panic: ")
851 printpanicval(e)
852 print("\n")
853 print("preempt off reason: ")
854 print(gp.m.preemptoff)
855 print("\n")
856 throw("panic during preemptoff")
857 }
858 if gp.m.locks != 0 {
859 print("panic: ")
860 printpanicval(e)
861 print("\n")
862 throw("panic holding locks")
863 }
864
865 var p _panic
866 p.arg = e
867 p.gopanicFP = unsafe.Pointer(sys.GetCallerSP())
868
869 runningPanicDefers.Add(1)
870
871 p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
872 for {
873 fn, ok := p.nextDefer()
874 if !ok {
875 break
876 }
877 fn()
878 }
879
880
881
882
883
884
885
886 if traceEnabled() {
887 traceAdvance(false)
888 }
889
890
891
892
893
894 preprintpanics(&p)
895
896 fatalpanic(&p)
897 *(*int)(nil) = 0
898 }
899
900
901
902
903 func (p *_panic) start(pc uintptr, sp unsafe.Pointer) {
904 gp := getg()
905
906
907
908
909
910 p.startPC = sys.GetCallerPC()
911 p.startSP = unsafe.Pointer(sys.GetCallerSP())
912
913 if p.deferreturn {
914 p.sp = sp
915
916 if s := (*savedOpenDeferState)(gp.param); s != nil {
917
918
919
920 gp.param = nil
921
922 p.retpc = s.retpc
923 p.deferBitsPtr = (*byte)(add(sp, s.deferBitsOffset))
924 p.slotsPtr = add(sp, s.slotsOffset)
925 }
926
927 return
928 }
929
930 p.link = gp._panic
931 gp._panic = (*_panic)(noescape(unsafe.Pointer(p)))
932
933
934
935
936
937
938
939
940 p.lr, p.fp = pc, sp
941 p.nextFrame()
942 }
943
944
945
946
947
948 func (p *_panic) nextDefer() (func(), bool) {
949 gp := getg()
950
951 if !p.deferreturn {
952 if gp._panic != p {
953 throw("bad panic stack")
954 }
955
956 if p.recovered {
957 mcall(recovery)
958 throw("recovery failed")
959 }
960 }
961
962 for {
963 for p.deferBitsPtr != nil {
964 bits := *p.deferBitsPtr
965
966
967
968
969
970
971
972
973
974 if bits == 0 {
975 p.deferBitsPtr = nil
976 break
977 }
978
979
980 i := 7 - uintptr(sys.LeadingZeros8(bits))
981
982
983 bits &^= 1 << i
984 *p.deferBitsPtr = bits
985
986 return *(*func())(add(p.slotsPtr, i*goarch.PtrSize)), true
987 }
988
989 Recheck:
990 if d := gp._defer; d != nil && d.sp == uintptr(p.sp) {
991 if d.rangefunc {
992 deferconvert(d)
993 popDefer(gp)
994 goto Recheck
995 }
996
997 fn := d.fn
998
999 p.retpc = d.pc
1000
1001
1002 popDefer(gp)
1003
1004 return fn, true
1005 }
1006
1007 if !p.nextFrame() {
1008 return nil, false
1009 }
1010 }
1011 }
1012
1013
1014 func (p *_panic) nextFrame() (ok bool) {
1015 if p.lr == 0 {
1016 return false
1017 }
1018
1019 gp := getg()
1020 systemstack(func() {
1021 var limit uintptr
1022 if d := gp._defer; d != nil {
1023 limit = d.sp
1024 }
1025
1026 var u unwinder
1027 u.initAt(p.lr, uintptr(p.fp), 0, gp, 0)
1028 for {
1029 if !u.valid() {
1030 p.lr = 0
1031 return
1032 }
1033
1034
1035
1036
1037
1038
1039 if u.frame.sp == limit {
1040 break
1041 }
1042
1043 if p.initOpenCodedDefers(u.frame.fn, unsafe.Pointer(u.frame.varp)) {
1044 break
1045 }
1046
1047 u.next()
1048 }
1049
1050 p.lr = u.frame.lr
1051 p.sp = unsafe.Pointer(u.frame.sp)
1052 p.fp = unsafe.Pointer(u.frame.fp)
1053
1054 ok = true
1055 })
1056
1057 return
1058 }
1059
1060 func (p *_panic) initOpenCodedDefers(fn funcInfo, varp unsafe.Pointer) bool {
1061 fd := funcdata(fn, abi.FUNCDATA_OpenCodedDeferInfo)
1062 if fd == nil {
1063 return false
1064 }
1065
1066 if fn.deferreturn == 0 {
1067 throw("missing deferreturn")
1068 }
1069
1070 deferBitsOffset, fd := readvarintUnsafe(fd)
1071 deferBitsPtr := (*uint8)(add(varp, -uintptr(deferBitsOffset)))
1072 if *deferBitsPtr == 0 {
1073 return false
1074 }
1075
1076 slotsOffset, fd := readvarintUnsafe(fd)
1077
1078 p.retpc = fn.entry() + uintptr(fn.deferreturn)
1079 p.deferBitsPtr = deferBitsPtr
1080 p.slotsPtr = add(varp, -uintptr(slotsOffset))
1081
1082 return true
1083 }
1084
1085
1086 func gorecover() any {
1087 gp := getg()
1088 p := gp._panic
1089 if p == nil || p.goexit || p.recovered {
1090 return nil
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
1136 canRecover := false
1137 systemstack(func() {
1138 var u unwinder
1139 u.init(gp, 0)
1140 u.next()
1141 u.next()
1142 nonWrapperFrames := 0
1143 loop:
1144 for ; u.valid(); u.next() {
1145 for iu, f := newInlineUnwinder(u.frame.fn, u.symPC()); f.valid(); f = iu.next(f) {
1146 sf := iu.srcFunc(f)
1147 switch sf.funcID {
1148 case abi.FuncIDWrapper:
1149 continue
1150 case abi.FuncID_gopanic:
1151 if u.frame.fp == uintptr(p.gopanicFP) && nonWrapperFrames > 0 {
1152 canRecover = true
1153 }
1154 break loop
1155 default:
1156 nonWrapperFrames++
1157 if nonWrapperFrames > 1 {
1158 break loop
1159 }
1160 }
1161 }
1162 }
1163 })
1164 if !canRecover {
1165 return nil
1166 }
1167 p.recovered = true
1168 return p.arg
1169 }
1170
1171
1172 func sync_throw(s string) {
1173 throw(s)
1174 }
1175
1176
1177 func sync_fatal(s string) {
1178 fatal(s)
1179 }
1180
1181
1182 func rand_fatal(s string) {
1183 fatal(s)
1184 }
1185
1186
1187 func sysrand_fatal(s string) {
1188 fatal(s)
1189 }
1190
1191
1192 func fips_fatal(s string) {
1193 fatal(s)
1194 }
1195
1196
1197 func maps_fatal(s string) {
1198 fatal(s)
1199 }
1200
1201
1202 func internal_sync_throw(s string) {
1203 throw(s)
1204 }
1205
1206
1207 func internal_sync_fatal(s string) {
1208 fatal(s)
1209 }
1210
1211
1212 func cgroup_throw(s string) {
1213 throw(s)
1214 }
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237 func throw(s string) {
1238
1239
1240 systemstack(func() {
1241 print("fatal error: ")
1242 printindented(s)
1243 print("\n")
1244 })
1245
1246 fatalthrow(throwTypeRuntime)
1247 }
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258 func fatal(s string) {
1259
1260
1261 printlock()
1262 systemstack(func() {
1263 print("fatal error: ")
1264 printindented(s)
1265 print("\n")
1266 })
1267
1268 fatalthrow(throwTypeUser)
1269 printunlock()
1270 }
1271
1272
1273
1274 var runningPanicDefers atomic.Uint32
1275
1276
1277 var panicking atomic.Uint32
1278
1279
1280
1281 var paniclk mutex
1282
1283
1284
1285
1286
1287
1288
1289
1290 func recovery(gp *g) {
1291 p := gp._panic
1292 pc, sp, fp := p.retpc, uintptr(p.sp), uintptr(p.fp)
1293 p0, saveOpenDeferState := p, p.deferBitsPtr != nil && *p.deferBitsPtr != 0
1294
1295
1296
1297
1298 f := findfunc(pc)
1299 if f.deferreturn == 0 {
1300 throw("no deferreturn")
1301 }
1302 gotoPc := f.entry() + uintptr(f.deferreturn)
1303
1304
1305 for ; p != nil && uintptr(p.startSP) < sp; p = p.link {
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325 if p.goexit {
1326 gotoPc, sp = p.startPC, uintptr(p.startSP)
1327 saveOpenDeferState = false
1328 break
1329 }
1330
1331 runningPanicDefers.Add(-1)
1332 }
1333 gp._panic = p
1334
1335 if p == nil {
1336 gp.sig = 0
1337 }
1338
1339 if gp.param != nil {
1340 throw("unexpected gp.param")
1341 }
1342 if saveOpenDeferState {
1343
1344
1345
1346 gp.param = unsafe.Pointer(&savedOpenDeferState{
1347 retpc: p0.retpc,
1348
1349
1350
1351
1352 deferBitsOffset: uintptr(unsafe.Pointer(p0.deferBitsPtr)) - uintptr(p0.sp),
1353 slotsOffset: uintptr(p0.slotsPtr) - uintptr(p0.sp),
1354 })
1355 }
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382 if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
1383 print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
1384 throw("bad recovery")
1385 }
1386
1387
1388 gp.sched.sp = sp
1389 gp.sched.pc = gotoPc
1390 gp.sched.lr = 0
1391
1392
1393
1394 switch {
1395 case goarch.IsAmd64 != 0:
1396
1397
1398
1399 gp.sched.bp = fp - 2*goarch.PtrSize
1400 case goarch.IsArm64 != 0:
1401
1402
1403
1404 gp.sched.bp = sp - goarch.PtrSize
1405 }
1406 gogo(&gp.sched)
1407 }
1408
1409
1410
1411
1412
1413
1414 func fatalthrow(t throwType) {
1415 pc := sys.GetCallerPC()
1416 sp := sys.GetCallerSP()
1417 gp := getg()
1418
1419 if gp.m.throwing == throwTypeNone {
1420 gp.m.throwing = t
1421 }
1422
1423
1424
1425 systemstack(func() {
1426 if isSecureMode() {
1427 exit(2)
1428 }
1429
1430 startpanic_m()
1431
1432 if dopanic_m(gp, pc, sp, nil) {
1433
1434
1435
1436 crash()
1437 }
1438
1439 exit(2)
1440 })
1441
1442 *(*int)(nil) = 0
1443 }
1444
1445
1446
1447
1448
1449
1450 func fatalpanic(msgs *_panic) {
1451 pc := sys.GetCallerPC()
1452 sp := sys.GetCallerSP()
1453 gp := getg()
1454 var docrash bool
1455
1456
1457 systemstack(func() {
1458 if startpanic_m() && msgs != nil {
1459
1460
1461
1462
1463
1464
1465 runningPanicDefers.Add(-1)
1466
1467 printpanics(msgs)
1468 }
1469
1470
1471
1472 var bubble *synctestBubble
1473 if de, ok := msgs.arg.(synctestDeadlockError); ok {
1474 bubble = de.bubble
1475 }
1476
1477 docrash = dopanic_m(gp, pc, sp, bubble)
1478 })
1479
1480 if docrash {
1481
1482
1483
1484 crash()
1485 }
1486
1487 systemstack(func() {
1488 exit(2)
1489 })
1490
1491 *(*int)(nil) = 0
1492 }
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506 func startpanic_m() bool {
1507 gp := getg()
1508 if mheap_.cachealloc.size == 0 {
1509 print("runtime: panic before malloc heap initialized\n")
1510 }
1511
1512
1513
1514
1515 gp.m.mallocing++
1516
1517
1518
1519 if gp.m.locks < 0 {
1520 gp.m.locks = 1
1521 }
1522
1523 switch gp.m.dying {
1524 case 0:
1525
1526 gp.m.dying = 1
1527 panicking.Add(1)
1528 lock(&paniclk)
1529 if debug.schedtrace > 0 || debug.scheddetail > 0 {
1530 schedtrace(true)
1531 }
1532 freezetheworld()
1533 return true
1534 case 1:
1535
1536
1537 gp.m.dying = 2
1538 print("panic during panic\n")
1539 return false
1540 case 2:
1541
1542
1543 gp.m.dying = 3
1544 print("stack trace unavailable\n")
1545 exit(4)
1546 fallthrough
1547 default:
1548
1549 exit(5)
1550 return false
1551 }
1552 }
1553
1554 var didothers bool
1555 var deadlock mutex
1556
1557
1558
1559
1560 func dopanic_m(gp *g, pc, sp uintptr, bubble *synctestBubble) bool {
1561 if gp.sig != 0 {
1562 signame := signame(gp.sig)
1563 if signame != "" {
1564 print("[signal ", signame)
1565 } else {
1566 print("[signal ", hex(gp.sig))
1567 }
1568 print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
1569 }
1570
1571 level, all, docrash := gotraceback()
1572 if level > 0 {
1573 if gp != gp.m.curg {
1574 all = true
1575 }
1576 if gp != gp.m.g0 {
1577 print("\n")
1578 goroutineheader(gp)
1579 traceback(pc, sp, 0, gp)
1580 } else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
1581 print("\nruntime stack:\n")
1582 traceback(pc, sp, 0, gp)
1583 }
1584 if !didothers {
1585 if all {
1586 didothers = true
1587 tracebackothers(gp)
1588 } else if bubble != nil {
1589
1590
1591 tracebacksomeothers(gp, func(other *g) bool {
1592 return bubble == other.bubble
1593 })
1594 }
1595 }
1596
1597 }
1598 unlock(&paniclk)
1599
1600 if panicking.Add(-1) != 0 {
1601
1602
1603
1604
1605 lock(&deadlock)
1606 lock(&deadlock)
1607 }
1608
1609 printDebugLog()
1610
1611 return docrash
1612 }
1613
1614
1615
1616
1617
1618 func canpanic() bool {
1619 gp := getg()
1620 mp := acquirem()
1621
1622
1623
1624
1625 if gp != mp.curg {
1626 releasem(mp)
1627 return false
1628 }
1629
1630 if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
1631 releasem(mp)
1632 return false
1633 }
1634 status := readgstatus(gp)
1635 if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
1636 releasem(mp)
1637 return false
1638 }
1639 if GOOS == "windows" && mp.libcallsp != 0 {
1640 releasem(mp)
1641 return false
1642 }
1643 releasem(mp)
1644 return true
1645 }
1646
1647
1648
1649
1650
1651
1652 func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
1653 if pc == 0 {
1654
1655
1656
1657
1658
1659 return false
1660 }
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670 if gp.m.incgo || findfunc(pc).valid() {
1671
1672
1673 return true
1674 }
1675 if findfunc(lr).valid() {
1676
1677
1678 return false
1679 }
1680
1681
1682 return true
1683 }
1684
1685
1686
1687
1688
1689
1690
1691
1692 func isAbortPC(pc uintptr) bool {
1693 f := findfunc(pc)
1694 if !f.valid() {
1695 return false
1696 }
1697 return f.funcID == abi.FuncID_abort
1698 }
1699
View as plain text