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