Source file
src/runtime/panic.go
Documentation: runtime
1
2
3
4
5 package runtime
6
7 import (
8 "internal/abi"
9 "internal/goexperiment"
10 "runtime/internal/atomic"
11 "runtime/internal/sys"
12 "unsafe"
13 )
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 func panicCheck1(pc uintptr, msg string) {
34 if sys.GoarchWasm == 0 && hasPrefix(funcname(findfunc(pc)), "runtime.") {
35
36 throw(msg)
37 }
38
39
40 gp := getg()
41 if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
42 throw(msg)
43 }
44 }
45
46
47
48
49
50
51 func panicCheck2(err string) {
52
53
54 gp := getg()
55 if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
56 throw(err)
57 }
58 }
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 func goPanicIndex(x int, y int) {
89 panicCheck1(getcallerpc(), "index out of range")
90 panic(boundsError{x: int64(x), signed: true, y: y, code: boundsIndex})
91 }
92 func goPanicIndexU(x uint, y int) {
93 panicCheck1(getcallerpc(), "index out of range")
94 panic(boundsError{x: int64(x), signed: false, y: y, code: boundsIndex})
95 }
96
97
98 func goPanicSliceAlen(x int, y int) {
99 panicCheck1(getcallerpc(), "slice bounds out of range")
100 panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAlen})
101 }
102 func goPanicSliceAlenU(x uint, y int) {
103 panicCheck1(getcallerpc(), "slice bounds out of range")
104 panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAlen})
105 }
106 func goPanicSliceAcap(x int, y int) {
107 panicCheck1(getcallerpc(), "slice bounds out of range")
108 panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAcap})
109 }
110 func goPanicSliceAcapU(x uint, y int) {
111 panicCheck1(getcallerpc(), "slice bounds out of range")
112 panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAcap})
113 }
114
115
116 func goPanicSliceB(x int, y int) {
117 panicCheck1(getcallerpc(), "slice bounds out of range")
118 panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceB})
119 }
120 func goPanicSliceBU(x uint, y int) {
121 panicCheck1(getcallerpc(), "slice bounds out of range")
122 panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceB})
123 }
124
125
126 func goPanicSlice3Alen(x int, y int) {
127 panicCheck1(getcallerpc(), "slice bounds out of range")
128 panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Alen})
129 }
130 func goPanicSlice3AlenU(x uint, y int) {
131 panicCheck1(getcallerpc(), "slice bounds out of range")
132 panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Alen})
133 }
134 func goPanicSlice3Acap(x int, y int) {
135 panicCheck1(getcallerpc(), "slice bounds out of range")
136 panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Acap})
137 }
138 func goPanicSlice3AcapU(x uint, y int) {
139 panicCheck1(getcallerpc(), "slice bounds out of range")
140 panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Acap})
141 }
142
143
144 func goPanicSlice3B(x int, y int) {
145 panicCheck1(getcallerpc(), "slice bounds out of range")
146 panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3B})
147 }
148 func goPanicSlice3BU(x uint, y int) {
149 panicCheck1(getcallerpc(), "slice bounds out of range")
150 panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3B})
151 }
152
153
154 func goPanicSlice3C(x int, y int) {
155 panicCheck1(getcallerpc(), "slice bounds out of range")
156 panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3C})
157 }
158 func goPanicSlice3CU(x uint, y int) {
159 panicCheck1(getcallerpc(), "slice bounds out of range")
160 panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3C})
161 }
162
163
164 func goPanicSliceConvert(x int, y int) {
165 panicCheck1(getcallerpc(), "slice length too short to convert to pointer to array")
166 panic(boundsError{x: int64(x), signed: true, y: y, code: boundsConvert})
167 }
168
169
170
171 func panicIndex(x int, y int)
172 func panicIndexU(x uint, y int)
173 func panicSliceAlen(x int, y int)
174 func panicSliceAlenU(x uint, y int)
175 func panicSliceAcap(x int, y int)
176 func panicSliceAcapU(x uint, y int)
177 func panicSliceB(x int, y int)
178 func panicSliceBU(x uint, y int)
179 func panicSlice3Alen(x int, y int)
180 func panicSlice3AlenU(x uint, y int)
181 func panicSlice3Acap(x int, y int)
182 func panicSlice3AcapU(x uint, y int)
183 func panicSlice3B(x int, y int)
184 func panicSlice3BU(x uint, y int)
185 func panicSlice3C(x int, y int)
186 func panicSlice3CU(x uint, y int)
187 func panicSliceConvert(x int, y int)
188
189 var shiftError = error(errorString("negative shift amount"))
190
191 func panicshift() {
192 panicCheck1(getcallerpc(), "negative shift amount")
193 panic(shiftError)
194 }
195
196 var divideError = error(errorString("integer divide by zero"))
197
198 func panicdivide() {
199 panicCheck2("integer divide by zero")
200 panic(divideError)
201 }
202
203 var overflowError = error(errorString("integer overflow"))
204
205 func panicoverflow() {
206 panicCheck2("integer overflow")
207 panic(overflowError)
208 }
209
210 var floatError = error(errorString("floating point error"))
211
212 func panicfloat() {
213 panicCheck2("floating point error")
214 panic(floatError)
215 }
216
217 var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
218
219 func panicmem() {
220 panicCheck2("invalid memory address or nil pointer dereference")
221 panic(memoryError)
222 }
223
224 func panicmemAddr(addr uintptr) {
225 panicCheck2("invalid memory address or nil pointer dereference")
226 panic(errorAddressString{msg: "invalid memory address or nil pointer dereference", addr: addr})
227 }
228
229
230
231
232 func deferproc(siz int32, fn *funcval) {
233 gp := getg()
234 if gp.m.curg != gp {
235
236 throw("defer on system stack")
237 }
238
239 if goexperiment.RegabiDefer && siz != 0 {
240
241 throw("defer with non-empty frame")
242 }
243
244
245
246
247
248
249 sp := getcallersp()
250 argp := uintptr(unsafe.Pointer(&fn)) + unsafe.Sizeof(fn)
251 callerpc := getcallerpc()
252
253 d := newdefer(siz)
254 if d._panic != nil {
255 throw("deferproc: d.panic != nil after newdefer")
256 }
257 d.link = gp._defer
258 gp._defer = d
259 d.fn = fn
260 d.pc = callerpc
261 d.sp = sp
262 switch siz {
263 case 0:
264
265 case sys.PtrSize:
266 *(*uintptr)(deferArgs(d)) = *(*uintptr)(unsafe.Pointer(argp))
267 default:
268 memmove(deferArgs(d), unsafe.Pointer(argp), uintptr(siz))
269 }
270
271
272
273
274
275
276
277 return0()
278
279
280 }
281
282
283
284
285
286
287
288
289
290 func deferprocStack(d *_defer) {
291 gp := getg()
292 if gp.m.curg != gp {
293
294 throw("defer on system stack")
295 }
296 if goexperiment.RegabiDefer && d.siz != 0 {
297 throw("defer with non-empty frame")
298 }
299
300
301
302 d.started = false
303 d.heap = false
304 d.openDefer = false
305 d.sp = getcallersp()
306 d.pc = getcallerpc()
307 d.framepc = 0
308 d.varp = 0
309
310
311
312
313
314
315
316
317
318
319
320 *(*uintptr)(unsafe.Pointer(&d._panic)) = 0
321 *(*uintptr)(unsafe.Pointer(&d.fd)) = 0
322 *(*uintptr)(unsafe.Pointer(&d.link)) = uintptr(unsafe.Pointer(gp._defer))
323 *(*uintptr)(unsafe.Pointer(&gp._defer)) = uintptr(unsafe.Pointer(d))
324
325 return0()
326
327
328 }
329
330
331
332
333
334 const (
335 deferHeaderSize = unsafe.Sizeof(_defer{})
336 minDeferAlloc = (deferHeaderSize + 15) &^ 15
337 minDeferArgs = minDeferAlloc - deferHeaderSize
338 )
339
340
341
342 func deferclass(siz uintptr) uintptr {
343 if siz <= minDeferArgs {
344 return 0
345 }
346 return (siz - minDeferArgs + 15) / 16
347 }
348
349
350 func totaldefersize(siz uintptr) uintptr {
351 if siz <= minDeferArgs {
352 return minDeferAlloc
353 }
354 return deferHeaderSize + siz
355 }
356
357
358
359 func testdefersizes() {
360 var m [len(p{}.deferpool)]int32
361
362 for i := range m {
363 m[i] = -1
364 }
365 for i := uintptr(0); ; i++ {
366 defersc := deferclass(i)
367 if defersc >= uintptr(len(m)) {
368 break
369 }
370 siz := roundupsize(totaldefersize(i))
371 if m[defersc] < 0 {
372 m[defersc] = int32(siz)
373 continue
374 }
375 if m[defersc] != int32(siz) {
376 print("bad defer size class: i=", i, " siz=", siz, " defersc=", defersc, "\n")
377 throw("bad defer size class")
378 }
379 }
380 }
381
382
383
384
385 func deferArgs(d *_defer) unsafe.Pointer {
386 if d.siz == 0 {
387
388 return nil
389 }
390 return add(unsafe.Pointer(d), unsafe.Sizeof(*d))
391 }
392
393
394
395
396
397 func deferFunc(d *_defer) func() {
398 if !goexperiment.RegabiDefer {
399 throw("requires GOEXPERIMENT=regabidefer")
400 }
401 var fn func()
402 *(**funcval)(unsafe.Pointer(&fn)) = d.fn
403 return fn
404 }
405
406 var deferType *_type
407
408 func init() {
409 var x interface{}
410 x = (*_defer)(nil)
411 deferType = (*(**ptrtype)(unsafe.Pointer(&x))).elem
412 }
413
414
415
416
417
418
419
420
421
422 func newdefer(siz int32) *_defer {
423 var d *_defer
424 sc := deferclass(uintptr(siz))
425 gp := getg()
426 if sc < uintptr(len(p{}.deferpool)) {
427 pp := gp.m.p.ptr()
428 if len(pp.deferpool[sc]) == 0 && sched.deferpool[sc] != nil {
429
430
431 systemstack(func() {
432 lock(&sched.deferlock)
433 for len(pp.deferpool[sc]) < cap(pp.deferpool[sc])/2 && sched.deferpool[sc] != nil {
434 d := sched.deferpool[sc]
435 sched.deferpool[sc] = d.link
436 d.link = nil
437 pp.deferpool[sc] = append(pp.deferpool[sc], d)
438 }
439 unlock(&sched.deferlock)
440 })
441 }
442 if n := len(pp.deferpool[sc]); n > 0 {
443 d = pp.deferpool[sc][n-1]
444 pp.deferpool[sc][n-1] = nil
445 pp.deferpool[sc] = pp.deferpool[sc][:n-1]
446 }
447 }
448 if d == nil {
449
450 systemstack(func() {
451 total := roundupsize(totaldefersize(uintptr(siz)))
452 d = (*_defer)(mallocgc(total, deferType, true))
453 })
454 }
455 d.siz = siz
456 d.heap = true
457 return d
458 }
459
460
461
462
463
464
465
466
467 func freedefer(d *_defer) {
468 if d._panic != nil {
469 freedeferpanic()
470 }
471 if d.fn != nil {
472 freedeferfn()
473 }
474 if !d.heap {
475 return
476 }
477 sc := deferclass(uintptr(d.siz))
478 if sc >= uintptr(len(p{}.deferpool)) {
479 return
480 }
481 pp := getg().m.p.ptr()
482 if len(pp.deferpool[sc]) == cap(pp.deferpool[sc]) {
483
484
485
486
487 systemstack(func() {
488 var first, last *_defer
489 for len(pp.deferpool[sc]) > cap(pp.deferpool[sc])/2 {
490 n := len(pp.deferpool[sc])
491 d := pp.deferpool[sc][n-1]
492 pp.deferpool[sc][n-1] = nil
493 pp.deferpool[sc] = pp.deferpool[sc][:n-1]
494 if first == nil {
495 first = d
496 } else {
497 last.link = d
498 }
499 last = d
500 }
501 lock(&sched.deferlock)
502 last.link = sched.deferpool[sc]
503 sched.deferpool[sc] = first
504 unlock(&sched.deferlock)
505 })
506 }
507
508
509
510 d.siz = 0
511 d.started = false
512 d.openDefer = false
513 d.sp = 0
514 d.pc = 0
515 d.framepc = 0
516 d.varp = 0
517 d.fd = nil
518
519
520
521 d.link = nil
522
523 pp.deferpool[sc] = append(pp.deferpool[sc], d)
524 }
525
526
527
528 func freedeferpanic() {
529
530 throw("freedefer with d._panic != nil")
531 }
532
533 func freedeferfn() {
534
535 throw("freedefer with d.fn != nil")
536 }
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552 func deferreturn() {
553 gp := getg()
554 d := gp._defer
555 if d == nil {
556 return
557 }
558 sp := getcallersp()
559 if d.sp != sp {
560 return
561 }
562 if d.openDefer {
563 done := runOpenDeferFrame(gp, d)
564 if !done {
565 throw("unfinished open-coded defers in deferreturn")
566 }
567 gp._defer = d.link
568 freedefer(d)
569 return
570 }
571
572
573
574
575
576
577
578 argp := getcallersp() + sys.MinFrameSize
579 switch d.siz {
580 case 0:
581
582 case sys.PtrSize:
583 *(*uintptr)(unsafe.Pointer(argp)) = *(*uintptr)(deferArgs(d))
584 default:
585 memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz))
586 }
587 fn := d.fn
588 d.fn = nil
589 gp._defer = d.link
590 freedefer(d)
591
592
593
594
595
596 _ = fn.fn
597 jmpdefer(fn, argp)
598 }
599
600
601
602
603
604
605
606
607
608 func Goexit() {
609
610
611
612 gp := getg()
613
614
615
616 var p _panic
617 p.goexit = true
618 p.link = gp._panic
619 gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
620
621 addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp()))
622 for {
623 d := gp._defer
624 if d == nil {
625 break
626 }
627 if d.started {
628 if d._panic != nil {
629 d._panic.aborted = true
630 d._panic = nil
631 }
632 if !d.openDefer {
633 d.fn = nil
634 gp._defer = d.link
635 freedefer(d)
636 continue
637 }
638 }
639 d.started = true
640 d._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
641 if d.openDefer {
642 done := runOpenDeferFrame(gp, d)
643 if !done {
644
645
646
647 throw("unfinished open-coded defers in Goexit")
648 }
649 if p.aborted {
650
651
652
653 addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp()))
654 } else {
655 addOneOpenDeferFrame(gp, 0, nil)
656 }
657 } else {
658 if goexperiment.RegabiDefer {
659
660
661 deferCallSave(&p, deferFunc(d))
662 } else {
663
664
665 reflectcallSave(&p, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz))
666 }
667 }
668 if p.aborted {
669
670
671
672
673
674
675 p.aborted = false
676 continue
677 }
678 if gp._defer != d {
679 throw("bad defer entry in Goexit")
680 }
681 d._panic = nil
682 d.fn = nil
683 gp._defer = d.link
684 freedefer(d)
685
686 }
687 goexit1()
688 }
689
690
691
692 func preprintpanics(p *_panic) {
693 defer func() {
694 if recover() != nil {
695 throw("panic while printing panic value")
696 }
697 }()
698 for p != nil {
699 switch v := p.arg.(type) {
700 case error:
701 p.arg = v.Error()
702 case stringer:
703 p.arg = v.String()
704 }
705 p = p.link
706 }
707 }
708
709
710
711 func printpanics(p *_panic) {
712 if p.link != nil {
713 printpanics(p.link)
714 if !p.link.goexit {
715 print("\t")
716 }
717 }
718 if p.goexit {
719 return
720 }
721 print("panic: ")
722 printany(p.arg)
723 if p.recovered {
724 print(" [recovered]")
725 }
726 print("\n")
727 }
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743 func addOneOpenDeferFrame(gp *g, pc uintptr, sp unsafe.Pointer) {
744 var prevDefer *_defer
745 if sp == nil {
746 prevDefer = gp._defer
747 pc = prevDefer.framepc
748 sp = unsafe.Pointer(prevDefer.sp)
749 }
750 systemstack(func() {
751 gentraceback(pc, uintptr(sp), 0, gp, 0, nil, 0x7fffffff,
752 func(frame *stkframe, unused unsafe.Pointer) bool {
753 if prevDefer != nil && prevDefer.sp == frame.sp {
754
755
756
757 return true
758 }
759 f := frame.fn
760 fd := funcdata(f, _FUNCDATA_OpenCodedDeferInfo)
761 if fd == nil {
762 return true
763 }
764
765
766 d := gp._defer
767 var prev *_defer
768 for d != nil {
769 dsp := d.sp
770 if frame.sp < dsp {
771 break
772 }
773 if frame.sp == dsp {
774 if !d.openDefer {
775 throw("duplicated defer entry")
776 }
777 return true
778 }
779 prev = d
780 d = d.link
781 }
782 if frame.fn.deferreturn == 0 {
783 throw("missing deferreturn")
784 }
785
786 maxargsize, _ := readvarintUnsafe(fd)
787 d1 := newdefer(int32(maxargsize))
788 d1.openDefer = true
789 d1._panic = nil
790
791
792
793
794
795
796 d1.pc = frame.fn.entry + uintptr(frame.fn.deferreturn)
797 d1.varp = frame.varp
798 d1.fd = fd
799
800
801 d1.framepc = frame.pc
802 d1.sp = frame.sp
803 d1.link = d
804 if prev == nil {
805 gp._defer = d1
806 } else {
807 prev.link = d1
808 }
809
810 return false
811 },
812 nil, 0)
813 })
814 }
815
816
817
818
819
820
821
822
823 func readvarintUnsafe(fd unsafe.Pointer) (uint32, unsafe.Pointer) {
824 var r uint32
825 var shift int
826 for {
827 b := *(*uint8)((unsafe.Pointer(fd)))
828 fd = add(fd, unsafe.Sizeof(b))
829 if b < 128 {
830 return r + uint32(b)<<shift, fd
831 }
832 r += ((uint32(b) &^ 128) << shift)
833 shift += 7
834 if shift > 28 {
835 panic("Bad varint")
836 }
837 }
838 }
839
840
841
842
843
844 func runOpenDeferFrame(gp *g, d *_defer) bool {
845 done := true
846 fd := d.fd
847
848
849 _, fd = readvarintUnsafe(fd)
850 deferBitsOffset, fd := readvarintUnsafe(fd)
851 nDefers, fd := readvarintUnsafe(fd)
852 deferBits := *(*uint8)(unsafe.Pointer(d.varp - uintptr(deferBitsOffset)))
853
854 for i := int(nDefers) - 1; i >= 0; i-- {
855
856 var argWidth, closureOffset, nArgs uint32
857 argWidth, fd = readvarintUnsafe(fd)
858 closureOffset, fd = readvarintUnsafe(fd)
859 nArgs, fd = readvarintUnsafe(fd)
860 if goexperiment.RegabiDefer && argWidth != 0 {
861 throw("defer with non-empty frame")
862 }
863 if deferBits&(1<<i) == 0 {
864 for j := uint32(0); j < nArgs; j++ {
865 _, fd = readvarintUnsafe(fd)
866 _, fd = readvarintUnsafe(fd)
867 _, fd = readvarintUnsafe(fd)
868 }
869 continue
870 }
871 closure := *(**funcval)(unsafe.Pointer(d.varp - uintptr(closureOffset)))
872 d.fn = closure
873 deferArgs := deferArgs(d)
874
875
876 for j := uint32(0); j < nArgs; j++ {
877 var argOffset, argLen, argCallOffset uint32
878 argOffset, fd = readvarintUnsafe(fd)
879 argLen, fd = readvarintUnsafe(fd)
880 argCallOffset, fd = readvarintUnsafe(fd)
881 memmove(unsafe.Pointer(uintptr(deferArgs)+uintptr(argCallOffset)),
882 unsafe.Pointer(d.varp-uintptr(argOffset)),
883 uintptr(argLen))
884 }
885 deferBits = deferBits &^ (1 << i)
886 *(*uint8)(unsafe.Pointer(d.varp - uintptr(deferBitsOffset))) = deferBits
887 p := d._panic
888 if goexperiment.RegabiDefer {
889 deferCallSave(p, deferFunc(d))
890 } else {
891 reflectcallSave(p, unsafe.Pointer(closure), deferArgs, argWidth)
892 }
893 if p != nil && p.aborted {
894 break
895 }
896 d.fn = nil
897
898 memclrNoHeapPointers(deferArgs, uintptr(argWidth))
899 if d._panic != nil && d._panic.recovered {
900 done = deferBits == 0
901 break
902 }
903 }
904
905 return done
906 }
907
908
909
910
911
912
913
914
915 func reflectcallSave(p *_panic, fn, arg unsafe.Pointer, argsize uint32) {
916 if goexperiment.RegabiDefer {
917 throw("not allowed with GOEXPERIMENT=regabidefer")
918 }
919 if p != nil {
920 p.argp = unsafe.Pointer(getargp())
921 p.pc = getcallerpc()
922 p.sp = unsafe.Pointer(getcallersp())
923 }
924
925
926 var regs abi.RegArgs
927 reflectcall(nil, fn, arg, argsize, argsize, argsize, ®s)
928 if p != nil {
929 p.pc = 0
930 p.sp = unsafe.Pointer(nil)
931 }
932 }
933
934
935
936
937
938
939
940
941 func deferCallSave(p *_panic, fn func()) {
942 if !goexperiment.RegabiDefer {
943 throw("only allowed with GOEXPERIMENT=regabidefer")
944 }
945 if p != nil {
946 p.argp = unsafe.Pointer(getargp())
947 p.pc = getcallerpc()
948 p.sp = unsafe.Pointer(getcallersp())
949 }
950 fn()
951 if p != nil {
952 p.pc = 0
953 p.sp = unsafe.Pointer(nil)
954 }
955 }
956
957
958 func gopanic(e interface{}) {
959 gp := getg()
960 if gp.m.curg != gp {
961 print("panic: ")
962 printany(e)
963 print("\n")
964 throw("panic on system stack")
965 }
966
967 if gp.m.mallocing != 0 {
968 print("panic: ")
969 printany(e)
970 print("\n")
971 throw("panic during malloc")
972 }
973 if gp.m.preemptoff != "" {
974 print("panic: ")
975 printany(e)
976 print("\n")
977 print("preempt off reason: ")
978 print(gp.m.preemptoff)
979 print("\n")
980 throw("panic during preemptoff")
981 }
982 if gp.m.locks != 0 {
983 print("panic: ")
984 printany(e)
985 print("\n")
986 throw("panic holding locks")
987 }
988
989 var p _panic
990 p.arg = e
991 p.link = gp._panic
992 gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
993
994 atomic.Xadd(&runningPanicDefers, 1)
995
996
997
998 addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp()))
999
1000 for {
1001 d := gp._defer
1002 if d == nil {
1003 break
1004 }
1005
1006
1007
1008
1009 if d.started {
1010 if d._panic != nil {
1011 d._panic.aborted = true
1012 }
1013 d._panic = nil
1014 if !d.openDefer {
1015
1016
1017
1018
1019 d.fn = nil
1020 gp._defer = d.link
1021 freedefer(d)
1022 continue
1023 }
1024 }
1025
1026
1027
1028
1029 d.started = true
1030
1031
1032
1033
1034 d._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
1035
1036 done := true
1037 if d.openDefer {
1038 done = runOpenDeferFrame(gp, d)
1039 if done && !d._panic.recovered {
1040 addOneOpenDeferFrame(gp, 0, nil)
1041 }
1042 } else {
1043 p.argp = unsafe.Pointer(getargp())
1044
1045 if goexperiment.RegabiDefer {
1046 fn := deferFunc(d)
1047 fn()
1048 } else {
1049
1050
1051 var regs abi.RegArgs
1052 reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz), uint32(d.siz), ®s)
1053 }
1054 }
1055 p.argp = nil
1056
1057
1058 if gp._defer != d {
1059 throw("bad defer entry in panic")
1060 }
1061 d._panic = nil
1062
1063
1064
1065
1066 pc := d.pc
1067 sp := unsafe.Pointer(d.sp)
1068 if done {
1069 d.fn = nil
1070 gp._defer = d.link
1071 freedefer(d)
1072 }
1073 if p.recovered {
1074 gp._panic = p.link
1075 if gp._panic != nil && gp._panic.goexit && gp._panic.aborted {
1076
1077
1078 gp.sigcode0 = uintptr(gp._panic.sp)
1079 gp.sigcode1 = uintptr(gp._panic.pc)
1080 mcall(recovery)
1081 throw("bypassed recovery failed")
1082 }
1083 atomic.Xadd(&runningPanicDefers, -1)
1084
1085
1086
1087
1088
1089
1090
1091 d := gp._defer
1092 var prev *_defer
1093 if !done {
1094
1095
1096
1097 prev = d
1098 d = d.link
1099 }
1100 for d != nil {
1101 if d.started {
1102
1103
1104
1105
1106
1107 break
1108 }
1109 if d.openDefer {
1110 if prev == nil {
1111 gp._defer = d.link
1112 } else {
1113 prev.link = d.link
1114 }
1115 newd := d.link
1116 freedefer(d)
1117 d = newd
1118 } else {
1119 prev = d
1120 d = d.link
1121 }
1122 }
1123
1124 gp._panic = p.link
1125
1126
1127 for gp._panic != nil && gp._panic.aborted {
1128 gp._panic = gp._panic.link
1129 }
1130 if gp._panic == nil {
1131 gp.sig = 0
1132 }
1133
1134 gp.sigcode0 = uintptr(sp)
1135 gp.sigcode1 = pc
1136 mcall(recovery)
1137 throw("recovery failed")
1138 }
1139 }
1140
1141
1142
1143
1144
1145 preprintpanics(gp._panic)
1146
1147 fatalpanic(gp._panic)
1148 *(*int)(nil) = 0
1149 }
1150
1151
1152
1153
1154
1155 func getargp() uintptr {
1156 return getcallersp() + sys.MinFrameSize
1157 }
1158
1159
1160
1161
1162
1163
1164
1165
1166 func gorecover(argp uintptr) interface{} {
1167
1168
1169
1170
1171
1172
1173 gp := getg()
1174 p := gp._panic
1175 if p != nil && !p.goexit && !p.recovered && argp == uintptr(p.argp) {
1176 p.recovered = true
1177 return p.arg
1178 }
1179 return nil
1180 }
1181
1182
1183 func sync_throw(s string) {
1184 throw(s)
1185 }
1186
1187
1188 func throw(s string) {
1189
1190
1191 systemstack(func() {
1192 print("fatal error: ", s, "\n")
1193 })
1194 gp := getg()
1195 if gp.m.throwing == 0 {
1196 gp.m.throwing = 1
1197 }
1198 fatalthrow()
1199 *(*int)(nil) = 0
1200 }
1201
1202
1203
1204
1205 var runningPanicDefers uint32
1206
1207
1208
1209 var panicking uint32
1210
1211
1212
1213 var paniclk mutex
1214
1215
1216
1217
1218 func recovery(gp *g) {
1219
1220 sp := gp.sigcode0
1221 pc := gp.sigcode1
1222
1223
1224 if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
1225 print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
1226 throw("bad recovery")
1227 }
1228
1229
1230
1231
1232 gp.sched.sp = sp
1233 gp.sched.pc = pc
1234 gp.sched.lr = 0
1235 gp.sched.ret = 1
1236 gogo(&gp.sched)
1237 }
1238
1239
1240
1241
1242
1243
1244 func fatalthrow() {
1245 pc := getcallerpc()
1246 sp := getcallersp()
1247 gp := getg()
1248
1249
1250 systemstack(func() {
1251 startpanic_m()
1252
1253 if dopanic_m(gp, pc, sp) {
1254
1255
1256
1257 crash()
1258 }
1259
1260 exit(2)
1261 })
1262
1263 *(*int)(nil) = 0
1264 }
1265
1266
1267
1268
1269
1270
1271 func fatalpanic(msgs *_panic) {
1272 pc := getcallerpc()
1273 sp := getcallersp()
1274 gp := getg()
1275 var docrash bool
1276
1277
1278 systemstack(func() {
1279 if startpanic_m() && msgs != nil {
1280
1281
1282
1283
1284
1285
1286 atomic.Xadd(&runningPanicDefers, -1)
1287
1288 printpanics(msgs)
1289 }
1290
1291 docrash = dopanic_m(gp, pc, sp)
1292 })
1293
1294 if docrash {
1295
1296
1297
1298 crash()
1299 }
1300
1301 systemstack(func() {
1302 exit(2)
1303 })
1304
1305 *(*int)(nil) = 0
1306 }
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320 func startpanic_m() bool {
1321 _g_ := getg()
1322 if mheap_.cachealloc.size == 0 {
1323 print("runtime: panic before malloc heap initialized\n")
1324 }
1325
1326
1327
1328
1329 _g_.m.mallocing++
1330
1331
1332
1333 if _g_.m.locks < 0 {
1334 _g_.m.locks = 1
1335 }
1336
1337 switch _g_.m.dying {
1338 case 0:
1339
1340 _g_.m.dying = 1
1341 atomic.Xadd(&panicking, 1)
1342 lock(&paniclk)
1343 if debug.schedtrace > 0 || debug.scheddetail > 0 {
1344 schedtrace(true)
1345 }
1346 freezetheworld()
1347 return true
1348 case 1:
1349
1350
1351 _g_.m.dying = 2
1352 print("panic during panic\n")
1353 return false
1354 case 2:
1355
1356
1357 _g_.m.dying = 3
1358 print("stack trace unavailable\n")
1359 exit(4)
1360 fallthrough
1361 default:
1362
1363 exit(5)
1364 return false
1365 }
1366 }
1367
1368 var didothers bool
1369 var deadlock mutex
1370
1371 func dopanic_m(gp *g, pc, sp uintptr) bool {
1372 if gp.sig != 0 {
1373 signame := signame(gp.sig)
1374 if signame != "" {
1375 print("[signal ", signame)
1376 } else {
1377 print("[signal ", hex(gp.sig))
1378 }
1379 print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
1380 }
1381
1382 level, all, docrash := gotraceback()
1383 _g_ := getg()
1384 if level > 0 {
1385 if gp != gp.m.curg {
1386 all = true
1387 }
1388 if gp != gp.m.g0 {
1389 print("\n")
1390 goroutineheader(gp)
1391 traceback(pc, sp, 0, gp)
1392 } else if level >= 2 || _g_.m.throwing > 0 {
1393 print("\nruntime stack:\n")
1394 traceback(pc, sp, 0, gp)
1395 }
1396 if !didothers && all {
1397 didothers = true
1398 tracebackothers(gp)
1399 }
1400 }
1401 unlock(&paniclk)
1402
1403 if atomic.Xadd(&panicking, -1) != 0 {
1404
1405
1406
1407
1408 lock(&deadlock)
1409 lock(&deadlock)
1410 }
1411
1412 printDebugLog()
1413
1414 return docrash
1415 }
1416
1417
1418
1419
1420
1421 func canpanic(gp *g) bool {
1422
1423
1424
1425 _g_ := getg()
1426 _m_ := _g_.m
1427
1428
1429
1430
1431 if gp == nil || gp != _m_.curg {
1432 return false
1433 }
1434 if _m_.locks != 0 || _m_.mallocing != 0 || _m_.throwing != 0 || _m_.preemptoff != "" || _m_.dying != 0 {
1435 return false
1436 }
1437 status := readgstatus(gp)
1438 if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
1439 return false
1440 }
1441 if GOOS == "windows" && _m_.libcallsp != 0 {
1442 return false
1443 }
1444 return true
1445 }
1446
1447
1448
1449
1450
1451
1452 func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
1453 if pc == 0 {
1454
1455
1456
1457
1458
1459 return false
1460 }
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470 if gp.m.incgo || findfunc(pc).valid() {
1471
1472
1473 return true
1474 }
1475 if findfunc(lr).valid() {
1476
1477
1478 return false
1479 }
1480
1481
1482 return true
1483 }
1484
1485
1486
1487
1488
1489
1490
1491
1492 func isAbortPC(pc uintptr) bool {
1493 f := findfunc(pc)
1494 if !f.valid() {
1495 return false
1496 }
1497 return f.funcID == funcID_abort
1498 }
1499
View as plain text