github.com/aloncn/graphics-go@v0.0.1/src/runtime/traceback.go (about) 1 // Copyright 2009 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 "runtime/internal/sys" 9 "unsafe" 10 ) 11 12 // The code in this file implements stack trace walking for all architectures. 13 // The most important fact about a given architecture is whether it uses a link register. 14 // On systems with link registers, the prologue for a non-leaf function stores the 15 // incoming value of LR at the bottom of the newly allocated stack frame. 16 // On systems without link registers, the architecture pushes a return PC during 17 // the call instruction, so the return PC ends up above the stack frame. 18 // In this file, the return PC is always called LR, no matter how it was found. 19 // 20 // To date, the opposite of a link register architecture is an x86 architecture. 21 // This code may need to change if some other kind of non-link-register 22 // architecture comes along. 23 // 24 // The other important fact is the size of a pointer: on 32-bit systems the LR 25 // takes up only 4 bytes on the stack, while on 64-bit systems it takes up 8 bytes. 26 // Typically this is ptrSize. 27 // 28 // As an exception, amd64p32 has ptrSize == 4 but the CALL instruction still 29 // stores an 8-byte return PC onto the stack. To accommodate this, we use regSize 30 // as the size of the architecture-pushed return PC. 31 // 32 // usesLR is defined below in terms of minFrameSize, which is defined in 33 // arch_$GOARCH.go. ptrSize and regSize are defined in stubs.go. 34 35 const usesLR = sys.MinFrameSize > 0 36 37 var ( 38 // initialized in tracebackinit 39 goexitPC uintptr 40 jmpdeferPC uintptr 41 mcallPC uintptr 42 morestackPC uintptr 43 mstartPC uintptr 44 rt0_goPC uintptr 45 sigpanicPC uintptr 46 runfinqPC uintptr 47 bgsweepPC uintptr 48 forcegchelperPC uintptr 49 timerprocPC uintptr 50 gcBgMarkWorkerPC uintptr 51 systemstack_switchPC uintptr 52 systemstackPC uintptr 53 stackBarrierPC uintptr 54 cgocallback_gofuncPC uintptr 55 56 gogoPC uintptr 57 58 externalthreadhandlerp uintptr // initialized elsewhere 59 ) 60 61 func tracebackinit() { 62 // Go variable initialization happens late during runtime startup. 63 // Instead of initializing the variables above in the declarations, 64 // schedinit calls this function so that the variables are 65 // initialized and available earlier in the startup sequence. 66 goexitPC = funcPC(goexit) 67 jmpdeferPC = funcPC(jmpdefer) 68 mcallPC = funcPC(mcall) 69 morestackPC = funcPC(morestack) 70 mstartPC = funcPC(mstart) 71 rt0_goPC = funcPC(rt0_go) 72 sigpanicPC = funcPC(sigpanic) 73 runfinqPC = funcPC(runfinq) 74 bgsweepPC = funcPC(bgsweep) 75 forcegchelperPC = funcPC(forcegchelper) 76 timerprocPC = funcPC(timerproc) 77 gcBgMarkWorkerPC = funcPC(gcBgMarkWorker) 78 systemstack_switchPC = funcPC(systemstack_switch) 79 systemstackPC = funcPC(systemstack) 80 stackBarrierPC = funcPC(stackBarrier) 81 cgocallback_gofuncPC = funcPC(cgocallback_gofunc) 82 83 // used by sigprof handler 84 gogoPC = funcPC(gogo) 85 } 86 87 // Traceback over the deferred function calls. 88 // Report them like calls that have been invoked but not started executing yet. 89 func tracebackdefers(gp *g, callback func(*stkframe, unsafe.Pointer) bool, v unsafe.Pointer) { 90 var frame stkframe 91 for d := gp._defer; d != nil; d = d.link { 92 fn := d.fn 93 if fn == nil { 94 // Defer of nil function. Args don't matter. 95 frame.pc = 0 96 frame.fn = nil 97 frame.argp = 0 98 frame.arglen = 0 99 frame.argmap = nil 100 } else { 101 frame.pc = uintptr(fn.fn) 102 f := findfunc(frame.pc) 103 if f == nil { 104 print("runtime: unknown pc in defer ", hex(frame.pc), "\n") 105 throw("unknown pc") 106 } 107 frame.fn = f 108 frame.argp = uintptr(deferArgs(d)) 109 frame.arglen, frame.argmap = getArgInfo(&frame, f, true) 110 } 111 frame.continpc = frame.pc 112 if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) { 113 return 114 } 115 } 116 } 117 118 // Generic traceback. Handles runtime stack prints (pcbuf == nil), 119 // the runtime.Callers function (pcbuf != nil), as well as the garbage 120 // collector (callback != nil). A little clunky to merge these, but avoids 121 // duplicating the code and all its subtlety. 122 func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max int, callback func(*stkframe, unsafe.Pointer) bool, v unsafe.Pointer, flags uint) int { 123 if goexitPC == 0 { 124 throw("gentraceback before goexitPC initialization") 125 } 126 g := getg() 127 if g == gp && g == g.m.curg { 128 // The starting sp has been passed in as a uintptr, and the caller may 129 // have other uintptr-typed stack references as well. 130 // If during one of the calls that got us here or during one of the 131 // callbacks below the stack must be grown, all these uintptr references 132 // to the stack will not be updated, and gentraceback will continue 133 // to inspect the old stack memory, which may no longer be valid. 134 // Even if all the variables were updated correctly, it is not clear that 135 // we want to expose a traceback that begins on one stack and ends 136 // on another stack. That could confuse callers quite a bit. 137 // Instead, we require that gentraceback and any other function that 138 // accepts an sp for the current goroutine (typically obtained by 139 // calling getcallersp) must not run on that goroutine's stack but 140 // instead on the g0 stack. 141 throw("gentraceback cannot trace user goroutine on its own stack") 142 } 143 level, _, _ := gotraceback() 144 145 // Fix up returns to the stack barrier by fetching the 146 // original return PC from gp.stkbar. 147 stkbarG := gp 148 stkbar := stkbarG.stkbar[stkbarG.stkbarPos:] 149 150 if pc0 == ^uintptr(0) && sp0 == ^uintptr(0) { // Signal to fetch saved values from gp. 151 if gp.syscallsp != 0 { 152 pc0 = gp.syscallpc 153 sp0 = gp.syscallsp 154 if usesLR { 155 lr0 = 0 156 } 157 } else { 158 pc0 = gp.sched.pc 159 sp0 = gp.sched.sp 160 if usesLR { 161 lr0 = gp.sched.lr 162 } 163 } 164 } 165 166 nprint := 0 167 var frame stkframe 168 frame.pc = pc0 169 frame.sp = sp0 170 if usesLR { 171 frame.lr = lr0 172 } 173 waspanic := false 174 printing := pcbuf == nil && callback == nil 175 _defer := gp._defer 176 177 for _defer != nil && uintptr(_defer.sp) == _NoArgs { 178 _defer = _defer.link 179 } 180 181 // If the PC is zero, it's likely a nil function call. 182 // Start in the caller's frame. 183 if frame.pc == 0 { 184 if usesLR { 185 frame.pc = *(*uintptr)(unsafe.Pointer(frame.sp)) 186 frame.lr = 0 187 } else { 188 frame.pc = uintptr(*(*sys.Uintreg)(unsafe.Pointer(frame.sp))) 189 frame.sp += sys.RegSize 190 } 191 } 192 193 f := findfunc(frame.pc) 194 if f != nil && f.entry == stackBarrierPC { 195 // We got caught in the middle of a stack barrier 196 // (presumably by a signal), so stkbar may be 197 // inconsistent with the barriers on the stack. 198 // Simulate the completion of the barrier. 199 // 200 // On x86, SP will be exactly one word above 201 // savedLRPtr. On LR machines, SP will be above 202 // savedLRPtr by some frame size. 203 var stkbarPos uintptr 204 if len(stkbar) > 0 && stkbar[0].savedLRPtr < sp0 { 205 // stackBarrier has not incremented stkbarPos. 206 stkbarPos = gp.stkbarPos 207 } else if gp.stkbarPos > 0 && gp.stkbar[gp.stkbarPos-1].savedLRPtr < sp0 { 208 // stackBarrier has incremented stkbarPos. 209 stkbarPos = gp.stkbarPos - 1 210 } else { 211 printlock() 212 print("runtime: failed to unwind through stackBarrier at SP ", hex(sp0), "; ") 213 gcPrintStkbars(gp, int(gp.stkbarPos)) 214 print("\n") 215 throw("inconsistent state in stackBarrier") 216 } 217 218 frame.pc = gp.stkbar[stkbarPos].savedLRVal 219 stkbar = gp.stkbar[stkbarPos+1:] 220 f = findfunc(frame.pc) 221 } 222 if f == nil { 223 if callback != nil { 224 print("runtime: unknown pc ", hex(frame.pc), "\n") 225 throw("unknown pc") 226 } 227 return 0 228 } 229 frame.fn = f 230 231 var cache pcvalueCache 232 233 n := 0 234 for n < max { 235 // Typically: 236 // pc is the PC of the running function. 237 // sp is the stack pointer at that program counter. 238 // fp is the frame pointer (caller's stack pointer) at that program counter, or nil if unknown. 239 // stk is the stack containing sp. 240 // The caller's program counter is lr, unless lr is zero, in which case it is *(uintptr*)sp. 241 f = frame.fn 242 243 // Found an actual function. 244 // Derive frame pointer and link register. 245 if frame.fp == 0 { 246 // We want to jump over the systemstack switch. If we're running on the 247 // g0, this systemstack is at the top of the stack. 248 // if we're not on g0 or there's a no curg, then this is a regular call. 249 sp := frame.sp 250 if flags&_TraceJumpStack != 0 && f.entry == systemstackPC && gp == g.m.g0 && gp.m.curg != nil { 251 sp = gp.m.curg.sched.sp 252 stkbarG = gp.m.curg 253 stkbar = stkbarG.stkbar[stkbarG.stkbarPos:] 254 } 255 frame.fp = sp + uintptr(funcspdelta(f, frame.pc, &cache)) 256 if !usesLR { 257 // On x86, call instruction pushes return PC before entering new function. 258 frame.fp += sys.RegSize 259 } 260 } 261 var flr *_func 262 if topofstack(f) { 263 frame.lr = 0 264 flr = nil 265 } else if usesLR && f.entry == jmpdeferPC { 266 // jmpdefer modifies SP/LR/PC non-atomically. 267 // If a profiling interrupt arrives during jmpdefer, 268 // the stack unwind may see a mismatched register set 269 // and get confused. Stop if we see PC within jmpdefer 270 // to avoid that confusion. 271 // See golang.org/issue/8153. 272 if callback != nil { 273 throw("traceback_arm: found jmpdefer when tracing with callback") 274 } 275 frame.lr = 0 276 } else { 277 var lrPtr uintptr 278 if usesLR { 279 if n == 0 && frame.sp < frame.fp || frame.lr == 0 { 280 lrPtr = frame.sp 281 frame.lr = *(*uintptr)(unsafe.Pointer(lrPtr)) 282 } 283 } else { 284 if frame.lr == 0 { 285 lrPtr = frame.fp - sys.RegSize 286 frame.lr = uintptr(*(*sys.Uintreg)(unsafe.Pointer(lrPtr))) 287 } 288 } 289 if frame.lr == stackBarrierPC { 290 // Recover original PC. 291 if len(stkbar) == 0 || stkbar[0].savedLRPtr != lrPtr { 292 print("found next stack barrier at ", hex(lrPtr), "; expected ") 293 gcPrintStkbars(stkbarG, len(stkbarG.stkbar)-len(stkbar)) 294 print("\n") 295 throw("missed stack barrier") 296 } 297 frame.lr = stkbar[0].savedLRVal 298 stkbar = stkbar[1:] 299 } 300 flr = findfunc(frame.lr) 301 if flr == nil { 302 // This happens if you get a profiling interrupt at just the wrong time. 303 // In that context it is okay to stop early. 304 // But if callback is set, we're doing a garbage collection and must 305 // get everything, so crash loudly. 306 if callback != nil { 307 print("runtime: unexpected return pc for ", funcname(f), " called from ", hex(frame.lr), "\n") 308 throw("unknown caller pc") 309 } 310 } 311 } 312 313 frame.varp = frame.fp 314 if !usesLR { 315 // On x86, call instruction pushes return PC before entering new function. 316 frame.varp -= sys.RegSize 317 } 318 319 // If framepointer_enabled and there's a frame, then 320 // there's a saved bp here. 321 if framepointer_enabled && GOARCH == "amd64" && frame.varp > frame.sp { 322 frame.varp -= sys.RegSize 323 } 324 325 // Derive size of arguments. 326 // Most functions have a fixed-size argument block, 327 // so we can use metadata about the function f. 328 // Not all, though: there are some variadic functions 329 // in package runtime and reflect, and for those we use call-specific 330 // metadata recorded by f's caller. 331 if callback != nil || printing { 332 frame.argp = frame.fp + sys.MinFrameSize 333 frame.arglen, frame.argmap = getArgInfo(&frame, f, callback != nil) 334 } 335 336 // Determine frame's 'continuation PC', where it can continue. 337 // Normally this is the return address on the stack, but if sigpanic 338 // is immediately below this function on the stack, then the frame 339 // stopped executing due to a trap, and frame.pc is probably not 340 // a safe point for looking up liveness information. In this panicking case, 341 // the function either doesn't return at all (if it has no defers or if the 342 // defers do not recover) or it returns from one of the calls to 343 // deferproc a second time (if the corresponding deferred func recovers). 344 // It suffices to assume that the most recent deferproc is the one that 345 // returns; everything live at earlier deferprocs is still live at that one. 346 frame.continpc = frame.pc 347 if waspanic { 348 if _defer != nil && _defer.sp == frame.sp { 349 frame.continpc = _defer.pc 350 } else { 351 frame.continpc = 0 352 } 353 } 354 355 // Unwind our local defer stack past this frame. 356 for _defer != nil && (_defer.sp == frame.sp || _defer.sp == _NoArgs) { 357 _defer = _defer.link 358 } 359 360 if skip > 0 { 361 skip-- 362 goto skipped 363 } 364 365 if pcbuf != nil { 366 (*[1 << 20]uintptr)(unsafe.Pointer(pcbuf))[n] = frame.pc 367 } 368 if callback != nil { 369 if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) { 370 return n 371 } 372 } 373 if printing { 374 if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp) { 375 // Print during crash. 376 // main(0x1, 0x2, 0x3) 377 // /home/rsc/go/src/runtime/x.go:23 +0xf 378 // 379 tracepc := frame.pc // back up to CALL instruction for funcline. 380 if (n > 0 || flags&_TraceTrap == 0) && frame.pc > f.entry && !waspanic { 381 tracepc-- 382 } 383 name := funcname(f) 384 if name == "runtime.gopanic" { 385 name = "panic" 386 } 387 print(name, "(") 388 argp := (*[100]uintptr)(unsafe.Pointer(frame.argp)) 389 for i := uintptr(0); i < frame.arglen/sys.PtrSize; i++ { 390 if i >= 10 { 391 print(", ...") 392 break 393 } 394 if i != 0 { 395 print(", ") 396 } 397 print(hex(argp[i])) 398 } 399 print(")\n") 400 file, line := funcline(f, tracepc) 401 print("\t", file, ":", line) 402 if frame.pc > f.entry { 403 print(" +", hex(frame.pc-f.entry)) 404 } 405 if g.m.throwing > 0 && gp == g.m.curg || level >= 2 { 406 print(" fp=", hex(frame.fp), " sp=", hex(frame.sp)) 407 } 408 print("\n") 409 nprint++ 410 } 411 } 412 n++ 413 414 skipped: 415 waspanic = f.entry == sigpanicPC 416 417 // Do not unwind past the bottom of the stack. 418 if flr == nil { 419 break 420 } 421 422 // Unwind to next frame. 423 frame.fn = flr 424 frame.pc = frame.lr 425 frame.lr = 0 426 frame.sp = frame.fp 427 frame.fp = 0 428 frame.argmap = nil 429 430 // On link register architectures, sighandler saves the LR on stack 431 // before faking a call to sigpanic. 432 if usesLR && waspanic { 433 x := *(*uintptr)(unsafe.Pointer(frame.sp)) 434 frame.sp += sys.MinFrameSize 435 if GOARCH == "arm64" { 436 // arm64 needs 16-byte aligned SP, always 437 frame.sp += sys.PtrSize 438 } 439 f = findfunc(frame.pc) 440 frame.fn = f 441 if f == nil { 442 frame.pc = x 443 } else if funcspdelta(f, frame.pc, &cache) == 0 { 444 frame.lr = x 445 } 446 } 447 } 448 449 if printing { 450 n = nprint 451 } 452 453 // If callback != nil, we're being called to gather stack information during 454 // garbage collection or stack growth. In that context, require that we used 455 // up the entire defer stack. If not, then there is a bug somewhere and the 456 // garbage collection or stack growth may not have seen the correct picture 457 // of the stack. Crash now instead of silently executing the garbage collection 458 // or stack copy incorrectly and setting up for a mysterious crash later. 459 // 460 // Note that panic != nil is okay here: there can be leftover panics, 461 // because the defers on the panic stack do not nest in frame order as 462 // they do on the defer stack. If you have: 463 // 464 // frame 1 defers d1 465 // frame 2 defers d2 466 // frame 3 defers d3 467 // frame 4 panics 468 // frame 4's panic starts running defers 469 // frame 5, running d3, defers d4 470 // frame 5 panics 471 // frame 5's panic starts running defers 472 // frame 6, running d4, garbage collects 473 // frame 6, running d2, garbage collects 474 // 475 // During the execution of d4, the panic stack is d4 -> d3, which 476 // is nested properly, and we'll treat frame 3 as resumable, because we 477 // can find d3. (And in fact frame 3 is resumable. If d4 recovers 478 // and frame 5 continues running, d3, d3 can recover and we'll 479 // resume execution in (returning from) frame 3.) 480 // 481 // During the execution of d2, however, the panic stack is d2 -> d3, 482 // which is inverted. The scan will match d2 to frame 2 but having 483 // d2 on the stack until then means it will not match d3 to frame 3. 484 // This is okay: if we're running d2, then all the defers after d2 have 485 // completed and their corresponding frames are dead. Not finding d3 486 // for frame 3 means we'll set frame 3's continpc == 0, which is correct 487 // (frame 3 is dead). At the end of the walk the panic stack can thus 488 // contain defers (d3 in this case) for dead frames. The inversion here 489 // always indicates a dead frame, and the effect of the inversion on the 490 // scan is to hide those dead frames, so the scan is still okay: 491 // what's left on the panic stack are exactly (and only) the dead frames. 492 // 493 // We require callback != nil here because only when callback != nil 494 // do we know that gentraceback is being called in a "must be correct" 495 // context as opposed to a "best effort" context. The tracebacks with 496 // callbacks only happen when everything is stopped nicely. 497 // At other times, such as when gathering a stack for a profiling signal 498 // or when printing a traceback during a crash, everything may not be 499 // stopped nicely, and the stack walk may not be able to complete. 500 // It's okay in those situations not to use up the entire defer stack: 501 // incomplete information then is still better than nothing. 502 if callback != nil && n < max && _defer != nil { 503 if _defer != nil { 504 print("runtime: g", gp.goid, ": leftover defer sp=", hex(_defer.sp), " pc=", hex(_defer.pc), "\n") 505 } 506 for _defer = gp._defer; _defer != nil; _defer = _defer.link { 507 print("\tdefer ", _defer, " sp=", hex(_defer.sp), " pc=", hex(_defer.pc), "\n") 508 } 509 throw("traceback has leftover defers") 510 } 511 512 if callback != nil && n < max && len(stkbar) > 0 { 513 print("runtime: g", gp.goid, ": leftover stack barriers ") 514 gcPrintStkbars(stkbarG, len(stkbarG.stkbar)-len(stkbar)) 515 print("\n") 516 throw("traceback has leftover stack barriers") 517 } 518 519 if callback != nil && n < max && frame.sp != gp.stktopsp { 520 print("runtime: g", gp.goid, ": frame.sp=", hex(frame.sp), " top=", hex(gp.stktopsp), "\n") 521 print("\tstack=[", hex(gp.stack.lo), "-", hex(gp.stack.hi), "] n=", n, " max=", max, "\n") 522 throw("traceback did not unwind completely") 523 } 524 525 return n 526 } 527 528 func getArgInfo(frame *stkframe, f *_func, needArgMap bool) (arglen uintptr, argmap *bitvector) { 529 arglen = uintptr(f.args) 530 if needArgMap && f.args == _ArgsSizeUnknown { 531 // Extract argument bitmaps for reflect stubs from the calls they made to reflect. 532 switch funcname(f) { 533 case "reflect.makeFuncStub", "reflect.methodValueCall": 534 arg0 := frame.sp + sys.MinFrameSize 535 fn := *(**[2]uintptr)(unsafe.Pointer(arg0)) 536 if fn[0] != f.entry { 537 print("runtime: confused by ", funcname(f), "\n") 538 throw("reflect mismatch") 539 } 540 bv := (*bitvector)(unsafe.Pointer(fn[1])) 541 arglen = uintptr(bv.n * sys.PtrSize) 542 argmap = bv 543 } 544 } 545 return 546 } 547 548 func printcreatedby(gp *g) { 549 // Show what created goroutine, except main goroutine (goid 1). 550 pc := gp.gopc 551 f := findfunc(pc) 552 if f != nil && showframe(f, gp) && gp.goid != 1 { 553 print("created by ", funcname(f), "\n") 554 tracepc := pc // back up to CALL instruction for funcline. 555 if pc > f.entry { 556 tracepc -= sys.PCQuantum 557 } 558 file, line := funcline(f, tracepc) 559 print("\t", file, ":", line) 560 if pc > f.entry { 561 print(" +", hex(pc-f.entry)) 562 } 563 print("\n") 564 } 565 } 566 567 func traceback(pc, sp, lr uintptr, gp *g) { 568 traceback1(pc, sp, lr, gp, 0) 569 } 570 571 // tracebacktrap is like traceback but expects that the PC and SP were obtained 572 // from a trap, not from gp->sched or gp->syscallpc/gp->syscallsp or getcallerpc/getcallersp. 573 // Because they are from a trap instead of from a saved pair, 574 // the initial PC must not be rewound to the previous instruction. 575 // (All the saved pairs record a PC that is a return address, so we 576 // rewind it into the CALL instruction.) 577 func tracebacktrap(pc, sp, lr uintptr, gp *g) { 578 traceback1(pc, sp, lr, gp, _TraceTrap) 579 } 580 581 func traceback1(pc, sp, lr uintptr, gp *g, flags uint) { 582 var n int 583 if readgstatus(gp)&^_Gscan == _Gsyscall { 584 // Override registers if blocked in system call. 585 pc = gp.syscallpc 586 sp = gp.syscallsp 587 flags &^= _TraceTrap 588 } 589 // Print traceback. By default, omits runtime frames. 590 // If that means we print nothing at all, repeat forcing all frames printed. 591 n = gentraceback(pc, sp, lr, gp, 0, nil, _TracebackMaxFrames, nil, nil, flags) 592 if n == 0 && (flags&_TraceRuntimeFrames) == 0 { 593 n = gentraceback(pc, sp, lr, gp, 0, nil, _TracebackMaxFrames, nil, nil, flags|_TraceRuntimeFrames) 594 } 595 if n == _TracebackMaxFrames { 596 print("...additional frames elided...\n") 597 } 598 printcreatedby(gp) 599 } 600 601 func callers(skip int, pcbuf []uintptr) int { 602 sp := getcallersp(unsafe.Pointer(&skip)) 603 pc := uintptr(getcallerpc(unsafe.Pointer(&skip))) 604 gp := getg() 605 var n int 606 systemstack(func() { 607 n = gentraceback(pc, sp, 0, gp, skip, &pcbuf[0], len(pcbuf), nil, nil, 0) 608 }) 609 return n 610 } 611 612 func gcallers(gp *g, skip int, pcbuf []uintptr) int { 613 return gentraceback(^uintptr(0), ^uintptr(0), 0, gp, skip, &pcbuf[0], len(pcbuf), nil, nil, 0) 614 } 615 616 func showframe(f *_func, gp *g) bool { 617 g := getg() 618 if g.m.throwing > 0 && gp != nil && (gp == g.m.curg || gp == g.m.caughtsig.ptr()) { 619 return true 620 } 621 level, _, _ := gotraceback() 622 name := funcname(f) 623 624 // Special case: always show runtime.gopanic frame, so that we can 625 // see where a panic started in the middle of a stack trace. 626 // See golang.org/issue/5832. 627 if name == "runtime.gopanic" { 628 return true 629 } 630 631 return level > 1 || f != nil && contains(name, ".") && (!hasprefix(name, "runtime.") || isExportedRuntime(name)) 632 } 633 634 // isExportedRuntime reports whether name is an exported runtime function. 635 // It is only for runtime functions, so ASCII A-Z is fine. 636 func isExportedRuntime(name string) bool { 637 const n = len("runtime.") 638 return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z' 639 } 640 641 var gStatusStrings = [...]string{ 642 _Gidle: "idle", 643 _Grunnable: "runnable", 644 _Grunning: "running", 645 _Gsyscall: "syscall", 646 _Gwaiting: "waiting", 647 _Gdead: "dead", 648 _Genqueue: "enqueue", 649 _Gcopystack: "copystack", 650 } 651 652 func goroutineheader(gp *g) { 653 gpstatus := readgstatus(gp) 654 655 isScan := gpstatus&_Gscan != 0 656 gpstatus &^= _Gscan // drop the scan bit 657 658 // Basic string status 659 var status string 660 if 0 <= gpstatus && gpstatus < uint32(len(gStatusStrings)) { 661 status = gStatusStrings[gpstatus] 662 } else { 663 status = "???" 664 } 665 666 // Override. 667 if gpstatus == _Gwaiting && gp.waitreason != "" { 668 status = gp.waitreason 669 } 670 671 // approx time the G is blocked, in minutes 672 var waitfor int64 673 if (gpstatus == _Gwaiting || gpstatus == _Gsyscall) && gp.waitsince != 0 { 674 waitfor = (nanotime() - gp.waitsince) / 60e9 675 } 676 print("goroutine ", gp.goid, " [", status) 677 if isScan { 678 print(" (scan)") 679 } 680 if waitfor >= 1 { 681 print(", ", waitfor, " minutes") 682 } 683 if gp.lockedm != nil { 684 print(", locked to thread") 685 } 686 print("]:\n") 687 } 688 689 func tracebackothers(me *g) { 690 level, _, _ := gotraceback() 691 692 // Show the current goroutine first, if we haven't already. 693 g := getg() 694 gp := g.m.curg 695 if gp != nil && gp != me { 696 print("\n") 697 goroutineheader(gp) 698 traceback(^uintptr(0), ^uintptr(0), 0, gp) 699 } 700 701 lock(&allglock) 702 for _, gp := range allgs { 703 if gp == me || gp == g.m.curg || readgstatus(gp) == _Gdead || isSystemGoroutine(gp) && level < 2 { 704 continue 705 } 706 print("\n") 707 goroutineheader(gp) 708 // Note: gp.m == g.m occurs when tracebackothers is 709 // called from a signal handler initiated during a 710 // systemstack call. The original G is still in the 711 // running state, and we want to print its stack. 712 if gp.m != g.m && readgstatus(gp)&^_Gscan == _Grunning { 713 print("\tgoroutine running on other thread; stack unavailable\n") 714 printcreatedby(gp) 715 } else { 716 traceback(^uintptr(0), ^uintptr(0), 0, gp) 717 } 718 } 719 unlock(&allglock) 720 } 721 722 // Does f mark the top of a goroutine stack? 723 func topofstack(f *_func) bool { 724 pc := f.entry 725 return pc == goexitPC || 726 pc == mstartPC || 727 pc == mcallPC || 728 pc == morestackPC || 729 pc == rt0_goPC || 730 externalthreadhandlerp != 0 && pc == externalthreadhandlerp 731 } 732 733 // isSystemGoroutine reports whether the goroutine g must be omitted in 734 // stack dumps and deadlock detector. 735 func isSystemGoroutine(gp *g) bool { 736 pc := gp.startpc 737 return pc == runfinqPC && !fingRunning || 738 pc == bgsweepPC || 739 pc == forcegchelperPC || 740 pc == timerprocPC || 741 pc == gcBgMarkWorkerPC 742 }