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