github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/runtime/panic.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime 6 7 import ( 8 "internal/goarch" 9 "runtime/internal/atomic" 10 "runtime/internal/sys" 11 "unsafe" 12 ) 13 14 // throwType indicates the current type of ongoing throw, which affects the 15 // amount of detail printed to stderr. Higher values include more detail. 16 type throwType uint32 17 18 const ( 19 // throwTypeNone means that we are not throwing. 20 throwTypeNone throwType = iota 21 22 // throwTypeUser is a throw due to a problem with the application. 23 // 24 // These throws do not include runtime frames, system goroutines, or 25 // frame metadata. 26 throwTypeUser 27 28 // throwTypeRuntime is a throw due to a problem with Go itself. 29 // 30 // These throws include as much information as possible to aid in 31 // debugging the runtime, including runtime frames, system goroutines, 32 // and frame metadata. 33 throwTypeRuntime 34 ) 35 36 // We have two different ways of doing defers. The older way involves creating a 37 // defer record at the time that a defer statement is executing and adding it to a 38 // defer chain. This chain is inspected by the deferreturn call at all function 39 // exits in order to run the appropriate defer calls. A cheaper way (which we call 40 // open-coded defers) is used for functions in which no defer statements occur in 41 // loops. In that case, we simply store the defer function/arg information into 42 // specific stack slots at the point of each defer statement, as well as setting a 43 // bit in a bitmask. At each function exit, we add inline code to directly make 44 // the appropriate defer calls based on the bitmask and fn/arg information stored 45 // on the stack. During panic/Goexit processing, the appropriate defer calls are 46 // made using extra funcdata info that indicates the exact stack slots that 47 // contain the bitmask and defer fn/args. 48 49 // Check to make sure we can really generate a panic. If the panic 50 // was generated from the runtime, or from inside malloc, then convert 51 // to a throw of msg. 52 // pc should be the program counter of the compiler-generated code that 53 // triggered this panic. 54 func panicCheck1(pc uintptr, msg string) { 55 if goarch.IsWasm == 0 && hasPrefix(funcname(findfunc(pc)), "runtime.") { 56 // Note: wasm can't tail call, so we can't get the original caller's pc. 57 throw(msg) 58 } 59 // TODO: is this redundant? How could we be in malloc 60 // but not in the runtime? runtime/internal/*, maybe? 61 gp := getg() 62 if gp != nil && gp.m != nil && gp.m.mallocing != 0 { 63 throw(msg) 64 } 65 } 66 67 // Same as above, but calling from the runtime is allowed. 68 // 69 // Using this function is necessary for any panic that may be 70 // generated by runtime.sigpanic, since those are always called by the 71 // runtime. 72 func panicCheck2(err string) { 73 // panic allocates, so to avoid recursive malloc, turn panics 74 // during malloc into throws. 75 gp := getg() 76 if gp != nil && gp.m != nil && gp.m.mallocing != 0 { 77 throw(err) 78 } 79 } 80 81 // Many of the following panic entry-points turn into throws when they 82 // happen in various runtime contexts. These should never happen in 83 // the runtime, and if they do, they indicate a serious issue and 84 // should not be caught by user code. 85 // 86 // The panic{Index,Slice,divide,shift} functions are called by 87 // code generated by the compiler for out of bounds index expressions, 88 // out of bounds slice expressions, division by zero, and shift by negative. 89 // The panicdivide (again), panicoverflow, panicfloat, and panicmem 90 // functions are called by the signal handler when a signal occurs 91 // indicating the respective problem. 92 // 93 // Since panic{Index,Slice,shift} are never called directly, and 94 // since the runtime package should never have an out of bounds slice 95 // or array reference or negative shift, if we see those functions called from the 96 // runtime package we turn the panic into a throw. That will dump the 97 // entire runtime stack for easier debugging. 98 // 99 // The entry points called by the signal handler will be called from 100 // runtime.sigpanic, so we can't disallow calls from the runtime to 101 // these (they always look like they're called from the runtime). 102 // Hence, for these, we just check for clearly bad runtime conditions. 103 // 104 // The panic{Index,Slice} functions are implemented in assembly and tail call 105 // to the goPanic{Index,Slice} functions below. This is done so we can use 106 // a space-minimal register calling convention. 107 108 // failures in the comparisons for s[x], 0 <= x < y (y == len(s)) 109 // 110 //go:yeswritebarrierrec 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 //go:yeswritebarrierrec 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 // failures in the comparisons for s[:x], 0 <= x <= y (y == len(s) or cap(s)) 123 // 124 //go:yeswritebarrierrec 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 //go:yeswritebarrierrec 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 //go:yeswritebarrierrec 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 //go:yeswritebarrierrec 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 // failures in the comparisons for s[x:y], 0 <= x <= y 149 // 150 //go:yeswritebarrierrec 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 //go:yeswritebarrierrec 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 // failures in the comparisons for s[::x], 0 <= x <= y (y == len(s) or cap(s)) 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 // failures in the comparisons for s[:x:y], 0 <= x <= y 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 // failures in the comparisons for s[x:y:], 0 <= x <= y 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 // failures in the conversion ([x]T)(s) or (*[x]T)(s), 0 <= x <= y, y == len(s) 201 func goPanicSliceConvert(x int, y int) { 202 panicCheck1(getcallerpc(), "slice length too short to convert to array or pointer to array") 203 panic(boundsError{x: int64(x), signed: true, y: y, code: boundsConvert}) 204 } 205 206 // Implemented in assembly, as they take arguments in registers. 207 // Declared here to mark them as ABIInternal. 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 //go:yeswritebarrierrec 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 //go:yeswritebarrierrec 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 // Create a new deferred function fn, which has no arguments and results. 269 // The compiler turns a defer statement into a call to this. 270 func deferproc(fn func()) { 271 gp := getg() 272 if gp.m.curg != gp { 273 // go code on the system stack can't defer 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 // We must not be preempted between calling getcallersp and 286 // storing it to d.sp because getcallersp's result is a 287 // uintptr stack pointer. 288 d.sp = getcallersp() 289 290 // deferproc returns 0 normally. 291 // a deferred func that stops a panic 292 // makes the deferproc return 1. 293 // the code the compiler generates always 294 // checks the return value and jumps to the 295 // end of the function if deferproc returns != 0. 296 return0() 297 // No code can go here - the C return register has 298 // been set and must not be clobbered. 299 } 300 301 // deferprocStack queues a new deferred function with a defer record on the stack. 302 // The defer record must have its fn field initialized. 303 // All other fields can contain junk. 304 // Nosplit because of the uninitialized pointer fields on the stack. 305 // 306 //go:nosplit 307 func deferprocStack(d *_defer) { 308 gp := getg() 309 if gp.m.curg != gp { 310 // go code on the system stack can't defer 311 throw("defer on system stack") 312 } 313 // fn is already set. 314 // The other fields are junk on entry to deferprocStack and 315 // are initialized here. 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 // The lines below implement: 324 // d.panic = nil 325 // d.fd = nil 326 // d.link = gp._defer 327 // gp._defer = d 328 // But without write barriers. The first three are writes to 329 // the stack so they don't need a write barrier, and furthermore 330 // are to uninitialized memory, so they must not use a write barrier. 331 // The fourth write does not require a write barrier because we 332 // explicitly mark all the defer structures, so we don't need to 333 // keep track of pointers to them with a write barrier. 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 // No code can go here - the C return register has 341 // been set and must not be clobbered. 342 } 343 344 // Each P holds a pool for defers. 345 346 // Allocate a Defer, usually using per-P pool. 347 // Each defer must be released with freedefer. The defer is not 348 // added to any defer chain yet. 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 // Allocate new defer. 373 d = new(_defer) 374 } 375 d.heap = true 376 return d 377 } 378 379 // Free the given defer. 380 // The defer cannot be used after this call. 381 // 382 // This is nosplit because the incoming defer is in a perilous state. 383 // It's not on any defer list, so stack copying won't adjust stack 384 // pointers in it (namely, d.link). Hence, if we were to copy the 385 // stack, d could then contain a stale pointer. 386 // 387 //go:nosplit 388 func freedefer(d *_defer) { 389 d.link = nil 390 // After this point we can copy the stack. 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 // Transfer half of local cache to the central cache. 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 // Separate function so that it can split stack. 434 // Windows otherwise runs out of stack space. 435 func freedeferpanic() { 436 // _panic must be cleared before d is unlinked from gp. 437 throw("freedefer with d._panic != nil") 438 } 439 440 func freedeferfn() { 441 // fn must be cleared before d is unlinked from gp. 442 throw("freedefer with d.fn != nil") 443 } 444 445 // deferreturn runs deferred functions for the caller's frame. 446 // The compiler inserts a call to this at the end of any 447 // function which calls defer. 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(d) 461 if !done { 462 throw("unfinished open-coded defers in deferreturn") 463 } 464 gp._defer = d.link 465 freedefer(d) 466 // If this frame uses open defers, then this 467 // must be the only defer record for the 468 // frame, so we can just return. 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 // Goexit terminates the goroutine that calls it. No other goroutine is affected. 481 // Goexit runs all deferred calls before terminating the goroutine. Because Goexit 482 // is not a panic, any recover calls in those deferred functions will return nil. 483 // 484 // Calling Goexit from the main goroutine terminates that goroutine 485 // without func main returning. Since func main has not returned, 486 // the program continues execution of other goroutines. 487 // If all other goroutines exit, the program crashes. 488 func Goexit() { 489 // Run all deferred functions for the current goroutine. 490 // This code is similar to gopanic, see that implementation 491 // for detailed comments. 492 gp := getg() 493 494 // Create a panic object for Goexit, so we can recognize when it might be 495 // bypassed by a recover(). 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(d) 523 if !done { 524 // We should always run all defers in the frame, 525 // since there is no panic associated with this 526 // defer that can be recovered. 527 throw("unfinished open-coded defers in Goexit") 528 } 529 if p.aborted { 530 // Since our current defer caused a panic and may 531 // have been already freed, just restart scanning 532 // for open-coded defers from this frame again. 533 addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp())) 534 } else { 535 addOneOpenDeferFrame(gp, 0, nil) 536 } 537 } else { 538 // Save the pc/sp in deferCallSave(), so we can "recover" back to this 539 // loop if necessary. 540 deferCallSave(&p, d.fn) 541 } 542 if p.aborted { 543 // We had a recursive panic in the defer d we started, and 544 // then did a recover in a defer that was further down the 545 // defer chain than d. In the case of an outstanding Goexit, 546 // we force the recover to return back to this loop. d will 547 // have already been freed if completed, so just continue 548 // immediately to the next defer on the chain. 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 // Note: we ignore recovers here because Goexit isn't a panic 560 } 561 goexit1() 562 } 563 564 // Call all Error and String methods before freezing the world. 565 // Used when crashing with panicking. 566 func preprintpanics(p *_panic) { 567 defer func() { 568 text := "panic while printing panic value" 569 switch r := recover().(type) { 570 case nil: 571 // nothing to do 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 // Print all currently active panics. Used when crashing. 590 // Should only be called after preprintpanics. 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 // addOneOpenDeferFrame scans the stack (in gentraceback order, from inner frames to 610 // outer frames) for the first frame (if any) with open-coded defers. If it finds 611 // one, it adds a single entry to the defer chain for that frame. The entry added 612 // represents all the defers in the associated open defer frame, and is sorted in 613 // order with respect to any non-open-coded defers. 614 // 615 // addOneOpenDeferFrame stops (possibly without adding a new entry) if it encounters 616 // an in-progress open defer entry. An in-progress open defer entry means there has 617 // been a new panic because of a defer in the associated frame. addOneOpenDeferFrame 618 // does not add an open defer entry past a started entry, because that started entry 619 // still needs to finished, and addOneOpenDeferFrame will be called when that started 620 // entry is completed. The defer removal loop in gopanic() similarly stops at an 621 // in-progress defer entry. Together, addOneOpenDeferFrame and the defer removal loop 622 // ensure the invariant that there is no open defer entry further up the stack than 623 // an in-progress defer, and also that the defer removal loop is guaranteed to remove 624 // all not-in-progress open defer entries from the defer chain. 625 // 626 // If sp is non-nil, addOneOpenDeferFrame starts the stack scan from the frame 627 // specified by sp. If sp is nil, it uses the sp from the current defer record (which 628 // has just been finished). Hence, it continues the stack scan from the frame of the 629 // defer that just finished. It skips any frame that already has a (not-in-progress) 630 // open-coded _defer record in the defer chain. 631 // 632 // Note: All entries of the defer chain (including this new open-coded entry) have 633 // their pointers (including sp) adjusted properly if the stack moves while 634 // running deferred functions. Also, it is safe to pass in the sp arg (which is 635 // the direct result of calling getcallersp()), because all pointer variables 636 // (including arguments) are adjusted as needed during stack copies. 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 // Skip the frame for the previous defer that 649 // we just finished (and was used to set 650 // where we restarted the stack scan) 651 return true 652 } 653 f := frame.fn 654 fd := funcdata(f, _FUNCDATA_OpenCodedDeferInfo) 655 if fd == nil { 656 return true 657 } 658 // Insert the open defer record in the 659 // chain, in order sorted by sp. 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 // Don't add any record past an 672 // in-progress defer entry. We don't 673 // need it, and more importantly, we 674 // want to keep the invariant that 675 // there is no open defer entry 676 // passed an in-progress entry (see 677 // header comment). 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 // These are the pc/sp to set after we've 694 // run a defer in this frame that did a 695 // recover. We return to a special 696 // deferreturn that runs any remaining 697 // defers and then returns from the 698 // function. 699 d1.pc = frame.fn.entry() + uintptr(frame.fn.deferreturn) 700 d1.varp = frame.varp 701 d1.fd = fd 702 // Save the SP/PC associated with current frame, 703 // so we can continue stack trace later if needed. 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 // Stop stack scanning after adding one open defer record 713 return false 714 }, 715 nil, 0) 716 }) 717 } 718 719 // readvarintUnsafe reads the uint32 in varint format starting at fd, and returns the 720 // uint32 and a pointer to the byte following the varint. 721 // 722 // There is a similar function runtime.readvarint, which takes a slice of bytes, 723 // rather than an unsafe pointer. These functions are duplicated, because one of 724 // the two use cases for the functions would get slower if the functions were 725 // combined. 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 // runOpenDeferFrame runs the active open-coded defers in the frame specified by 744 // d. It normally processes all active defers in the frame, but stops immediately 745 // if a defer does a successful recover. It returns true if there are no 746 // remaining defers to run in the frame. 747 func runOpenDeferFrame(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 // read the funcdata info for this defer 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 // Call the defer. Note that this can change d.varp if 768 // the stack moves. 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 // deferCallSave calls fn() after saving the caller's pc and sp in the 784 // panic record. This allows the runtime to return to the Goexit defer 785 // processing loop, in the unusual case where the Goexit may be 786 // bypassed by a successful recover. 787 // 788 // This is marked as a wrapper by the compiler so it doesn't appear in 789 // tracebacks. 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 // The implementation of the predeclared function panic. 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 runningPanicDefers.Add(1) 841 842 // By calculating getcallerpc/getcallersp here, we avoid scanning the 843 // gopanic frame (stack scanning is slow...) 844 addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp())) 845 846 for { 847 d := gp._defer 848 if d == nil { 849 break 850 } 851 852 // If defer was started by earlier panic or Goexit (and, since we're back here, that triggered a new panic), 853 // take defer off list. An earlier panic will not continue running, but we will make sure below that an 854 // earlier Goexit does continue running. 855 if d.started { 856 if d._panic != nil { 857 d._panic.aborted = true 858 } 859 d._panic = nil 860 if !d.openDefer { 861 // For open-coded defers, we need to process the 862 // defer again, in case there are any other defers 863 // to call in the frame (not including the defer 864 // call that caused the panic). 865 d.fn = nil 866 gp._defer = d.link 867 freedefer(d) 868 continue 869 } 870 } 871 872 // Mark defer as started, but keep on list, so that traceback 873 // can find and update the defer's argument frame if stack growth 874 // or a garbage collection happens before executing d.fn. 875 d.started = true 876 877 // Record the panic that is running the defer. 878 // If there is a new panic during the deferred call, that panic 879 // will find d in the list and will mark d._panic (this panic) aborted. 880 d._panic = (*_panic)(noescape(unsafe.Pointer(&p))) 881 882 done := true 883 if d.openDefer { 884 done = runOpenDeferFrame(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 // Deferred function did not panic. Remove d. 895 if gp._defer != d { 896 throw("bad defer entry in panic") 897 } 898 d._panic = nil 899 900 // trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic 901 //GC() 902 903 pc := d.pc 904 sp := unsafe.Pointer(d.sp) // must be pointer so it gets adjusted during stack copy 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 // A normal recover would bypass/abort the Goexit. Instead, 914 // we return to the processing loop of the Goexit. 915 gp.sigcode0 = uintptr(gp._panic.sp) 916 gp.sigcode1 = uintptr(gp._panic.pc) 917 mcall(recovery) 918 throw("bypassed recovery failed") // mcall should not return 919 } 920 runningPanicDefers.Add(-1) 921 922 // After a recover, remove any remaining non-started, 923 // open-coded defer entries, since the corresponding defers 924 // will be executed normally (inline). Any such entry will 925 // become stale once we run the corresponding defers inline 926 // and exit the associated stack frame. We only remove up to 927 // the first started (in-progress) open defer entry, not 928 // including the current frame, since any higher entries will 929 // be from a higher panic in progress, and will still be 930 // needed. 931 d := gp._defer 932 var prev *_defer 933 if !done { 934 // Skip our current frame, if not done. It is 935 // needed to complete any remaining defers in 936 // deferreturn() 937 prev = d 938 d = d.link 939 } 940 for d != nil { 941 if d.started { 942 // This defer is started but we 943 // are in the middle of a 944 // defer-panic-recover inside of 945 // it, so don't remove it or any 946 // further defer entries 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 // Aborted panics are marked but remain on the g.panic list. 966 // Remove them from the list. 967 for gp._panic != nil && gp._panic.aborted { 968 gp._panic = gp._panic.link 969 } 970 if gp._panic == nil { // must be done with signal 971 gp.sig = 0 972 } 973 // Pass information about recovering frame to recovery. 974 gp.sigcode0 = uintptr(sp) 975 gp.sigcode1 = pc 976 mcall(recovery) 977 throw("recovery failed") // mcall should not return 978 } 979 } 980 981 // ran out of deferred calls - old-school panic now 982 // Because it is unsafe to call arbitrary user code after freezing 983 // the world, we call preprintpanics to invoke all necessary Error 984 // and String methods to prepare the panic strings before startpanic. 985 preprintpanics(gp._panic) 986 987 fatalpanic(gp._panic) // should not return 988 *(*int)(nil) = 0 // not reached 989 } 990 991 // getargp returns the location where the caller 992 // writes outgoing function call arguments. 993 // 994 //go:nosplit 995 //go:noinline 996 func getargp() uintptr { 997 return getcallersp() + sys.MinFrameSize 998 } 999 1000 // The implementation of the predeclared function recover. 1001 // Cannot split the stack because it needs to reliably 1002 // find the stack segment of its caller. 1003 // 1004 // TODO(rsc): Once we commit to CopyStackAlways, 1005 // this doesn't need to be nosplit. 1006 // 1007 //go:nosplit 1008 func gorecover(argp uintptr) any { 1009 // Must be in a function running as part of a deferred call during the panic. 1010 // Must be called from the topmost function of the call 1011 // (the function used in the defer statement). 1012 // p.argp is the argument pointer of that topmost deferred function call. 1013 // Compare against argp reported by caller. 1014 // If they match, the caller is the one who can recover. 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 //go:linkname sync_throw sync.throw 1025 func sync_throw(s string) { 1026 throw(s) 1027 } 1028 1029 //go:linkname sync_fatal sync.fatal 1030 func sync_fatal(s string) { 1031 fatal(s) 1032 } 1033 1034 // throw triggers a fatal error that dumps a stack trace and exits. 1035 // 1036 // throw should be used for runtime-internal fatal errors where Go itself, 1037 // rather than user code, may be at fault for the failure. 1038 // 1039 //go:nosplit 1040 func throw(s string) { 1041 // Everything throw does should be recursively nosplit so it 1042 // can be called even when it's unsafe to grow the stack. 1043 systemstack(func() { 1044 print("fatal error: ", s, "\n") 1045 }) 1046 1047 fatalthrow(throwTypeRuntime) 1048 } 1049 1050 // fatal triggers a fatal error that dumps a stack trace and exits. 1051 // 1052 // fatal is equivalent to throw, but is used when user code is expected to be 1053 // at fault for the failure, such as racing map writes. 1054 // 1055 // fatal does not include runtime frames, system goroutines, or frame metadata 1056 // (fp, sp, pc) in the stack trace unless GOTRACEBACK=system or higher. 1057 // 1058 //go:nosplit 1059 func fatal(s string) { 1060 // Everything fatal does should be recursively nosplit so it 1061 // can be called even when it's unsafe to grow the stack. 1062 systemstack(func() { 1063 print("fatal error: ", s, "\n") 1064 }) 1065 1066 fatalthrow(throwTypeUser) 1067 } 1068 1069 // runningPanicDefers is non-zero while running deferred functions for panic. 1070 // This is used to try hard to get a panic stack trace out when exiting. 1071 var runningPanicDefers atomic.Uint32 1072 1073 // panicking is non-zero when crashing the program for an unrecovered panic. 1074 var panicking atomic.Uint32 1075 1076 // paniclk is held while printing the panic information and stack trace, 1077 // so that two concurrent panics don't overlap their output. 1078 var paniclk mutex 1079 1080 // Unwind the stack after a deferred function calls recover 1081 // after a panic. Then arrange to continue running as though 1082 // the caller of the deferred function returned normally. 1083 func recovery(gp *g) { 1084 // Info about defer passed in G struct. 1085 sp := gp.sigcode0 1086 pc := gp.sigcode1 1087 1088 // d's arguments need to be in the stack. 1089 if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) { 1090 print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n") 1091 throw("bad recovery") 1092 } 1093 1094 // Make the deferproc for this d return again, 1095 // this time returning 1. The calling function will 1096 // jump to the standard return epilogue. 1097 gp.sched.sp = sp 1098 gp.sched.pc = pc 1099 gp.sched.lr = 0 1100 gp.sched.ret = 1 1101 gogo(&gp.sched) 1102 } 1103 1104 // fatalthrow implements an unrecoverable runtime throw. It freezes the 1105 // system, prints stack traces starting from its caller, and terminates the 1106 // process. 1107 // 1108 //go:nosplit 1109 func fatalthrow(t throwType) { 1110 pc := getcallerpc() 1111 sp := getcallersp() 1112 gp := getg() 1113 1114 if gp.m.throwing == throwTypeNone { 1115 gp.m.throwing = t 1116 } 1117 1118 // Switch to the system stack to avoid any stack growth, which may make 1119 // things worse if the runtime is in a bad state. 1120 systemstack(func() { 1121 startpanic_m() 1122 1123 if dopanic_m(gp, pc, sp) { 1124 // crash uses a decent amount of nosplit stack and we're already 1125 // low on stack in throw, so crash on the system stack (unlike 1126 // fatalpanic). 1127 crash() 1128 } 1129 1130 exit(2) 1131 }) 1132 1133 *(*int)(nil) = 0 // not reached 1134 } 1135 1136 // fatalpanic implements an unrecoverable panic. It is like fatalthrow, except 1137 // that if msgs != nil, fatalpanic also prints panic messages and decrements 1138 // runningPanicDefers once main is blocked from exiting. 1139 // 1140 //go:nosplit 1141 func fatalpanic(msgs *_panic) { 1142 pc := getcallerpc() 1143 sp := getcallersp() 1144 gp := getg() 1145 var docrash bool 1146 // Switch to the system stack to avoid any stack growth, which 1147 // may make things worse if the runtime is in a bad state. 1148 systemstack(func() { 1149 if startpanic_m() && msgs != nil { 1150 // There were panic messages and startpanic_m 1151 // says it's okay to try to print them. 1152 1153 // startpanic_m set panicking, which will 1154 // block main from exiting, so now OK to 1155 // decrement runningPanicDefers. 1156 runningPanicDefers.Add(-1) 1157 1158 printpanics(msgs) 1159 } 1160 1161 docrash = dopanic_m(gp, pc, sp) 1162 }) 1163 1164 if docrash { 1165 // By crashing outside the above systemstack call, debuggers 1166 // will not be confused when generating a backtrace. 1167 // Function crash is marked nosplit to avoid stack growth. 1168 crash() 1169 } 1170 1171 systemstack(func() { 1172 exit(2) 1173 }) 1174 1175 *(*int)(nil) = 0 // not reached 1176 } 1177 1178 // startpanic_m prepares for an unrecoverable panic. 1179 // 1180 // It returns true if panic messages should be printed, or false if 1181 // the runtime is in bad shape and should just print stacks. 1182 // 1183 // It must not have write barriers even though the write barrier 1184 // explicitly ignores writes once dying > 0. Write barriers still 1185 // assume that g.m.p != nil, and this function may not have P 1186 // in some contexts (e.g. a panic in a signal handler for a signal 1187 // sent to an M with no P). 1188 // 1189 //go:nowritebarrierrec 1190 func startpanic_m() bool { 1191 gp := getg() 1192 if mheap_.cachealloc.size == 0 { // very early 1193 print("runtime: panic before malloc heap initialized\n") 1194 } 1195 // Disallow malloc during an unrecoverable panic. A panic 1196 // could happen in a signal handler, or in a throw, or inside 1197 // malloc itself. We want to catch if an allocation ever does 1198 // happen (even if we're not in one of these situations). 1199 gp.m.mallocing++ 1200 1201 // If we're dying because of a bad lock count, set it to a 1202 // good lock count so we don't recursively panic below. 1203 if gp.m.locks < 0 { 1204 gp.m.locks = 1 1205 } 1206 1207 switch gp.m.dying { 1208 case 0: 1209 // Setting dying >0 has the side-effect of disabling this G's writebuf. 1210 gp.m.dying = 1 1211 panicking.Add(1) 1212 lock(&paniclk) 1213 if debug.schedtrace > 0 || debug.scheddetail > 0 { 1214 schedtrace(true) 1215 } 1216 freezetheworld() 1217 return true 1218 case 1: 1219 // Something failed while panicking. 1220 // Just print a stack trace and exit. 1221 gp.m.dying = 2 1222 print("panic during panic\n") 1223 return false 1224 case 2: 1225 // This is a genuine bug in the runtime, we couldn't even 1226 // print the stack trace successfully. 1227 gp.m.dying = 3 1228 print("stack trace unavailable\n") 1229 exit(4) 1230 fallthrough 1231 default: 1232 // Can't even print! Just exit. 1233 exit(5) 1234 return false // Need to return something. 1235 } 1236 } 1237 1238 var didothers bool 1239 var deadlock mutex 1240 1241 // gp is the crashing g running on this M, but may be a user G, while getg() is 1242 // always g0. 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 if level > 0 { 1256 if gp != gp.m.curg { 1257 all = true 1258 } 1259 if gp != gp.m.g0 { 1260 print("\n") 1261 goroutineheader(gp) 1262 traceback(pc, sp, 0, gp) 1263 } else if level >= 2 || gp.m.throwing >= throwTypeRuntime { 1264 print("\nruntime stack:\n") 1265 traceback(pc, sp, 0, gp) 1266 } 1267 if !didothers && all { 1268 didothers = true 1269 tracebackothers(gp) 1270 } 1271 } 1272 unlock(&paniclk) 1273 1274 if panicking.Add(-1) != 0 { 1275 // Some other m is panicking too. 1276 // Let it print what it needs to print. 1277 // Wait forever without chewing up cpu. 1278 // It will exit when it's done. 1279 lock(&deadlock) 1280 lock(&deadlock) 1281 } 1282 1283 printDebugLog() 1284 1285 return docrash 1286 } 1287 1288 // canpanic returns false if a signal should throw instead of 1289 // panicking. 1290 // 1291 //go:nosplit 1292 func canpanic() bool { 1293 gp := getg() 1294 mp := acquirem() 1295 1296 // Is it okay for gp to panic instead of crashing the program? 1297 // Yes, as long as it is running Go code, not runtime code, 1298 // and not stuck in a system call. 1299 if gp != mp.curg { 1300 releasem(mp) 1301 return false 1302 } 1303 // N.B. mp.locks != 1 instead of 0 to account for acquirem. 1304 if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 { 1305 releasem(mp) 1306 return false 1307 } 1308 status := readgstatus(gp) 1309 if status&^_Gscan != _Grunning || gp.syscallsp != 0 { 1310 releasem(mp) 1311 return false 1312 } 1313 if GOOS == "windows" && mp.libcallsp != 0 { 1314 releasem(mp) 1315 return false 1316 } 1317 releasem(mp) 1318 return true 1319 } 1320 1321 // shouldPushSigpanic reports whether pc should be used as sigpanic's 1322 // return PC (pushing a frame for the call). Otherwise, it should be 1323 // left alone so that LR is used as sigpanic's return PC, effectively 1324 // replacing the top-most frame with sigpanic. This is used by 1325 // preparePanic. 1326 func shouldPushSigpanic(gp *g, pc, lr uintptr) bool { 1327 if pc == 0 { 1328 // Probably a call to a nil func. The old LR is more 1329 // useful in the stack trace. Not pushing the frame 1330 // will make the trace look like a call to sigpanic 1331 // instead. (Otherwise the trace will end at sigpanic 1332 // and we won't get to see who faulted.) 1333 return false 1334 } 1335 // If we don't recognize the PC as code, but we do recognize 1336 // the link register as code, then this assumes the panic was 1337 // caused by a call to non-code. In this case, we want to 1338 // ignore this call to make unwinding show the context. 1339 // 1340 // If we running C code, we're not going to recognize pc as a 1341 // Go function, so just assume it's good. Otherwise, traceback 1342 // may try to read a stale LR that looks like a Go code 1343 // pointer and wander into the woods. 1344 if gp.m.incgo || findfunc(pc).valid() { 1345 // This wasn't a bad call, so use PC as sigpanic's 1346 // return PC. 1347 return true 1348 } 1349 if findfunc(lr).valid() { 1350 // This was a bad call, but the LR is good, so use the 1351 // LR as sigpanic's return PC. 1352 return false 1353 } 1354 // Neither the PC or LR is good. Hopefully pushing a frame 1355 // will work. 1356 return true 1357 } 1358 1359 // isAbortPC reports whether pc is the program counter at which 1360 // runtime.abort raises a signal. 1361 // 1362 // It is nosplit because it's part of the isgoexception 1363 // implementation. 1364 // 1365 //go:nosplit 1366 func isAbortPC(pc uintptr) bool { 1367 f := findfunc(pc) 1368 if !f.valid() { 1369 return false 1370 } 1371 return f.funcID == funcID_abort 1372 }