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