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