github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/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/atomic" 9 "runtime/internal/sys" 10 "unsafe" 11 ) 12 13 // The code in this file implements stack trace walking for all architectures. 14 // The most important fact about a given architecture is whether it uses a link register. 15 // On systems with link registers, the prologue for a non-leaf function stores the 16 // incoming value of LR at the bottom of the newly allocated stack frame. 17 // On systems without link registers, the architecture pushes a return PC during 18 // the call instruction, so the return PC ends up above the stack frame. 19 // In this file, the return PC is always called LR, no matter how it was found. 20 // 21 // To date, the opposite of a link register architecture is an x86 architecture. 22 // This code may need to change if some other kind of non-link-register 23 // architecture comes along. 24 // 25 // The other important fact is the size of a pointer: on 32-bit systems the LR 26 // takes up only 4 bytes on the stack, while on 64-bit systems it takes up 8 bytes. 27 // Typically this is ptrSize. 28 // 29 // As an exception, amd64p32 has ptrSize == 4 but the CALL instruction still 30 // stores an 8-byte return PC onto the stack. To accommodate this, we use regSize 31 // as the size of the architecture-pushed return PC. 32 // 33 // usesLR is defined below in terms of minFrameSize, which is defined in 34 // arch_$GOARCH.go. ptrSize and regSize are defined in stubs.go. 35 36 const usesLR = sys.MinFrameSize > 0 37 38 var skipPC uintptr 39 40 func tracebackinit() { 41 // Go variable initialization happens late during runtime startup. 42 // Instead of initializing the variables above in the declarations, 43 // schedinit calls this function so that the variables are 44 // initialized and available earlier in the startup sequence. 45 skipPC = funcPC(skipPleaseUseCallersFrames) 46 } 47 48 // Traceback over the deferred function calls. 49 // Report them like calls that have been invoked but not started executing yet. 50 func tracebackdefers(gp *g, callback func(*stkframe, unsafe.Pointer) bool, v unsafe.Pointer) { 51 var frame stkframe 52 for d := gp._defer; d != nil; d = d.link { 53 fn := d.fn 54 if fn == nil { 55 // Defer of nil function. Args don't matter. 56 frame.pc = 0 57 frame.fn = funcInfo{} 58 frame.argp = 0 59 frame.arglen = 0 60 frame.argmap = nil 61 } else { 62 frame.pc = fn.fn 63 f := findfunc(frame.pc) 64 if !f.valid() { 65 print("runtime: unknown pc in defer ", hex(frame.pc), "\n") 66 throw("unknown pc") 67 } 68 frame.fn = f 69 frame.argp = uintptr(deferArgs(d)) 70 var ok bool 71 frame.arglen, frame.argmap, ok = getArgInfoFast(f, true) 72 if !ok { 73 frame.arglen, frame.argmap = getArgInfo(&frame, f, true, fn) 74 } 75 } 76 frame.continpc = frame.pc 77 if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) { 78 return 79 } 80 } 81 } 82 83 const sizeofSkipFunction = 256 84 85 // This function is defined in asm.s to be sizeofSkipFunction bytes long. 86 func skipPleaseUseCallersFrames() 87 88 // Generic traceback. Handles runtime stack prints (pcbuf == nil), 89 // the runtime.Callers function (pcbuf != nil), as well as the garbage 90 // collector (callback != nil). A little clunky to merge these, but avoids 91 // duplicating the code and all its subtlety. 92 // 93 // The skip argument is only valid with pcbuf != nil and counts the number 94 // of logical frames to skip rather than physical frames (with inlining, a 95 // PC in pcbuf can represent multiple calls). If a PC is partially skipped 96 // and max > 1, pcbuf[1] will be runtime.skipPleaseUseCallersFrames+N where 97 // N indicates the number of logical frames to skip in pcbuf[0]. 98 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 { 99 if skip > 0 && callback != nil { 100 throw("gentraceback callback cannot be used with non-zero skip") 101 } 102 103 // Don't call this "g"; it's too easy get "g" and "gp" confused. 104 if ourg := getg(); ourg == gp && ourg == ourg.m.curg { 105 // The starting sp has been passed in as a uintptr, and the caller may 106 // have other uintptr-typed stack references as well. 107 // If during one of the calls that got us here or during one of the 108 // callbacks below the stack must be grown, all these uintptr references 109 // to the stack will not be updated, and gentraceback will continue 110 // to inspect the old stack memory, which may no longer be valid. 111 // Even if all the variables were updated correctly, it is not clear that 112 // we want to expose a traceback that begins on one stack and ends 113 // on another stack. That could confuse callers quite a bit. 114 // Instead, we require that gentraceback and any other function that 115 // accepts an sp for the current goroutine (typically obtained by 116 // calling getcallersp) must not run on that goroutine's stack but 117 // instead on the g0 stack. 118 throw("gentraceback cannot trace user goroutine on its own stack") 119 } 120 level, _, _ := gotraceback() 121 122 if pc0 == ^uintptr(0) && sp0 == ^uintptr(0) { // Signal to fetch saved values from gp. 123 if gp.syscallsp != 0 { 124 pc0 = gp.syscallpc 125 sp0 = gp.syscallsp 126 if usesLR { 127 lr0 = 0 128 } 129 } else { 130 pc0 = gp.sched.pc 131 sp0 = gp.sched.sp 132 if usesLR { 133 lr0 = gp.sched.lr 134 } 135 } 136 } 137 138 nprint := 0 139 var frame stkframe 140 frame.pc = pc0 141 frame.sp = sp0 142 if usesLR { 143 frame.lr = lr0 144 } 145 waspanic := false 146 cgoCtxt := gp.cgoCtxt 147 printing := pcbuf == nil && callback == nil 148 _defer := gp._defer 149 150 for _defer != nil && _defer.sp == _NoArgs { 151 _defer = _defer.link 152 } 153 154 // If the PC is zero, it's likely a nil function call. 155 // Start in the caller's frame. 156 if frame.pc == 0 { 157 if usesLR { 158 frame.pc = *(*uintptr)(unsafe.Pointer(frame.sp)) 159 frame.lr = 0 160 } else { 161 frame.pc = uintptr(*(*sys.Uintreg)(unsafe.Pointer(frame.sp))) 162 frame.sp += sys.RegSize 163 } 164 } 165 166 f := findfunc(frame.pc) 167 if !f.valid() { 168 if callback != nil || printing { 169 print("runtime: unknown pc ", hex(frame.pc), "\n") 170 tracebackHexdump(gp.stack, &frame, 0) 171 } 172 if callback != nil { 173 throw("unknown pc") 174 } 175 return 0 176 } 177 frame.fn = f 178 179 var cache pcvalueCache 180 181 lastFuncID := funcID_normal 182 n := 0 183 for n < max { 184 // Typically: 185 // pc is the PC of the running function. 186 // sp is the stack pointer at that program counter. 187 // fp is the frame pointer (caller's stack pointer) at that program counter, or nil if unknown. 188 // stk is the stack containing sp. 189 // The caller's program counter is lr, unless lr is zero, in which case it is *(uintptr*)sp. 190 f = frame.fn 191 if f.pcsp == 0 { 192 // No frame information, must be external function, like race support. 193 // See golang.org/issue/13568. 194 break 195 } 196 197 // Found an actual function. 198 // Derive frame pointer and link register. 199 if frame.fp == 0 { 200 // Jump over system stack transitions. If we're on g0 and there's a user 201 // goroutine, try to jump. Otherwise this is a regular call. 202 if flags&_TraceJumpStack != 0 && gp == gp.m.g0 && gp.m.curg != nil { 203 switch f.funcID { 204 case funcID_morestack: 205 // morestack does not return normally -- newstack() 206 // gogo's to curg.sched. Match that. 207 // This keeps morestack() from showing up in the backtrace, 208 // but that makes some sense since it'll never be returned 209 // to. 210 frame.pc = gp.m.curg.sched.pc 211 frame.fn = findfunc(frame.pc) 212 f = frame.fn 213 frame.sp = gp.m.curg.sched.sp 214 cgoCtxt = gp.m.curg.cgoCtxt 215 case funcID_systemstack: 216 // systemstack returns normally, so just follow the 217 // stack transition. 218 frame.sp = gp.m.curg.sched.sp 219 cgoCtxt = gp.m.curg.cgoCtxt 220 } 221 } 222 frame.fp = frame.sp + uintptr(funcspdelta(f, frame.pc, &cache)) 223 if !usesLR { 224 // On x86, call instruction pushes return PC before entering new function. 225 frame.fp += sys.RegSize 226 } 227 } 228 var flr funcInfo 229 if topofstack(f, gp.m != nil && gp == gp.m.g0) { 230 frame.lr = 0 231 flr = funcInfo{} 232 } else if usesLR && f.funcID == funcID_jmpdefer { 233 // jmpdefer modifies SP/LR/PC non-atomically. 234 // If a profiling interrupt arrives during jmpdefer, 235 // the stack unwind may see a mismatched register set 236 // and get confused. Stop if we see PC within jmpdefer 237 // to avoid that confusion. 238 // See golang.org/issue/8153. 239 if callback != nil { 240 throw("traceback_arm: found jmpdefer when tracing with callback") 241 } 242 frame.lr = 0 243 } else { 244 var lrPtr uintptr 245 if usesLR { 246 if n == 0 && frame.sp < frame.fp || frame.lr == 0 { 247 lrPtr = frame.sp 248 frame.lr = *(*uintptr)(unsafe.Pointer(lrPtr)) 249 } 250 } else { 251 if frame.lr == 0 { 252 lrPtr = frame.fp - sys.RegSize 253 frame.lr = uintptr(*(*sys.Uintreg)(unsafe.Pointer(lrPtr))) 254 } 255 } 256 flr = findfunc(frame.lr) 257 if !flr.valid() { 258 // This happens if you get a profiling interrupt at just the wrong time. 259 // In that context it is okay to stop early. 260 // But if callback is set, we're doing a garbage collection and must 261 // get everything, so crash loudly. 262 doPrint := printing 263 if doPrint && gp.m.incgo && f.funcID == funcID_sigpanic { 264 // We can inject sigpanic 265 // calls directly into C code, 266 // in which case we'll see a C 267 // return PC. Don't complain. 268 doPrint = false 269 } 270 if callback != nil || doPrint { 271 print("runtime: unexpected return pc for ", funcname(f), " called from ", hex(frame.lr), "\n") 272 tracebackHexdump(gp.stack, &frame, lrPtr) 273 } 274 if callback != nil { 275 throw("unknown caller pc") 276 } 277 } 278 } 279 280 frame.varp = frame.fp 281 if !usesLR { 282 // On x86, call instruction pushes return PC before entering new function. 283 frame.varp -= sys.RegSize 284 } 285 286 // If framepointer_enabled and there's a frame, then 287 // there's a saved bp here. 288 if frame.varp > frame.sp && (framepointer_enabled && GOARCH == "amd64" || GOARCH == "arm64") { 289 frame.varp -= sys.RegSize 290 } 291 292 // Derive size of arguments. 293 // Most functions have a fixed-size argument block, 294 // so we can use metadata about the function f. 295 // Not all, though: there are some variadic functions 296 // in package runtime and reflect, and for those we use call-specific 297 // metadata recorded by f's caller. 298 if callback != nil || printing { 299 frame.argp = frame.fp + sys.MinFrameSize 300 var ok bool 301 frame.arglen, frame.argmap, ok = getArgInfoFast(f, callback != nil) 302 if !ok { 303 frame.arglen, frame.argmap = getArgInfo(&frame, f, callback != nil, nil) 304 } 305 } 306 307 // Determine frame's 'continuation PC', where it can continue. 308 // Normally this is the return address on the stack, but if sigpanic 309 // is immediately below this function on the stack, then the frame 310 // stopped executing due to a trap, and frame.pc is probably not 311 // a safe point for looking up liveness information. In this panicking case, 312 // the function either doesn't return at all (if it has no defers or if the 313 // defers do not recover) or it returns from one of the calls to 314 // deferproc a second time (if the corresponding deferred func recovers). 315 // In the latter case, use a deferreturn call site as the continuation pc. 316 frame.continpc = frame.pc 317 if waspanic { 318 // We match up defers with frames using the SP. 319 // However, if the function has an empty stack 320 // frame, then it's possible (on LR machines) 321 // for multiple call frames to have the same 322 // SP. But, since a function with no frame 323 // can't push a defer, the defer can't belong 324 // to that frame. 325 if _defer != nil && _defer.sp == frame.sp && frame.sp != frame.fp { 326 frame.continpc = frame.fn.entry + uintptr(frame.fn.deferreturn) + 1 327 // Note: the +1 is to offset the -1 that 328 // stack.go:getStackMap does to back up a return 329 // address make sure the pc is in the CALL instruction. 330 } else { 331 frame.continpc = 0 332 } 333 } 334 335 // Unwind our local defer stack past this frame. 336 for _defer != nil && ((_defer.sp == frame.sp && frame.sp != frame.fp) || _defer.sp == _NoArgs) { 337 _defer = _defer.link 338 } 339 340 if callback != nil { 341 if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) { 342 return n 343 } 344 } 345 346 if pcbuf != nil { 347 pc := frame.pc 348 // backup to CALL instruction to read inlining info (same logic as below) 349 tracepc := pc 350 if (n > 0 || flags&_TraceTrap == 0) && frame.pc > f.entry && !waspanic { 351 tracepc-- 352 } 353 354 // If there is inlining info, record the inner frames. 355 if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil { 356 inltree := (*[1 << 20]inlinedCall)(inldata) 357 for { 358 ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, &cache) 359 if ix < 0 { 360 break 361 } 362 if inltree[ix].funcID == funcID_wrapper && elideWrapperCalling(lastFuncID) { 363 // ignore wrappers 364 } else if skip > 0 { 365 skip-- 366 } else if n < max { 367 (*[1 << 20]uintptr)(unsafe.Pointer(pcbuf))[n] = pc 368 n++ 369 } 370 lastFuncID = inltree[ix].funcID 371 // Back up to an instruction in the "caller". 372 tracepc = frame.fn.entry + uintptr(inltree[ix].parentPc) 373 pc = tracepc + 1 374 } 375 } 376 // Record the main frame. 377 if f.funcID == funcID_wrapper && elideWrapperCalling(lastFuncID) { 378 // Ignore wrapper functions (except when they trigger panics). 379 } else if skip > 0 { 380 skip-- 381 } else if n < max { 382 (*[1 << 20]uintptr)(unsafe.Pointer(pcbuf))[n] = pc 383 n++ 384 } 385 lastFuncID = f.funcID 386 n-- // offset n++ below 387 } 388 389 if printing { 390 // assume skip=0 for printing. 391 // 392 // Never elide wrappers if we haven't printed 393 // any frames. And don't elide wrappers that 394 // called panic rather than the wrapped 395 // function. Otherwise, leave them out. 396 397 // backup to CALL instruction to read inlining info (same logic as below) 398 tracepc := frame.pc 399 if (n > 0 || flags&_TraceTrap == 0) && frame.pc > f.entry && !waspanic { 400 tracepc-- 401 } 402 // If there is inlining info, print the inner frames. 403 if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil { 404 inltree := (*[1 << 20]inlinedCall)(inldata) 405 for { 406 ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, nil) 407 if ix < 0 { 408 break 409 } 410 if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp, nprint == 0, inltree[ix].funcID, lastFuncID) { 411 name := funcnameFromNameoff(f, inltree[ix].func_) 412 file, line := funcline(f, tracepc) 413 print(name, "(...)\n") 414 print("\t", file, ":", line, "\n") 415 nprint++ 416 } 417 lastFuncID = inltree[ix].funcID 418 // Back up to an instruction in the "caller". 419 tracepc = frame.fn.entry + uintptr(inltree[ix].parentPc) 420 } 421 } 422 if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp, nprint == 0, f.funcID, lastFuncID) { 423 // Print during crash. 424 // main(0x1, 0x2, 0x3) 425 // /home/rsc/go/src/runtime/x.go:23 +0xf 426 // 427 name := funcname(f) 428 file, line := funcline(f, tracepc) 429 if name == "runtime.gopanic" { 430 name = "panic" 431 } 432 print(name, "(") 433 argp := (*[100]uintptr)(unsafe.Pointer(frame.argp)) 434 for i := uintptr(0); i < frame.arglen/sys.PtrSize; i++ { 435 if i >= 10 { 436 print(", ...") 437 break 438 } 439 if i != 0 { 440 print(", ") 441 } 442 print(hex(argp[i])) 443 } 444 print(")\n") 445 print("\t", file, ":", line) 446 if frame.pc > f.entry { 447 print(" +", hex(frame.pc-f.entry)) 448 } 449 if gp.m != nil && gp.m.throwing > 0 && gp == gp.m.curg || level >= 2 { 450 print(" fp=", hex(frame.fp), " sp=", hex(frame.sp), " pc=", hex(frame.pc)) 451 } 452 print("\n") 453 nprint++ 454 } 455 lastFuncID = f.funcID 456 } 457 n++ 458 459 if f.funcID == funcID_cgocallback_gofunc && len(cgoCtxt) > 0 { 460 ctxt := cgoCtxt[len(cgoCtxt)-1] 461 cgoCtxt = cgoCtxt[:len(cgoCtxt)-1] 462 463 // skip only applies to Go frames. 464 // callback != nil only used when we only care 465 // about Go frames. 466 if skip == 0 && callback == nil { 467 n = tracebackCgoContext(pcbuf, printing, ctxt, n, max) 468 } 469 } 470 471 waspanic = f.funcID == funcID_sigpanic 472 473 // Do not unwind past the bottom of the stack. 474 if !flr.valid() { 475 break 476 } 477 478 // Unwind to next frame. 479 frame.fn = flr 480 frame.pc = frame.lr 481 frame.lr = 0 482 frame.sp = frame.fp 483 frame.fp = 0 484 frame.argmap = nil 485 486 // On link register architectures, sighandler saves the LR on stack 487 // before faking a call to sigpanic. 488 if usesLR && waspanic { 489 x := *(*uintptr)(unsafe.Pointer(frame.sp)) 490 frame.sp += sys.MinFrameSize 491 if GOARCH == "arm64" { 492 // arm64 needs 16-byte aligned SP, always 493 frame.sp += sys.PtrSize 494 } 495 f = findfunc(frame.pc) 496 frame.fn = f 497 if !f.valid() { 498 frame.pc = x 499 } else if funcspdelta(f, frame.pc, &cache) == 0 { 500 frame.lr = x 501 } 502 } 503 } 504 505 if printing { 506 n = nprint 507 } 508 509 // If callback != nil, we're being called to gather stack information during 510 // garbage collection or stack growth. In that context, require that we used 511 // up the entire defer stack. If not, then there is a bug somewhere and the 512 // garbage collection or stack growth may not have seen the correct picture 513 // of the stack. Crash now instead of silently executing the garbage collection 514 // or stack copy incorrectly and setting up for a mysterious crash later. 515 // 516 // Note that panic != nil is okay here: there can be leftover panics, 517 // because the defers on the panic stack do not nest in frame order as 518 // they do on the defer stack. If you have: 519 // 520 // frame 1 defers d1 521 // frame 2 defers d2 522 // frame 3 defers d3 523 // frame 4 panics 524 // frame 4's panic starts running defers 525 // frame 5, running d3, defers d4 526 // frame 5 panics 527 // frame 5's panic starts running defers 528 // frame 6, running d4, garbage collects 529 // frame 6, running d2, garbage collects 530 // 531 // During the execution of d4, the panic stack is d4 -> d3, which 532 // is nested properly, and we'll treat frame 3 as resumable, because we 533 // can find d3. (And in fact frame 3 is resumable. If d4 recovers 534 // and frame 5 continues running, d3, d3 can recover and we'll 535 // resume execution in (returning from) frame 3.) 536 // 537 // During the execution of d2, however, the panic stack is d2 -> d3, 538 // which is inverted. The scan will match d2 to frame 2 but having 539 // d2 on the stack until then means it will not match d3 to frame 3. 540 // This is okay: if we're running d2, then all the defers after d2 have 541 // completed and their corresponding frames are dead. Not finding d3 542 // for frame 3 means we'll set frame 3's continpc == 0, which is correct 543 // (frame 3 is dead). At the end of the walk the panic stack can thus 544 // contain defers (d3 in this case) for dead frames. The inversion here 545 // always indicates a dead frame, and the effect of the inversion on the 546 // scan is to hide those dead frames, so the scan is still okay: 547 // what's left on the panic stack are exactly (and only) the dead frames. 548 // 549 // We require callback != nil here because only when callback != nil 550 // do we know that gentraceback is being called in a "must be correct" 551 // context as opposed to a "best effort" context. The tracebacks with 552 // callbacks only happen when everything is stopped nicely. 553 // At other times, such as when gathering a stack for a profiling signal 554 // or when printing a traceback during a crash, everything may not be 555 // stopped nicely, and the stack walk may not be able to complete. 556 // It's okay in those situations not to use up the entire defer stack: 557 // incomplete information then is still better than nothing. 558 if callback != nil && n < max && _defer != nil { 559 print("runtime: g", gp.goid, ": leftover defer sp=", hex(_defer.sp), " pc=", hex(_defer.pc), "\n") 560 for _defer = gp._defer; _defer != nil; _defer = _defer.link { 561 print("\tdefer ", _defer, " sp=", hex(_defer.sp), " pc=", hex(_defer.pc), "\n") 562 } 563 throw("traceback has leftover defers") 564 } 565 566 if callback != nil && n < max && frame.sp != gp.stktopsp { 567 print("runtime: g", gp.goid, ": frame.sp=", hex(frame.sp), " top=", hex(gp.stktopsp), "\n") 568 print("\tstack=[", hex(gp.stack.lo), "-", hex(gp.stack.hi), "] n=", n, " max=", max, "\n") 569 throw("traceback did not unwind completely") 570 } 571 572 return n 573 } 574 575 // reflectMethodValue is a partial duplicate of reflect.makeFuncImpl 576 // and reflect.methodValue. 577 type reflectMethodValue struct { 578 fn uintptr 579 stack *bitvector // ptrmap for both args and results 580 argLen uintptr // just args 581 } 582 583 // getArgInfoFast returns the argument frame information for a call to f. 584 // It is short and inlineable. However, it does not handle all functions. 585 // If ok reports false, you must call getArgInfo instead. 586 // TODO(josharian): once we do mid-stack inlining, 587 // call getArgInfo directly from getArgInfoFast and stop returning an ok bool. 588 func getArgInfoFast(f funcInfo, needArgMap bool) (arglen uintptr, argmap *bitvector, ok bool) { 589 return uintptr(f.args), nil, !(needArgMap && f.args == _ArgsSizeUnknown) 590 } 591 592 // getArgInfo returns the argument frame information for a call to f 593 // with call frame frame. 594 // 595 // This is used for both actual calls with active stack frames and for 596 // deferred calls that are not yet executing. If this is an actual 597 // call, ctxt must be nil (getArgInfo will retrieve what it needs from 598 // the active stack frame). If this is a deferred call, ctxt must be 599 // the function object that was deferred. 600 func getArgInfo(frame *stkframe, f funcInfo, needArgMap bool, ctxt *funcval) (arglen uintptr, argmap *bitvector) { 601 arglen = uintptr(f.args) 602 if needArgMap && f.args == _ArgsSizeUnknown { 603 // Extract argument bitmaps for reflect stubs from the calls they made to reflect. 604 switch funcname(f) { 605 case "reflect.makeFuncStub", "reflect.methodValueCall": 606 // These take a *reflect.methodValue as their 607 // context register. 608 var mv *reflectMethodValue 609 var retValid bool 610 if ctxt != nil { 611 // This is not an actual call, but a 612 // deferred call. The function value 613 // is itself the *reflect.methodValue. 614 mv = (*reflectMethodValue)(unsafe.Pointer(ctxt)) 615 } else { 616 // This is a real call that took the 617 // *reflect.methodValue as its context 618 // register and immediately saved it 619 // to 0(SP). Get the methodValue from 620 // 0(SP). 621 arg0 := frame.sp + sys.MinFrameSize 622 mv = *(**reflectMethodValue)(unsafe.Pointer(arg0)) 623 // Figure out whether the return values are valid. 624 // Reflect will update this value after it copies 625 // in the return values. 626 retValid = *(*bool)(unsafe.Pointer(arg0 + 3*sys.PtrSize)) 627 } 628 if mv.fn != f.entry { 629 print("runtime: confused by ", funcname(f), "\n") 630 throw("reflect mismatch") 631 } 632 bv := mv.stack 633 arglen = uintptr(bv.n * sys.PtrSize) 634 if !retValid { 635 arglen = uintptr(mv.argLen) &^ (sys.PtrSize - 1) 636 } 637 argmap = bv 638 } 639 } 640 return 641 } 642 643 // tracebackCgoContext handles tracing back a cgo context value, from 644 // the context argument to setCgoTraceback, for the gentraceback 645 // function. It returns the new value of n. 646 func tracebackCgoContext(pcbuf *uintptr, printing bool, ctxt uintptr, n, max int) int { 647 var cgoPCs [32]uintptr 648 cgoContextPCs(ctxt, cgoPCs[:]) 649 var arg cgoSymbolizerArg 650 anySymbolized := false 651 for _, pc := range cgoPCs { 652 if pc == 0 || n >= max { 653 break 654 } 655 if pcbuf != nil { 656 (*[1 << 20]uintptr)(unsafe.Pointer(pcbuf))[n] = pc 657 } 658 if printing { 659 if cgoSymbolizer == nil { 660 print("non-Go function at pc=", hex(pc), "\n") 661 } else { 662 c := printOneCgoTraceback(pc, max-n, &arg) 663 n += c - 1 // +1 a few lines down 664 anySymbolized = true 665 } 666 } 667 n++ 668 } 669 if anySymbolized { 670 arg.pc = 0 671 callCgoSymbolizer(&arg) 672 } 673 return n 674 } 675 676 func printcreatedby(gp *g) { 677 // Show what created goroutine, except main goroutine (goid 1). 678 pc := gp.gopc 679 f := findfunc(pc) 680 if f.valid() && showframe(f, gp, false, funcID_normal, funcID_normal) && gp.goid != 1 { 681 printcreatedby1(f, pc) 682 } 683 } 684 685 func printcreatedby1(f funcInfo, pc uintptr) { 686 print("created by ", funcname(f), "\n") 687 tracepc := pc // back up to CALL instruction for funcline. 688 if pc > f.entry { 689 tracepc -= sys.PCQuantum 690 } 691 file, line := funcline(f, tracepc) 692 print("\t", file, ":", line) 693 if pc > f.entry { 694 print(" +", hex(pc-f.entry)) 695 } 696 print("\n") 697 } 698 699 func traceback(pc, sp, lr uintptr, gp *g) { 700 traceback1(pc, sp, lr, gp, 0) 701 } 702 703 // tracebacktrap is like traceback but expects that the PC and SP were obtained 704 // from a trap, not from gp->sched or gp->syscallpc/gp->syscallsp or getcallerpc/getcallersp. 705 // Because they are from a trap instead of from a saved pair, 706 // the initial PC must not be rewound to the previous instruction. 707 // (All the saved pairs record a PC that is a return address, so we 708 // rewind it into the CALL instruction.) 709 // If gp.m.libcall{g,pc,sp} information is available, it uses that information in preference to 710 // the pc/sp/lr passed in. 711 func tracebacktrap(pc, sp, lr uintptr, gp *g) { 712 if gp.m.libcallsp != 0 { 713 // We're in C code somewhere, traceback from the saved position. 714 traceback1(gp.m.libcallpc, gp.m.libcallsp, 0, gp.m.libcallg.ptr(), 0) 715 return 716 } 717 traceback1(pc, sp, lr, gp, _TraceTrap) 718 } 719 720 func traceback1(pc, sp, lr uintptr, gp *g, flags uint) { 721 // If the goroutine is in cgo, and we have a cgo traceback, print that. 722 if iscgo && gp.m != nil && gp.m.ncgo > 0 && gp.syscallsp != 0 && gp.m.cgoCallers != nil && gp.m.cgoCallers[0] != 0 { 723 // Lock cgoCallers so that a signal handler won't 724 // change it, copy the array, reset it, unlock it. 725 // We are locked to the thread and are not running 726 // concurrently with a signal handler. 727 // We just have to stop a signal handler from interrupting 728 // in the middle of our copy. 729 atomic.Store(&gp.m.cgoCallersUse, 1) 730 cgoCallers := *gp.m.cgoCallers 731 gp.m.cgoCallers[0] = 0 732 atomic.Store(&gp.m.cgoCallersUse, 0) 733 734 printCgoTraceback(&cgoCallers) 735 } 736 737 var n int 738 if readgstatus(gp)&^_Gscan == _Gsyscall { 739 // Override registers if blocked in system call. 740 pc = gp.syscallpc 741 sp = gp.syscallsp 742 flags &^= _TraceTrap 743 } 744 // Print traceback. By default, omits runtime frames. 745 // If that means we print nothing at all, repeat forcing all frames printed. 746 n = gentraceback(pc, sp, lr, gp, 0, nil, _TracebackMaxFrames, nil, nil, flags) 747 if n == 0 && (flags&_TraceRuntimeFrames) == 0 { 748 n = gentraceback(pc, sp, lr, gp, 0, nil, _TracebackMaxFrames, nil, nil, flags|_TraceRuntimeFrames) 749 } 750 if n == _TracebackMaxFrames { 751 print("...additional frames elided...\n") 752 } 753 printcreatedby(gp) 754 755 if gp.ancestors == nil { 756 return 757 } 758 for _, ancestor := range *gp.ancestors { 759 printAncestorTraceback(ancestor) 760 } 761 } 762 763 // printAncestorTraceback prints the traceback of the given ancestor. 764 // TODO: Unify this with gentraceback and CallersFrames. 765 func printAncestorTraceback(ancestor ancestorInfo) { 766 print("[originating from goroutine ", ancestor.goid, "]:\n") 767 for fidx, pc := range ancestor.pcs { 768 f := findfunc(pc) // f previously validated 769 if showfuncinfo(f, fidx == 0, funcID_normal, funcID_normal) { 770 printAncestorTracebackFuncInfo(f, pc) 771 } 772 } 773 if len(ancestor.pcs) == _TracebackMaxFrames { 774 print("...additional frames elided...\n") 775 } 776 // Show what created goroutine, except main goroutine (goid 1). 777 f := findfunc(ancestor.gopc) 778 if f.valid() && showfuncinfo(f, false, funcID_normal, funcID_normal) && ancestor.goid != 1 { 779 printcreatedby1(f, ancestor.gopc) 780 } 781 } 782 783 // printAncestorTraceback prints the given function info at a given pc 784 // within an ancestor traceback. The precision of this info is reduced 785 // due to only have access to the pcs at the time of the caller 786 // goroutine being created. 787 func printAncestorTracebackFuncInfo(f funcInfo, pc uintptr) { 788 name := funcname(f) 789 if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil { 790 inltree := (*[1 << 20]inlinedCall)(inldata) 791 ix := pcdatavalue(f, _PCDATA_InlTreeIndex, pc, nil) 792 if ix >= 0 { 793 name = funcnameFromNameoff(f, inltree[ix].func_) 794 } 795 } 796 file, line := funcline(f, pc) 797 if name == "runtime.gopanic" { 798 name = "panic" 799 } 800 print(name, "(...)\n") 801 print("\t", file, ":", line) 802 if pc > f.entry { 803 print(" +", hex(pc-f.entry)) 804 } 805 print("\n") 806 } 807 808 func callers(skip int, pcbuf []uintptr) int { 809 sp := getcallersp() 810 pc := getcallerpc() 811 gp := getg() 812 var n int 813 systemstack(func() { 814 n = gentraceback(pc, sp, 0, gp, skip, &pcbuf[0], len(pcbuf), nil, nil, 0) 815 }) 816 return n 817 } 818 819 func gcallers(gp *g, skip int, pcbuf []uintptr) int { 820 return gentraceback(^uintptr(0), ^uintptr(0), 0, gp, skip, &pcbuf[0], len(pcbuf), nil, nil, 0) 821 } 822 823 // showframe reports whether the frame with the given characteristics should 824 // be printed during a traceback. 825 func showframe(f funcInfo, gp *g, firstFrame bool, funcID, childID funcID) bool { 826 g := getg() 827 if g.m.throwing > 0 && gp != nil && (gp == g.m.curg || gp == g.m.caughtsig.ptr()) { 828 return true 829 } 830 return showfuncinfo(f, firstFrame, funcID, childID) 831 } 832 833 // showfuncinfo reports whether a function with the given characteristics should 834 // be printed during a traceback. 835 func showfuncinfo(f funcInfo, firstFrame bool, funcID, childID funcID) bool { 836 level, _, _ := gotraceback() 837 if level > 1 { 838 // Show all frames. 839 return true 840 } 841 842 if !f.valid() { 843 return false 844 } 845 846 if funcID == funcID_wrapper && elideWrapperCalling(childID) { 847 return false 848 } 849 850 name := funcname(f) 851 852 // Special case: always show runtime.gopanic frame 853 // in the middle of a stack trace, so that we can 854 // see the boundary between ordinary code and 855 // panic-induced deferred code. 856 // See golang.org/issue/5832. 857 if name == "runtime.gopanic" && !firstFrame { 858 return true 859 } 860 861 return contains(name, ".") && (!hasPrefix(name, "runtime.") || isExportedRuntime(name)) 862 } 863 864 // isExportedRuntime reports whether name is an exported runtime function. 865 // It is only for runtime functions, so ASCII A-Z is fine. 866 func isExportedRuntime(name string) bool { 867 const n = len("runtime.") 868 return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z' 869 } 870 871 // elideWrapperCalling reports whether a wrapper function that called 872 // function id should be elided from stack traces. 873 func elideWrapperCalling(id funcID) bool { 874 // If the wrapper called a panic function instead of the 875 // wrapped function, we want to include it in stacks. 876 return !(id == funcID_gopanic || id == funcID_sigpanic || id == funcID_panicwrap) 877 } 878 879 var gStatusStrings = [...]string{ 880 _Gidle: "idle", 881 _Grunnable: "runnable", 882 _Grunning: "running", 883 _Gsyscall: "syscall", 884 _Gwaiting: "waiting", 885 _Gdead: "dead", 886 _Gcopystack: "copystack", 887 } 888 889 func goroutineheader(gp *g) { 890 gpstatus := readgstatus(gp) 891 892 isScan := gpstatus&_Gscan != 0 893 gpstatus &^= _Gscan // drop the scan bit 894 895 // Basic string status 896 var status string 897 if 0 <= gpstatus && gpstatus < uint32(len(gStatusStrings)) { 898 status = gStatusStrings[gpstatus] 899 } else { 900 status = "???" 901 } 902 903 // Override. 904 if gpstatus == _Gwaiting && gp.waitreason != waitReasonZero { 905 status = gp.waitreason.String() 906 } 907 908 // approx time the G is blocked, in minutes 909 var waitfor int64 910 if (gpstatus == _Gwaiting || gpstatus == _Gsyscall) && gp.waitsince != 0 { 911 waitfor = (nanotime() - gp.waitsince) / 60e9 912 } 913 print("goroutine ", gp.goid, " [", status) 914 if isScan { 915 print(" (scan)") 916 } 917 if waitfor >= 1 { 918 print(", ", waitfor, " minutes") 919 } 920 if gp.lockedm != 0 { 921 print(", locked to thread") 922 } 923 print("]:\n") 924 } 925 926 func tracebackothers(me *g) { 927 level, _, _ := gotraceback() 928 929 // Show the current goroutine first, if we haven't already. 930 g := getg() 931 gp := g.m.curg 932 if gp != nil && gp != me { 933 print("\n") 934 goroutineheader(gp) 935 traceback(^uintptr(0), ^uintptr(0), 0, gp) 936 } 937 938 lock(&allglock) 939 for _, gp := range allgs { 940 if gp == me || gp == g.m.curg || readgstatus(gp) == _Gdead || isSystemGoroutine(gp, false) && level < 2 { 941 continue 942 } 943 print("\n") 944 goroutineheader(gp) 945 // Note: gp.m == g.m occurs when tracebackothers is 946 // called from a signal handler initiated during a 947 // systemstack call. The original G is still in the 948 // running state, and we want to print its stack. 949 if gp.m != g.m && readgstatus(gp)&^_Gscan == _Grunning { 950 print("\tgoroutine running on other thread; stack unavailable\n") 951 printcreatedby(gp) 952 } else { 953 traceback(^uintptr(0), ^uintptr(0), 0, gp) 954 } 955 } 956 unlock(&allglock) 957 } 958 959 // tracebackHexdump hexdumps part of stk around frame.sp and frame.fp 960 // for debugging purposes. If the address bad is included in the 961 // hexdumped range, it will mark it as well. 962 func tracebackHexdump(stk stack, frame *stkframe, bad uintptr) { 963 const expand = 32 * sys.PtrSize 964 const maxExpand = 256 * sys.PtrSize 965 // Start around frame.sp. 966 lo, hi := frame.sp, frame.sp 967 // Expand to include frame.fp. 968 if frame.fp != 0 && frame.fp < lo { 969 lo = frame.fp 970 } 971 if frame.fp != 0 && frame.fp > hi { 972 hi = frame.fp 973 } 974 // Expand a bit more. 975 lo, hi = lo-expand, hi+expand 976 // But don't go too far from frame.sp. 977 if lo < frame.sp-maxExpand { 978 lo = frame.sp - maxExpand 979 } 980 if hi > frame.sp+maxExpand { 981 hi = frame.sp + maxExpand 982 } 983 // And don't go outside the stack bounds. 984 if lo < stk.lo { 985 lo = stk.lo 986 } 987 if hi > stk.hi { 988 hi = stk.hi 989 } 990 991 // Print the hex dump. 992 print("stack: frame={sp:", hex(frame.sp), ", fp:", hex(frame.fp), "} stack=[", hex(stk.lo), ",", hex(stk.hi), ")\n") 993 hexdumpWords(lo, hi, func(p uintptr) byte { 994 switch p { 995 case frame.fp: 996 return '>' 997 case frame.sp: 998 return '<' 999 case bad: 1000 return '!' 1001 } 1002 return 0 1003 }) 1004 } 1005 1006 // Does f mark the top of a goroutine stack? 1007 func topofstack(f funcInfo, g0 bool) bool { 1008 return f.funcID == funcID_goexit || 1009 f.funcID == funcID_mstart || 1010 f.funcID == funcID_mcall || 1011 f.funcID == funcID_morestack || 1012 f.funcID == funcID_rt0_go || 1013 f.funcID == funcID_externalthreadhandler || 1014 // asmcgocall is TOS on the system stack because it 1015 // switches to the system stack, but in this case we 1016 // can come back to the regular stack and still want 1017 // to be able to unwind through the call that appeared 1018 // on the regular stack. 1019 (g0 && f.funcID == funcID_asmcgocall) 1020 } 1021 1022 // isSystemGoroutine reports whether the goroutine g must be omitted 1023 // in stack dumps and deadlock detector. This is any goroutine that 1024 // starts at a runtime.* entry point, except for runtime.main and 1025 // sometimes runtime.runfinq. 1026 // 1027 // If fixed is true, any goroutine that can vary between user and 1028 // system (that is, the finalizer goroutine) is considered a user 1029 // goroutine. 1030 func isSystemGoroutine(gp *g, fixed bool) bool { 1031 // Keep this in sync with cmd/trace/trace.go:isSystemGoroutine. 1032 f := findfunc(gp.startpc) 1033 if !f.valid() { 1034 return false 1035 } 1036 if f.funcID == funcID_runtime_main { 1037 return false 1038 } 1039 if f.funcID == funcID_runfinq { 1040 // We include the finalizer goroutine if it's calling 1041 // back into user code. 1042 if fixed { 1043 // This goroutine can vary. In fixed mode, 1044 // always consider it a user goroutine. 1045 return false 1046 } 1047 return !fingRunning 1048 } 1049 return hasPrefix(funcname(f), "runtime.") 1050 } 1051 1052 // SetCgoTraceback records three C functions to use to gather 1053 // traceback information from C code and to convert that traceback 1054 // information into symbolic information. These are used when printing 1055 // stack traces for a program that uses cgo. 1056 // 1057 // The traceback and context functions may be called from a signal 1058 // handler, and must therefore use only async-signal safe functions. 1059 // The symbolizer function may be called while the program is 1060 // crashing, and so must be cautious about using memory. None of the 1061 // functions may call back into Go. 1062 // 1063 // The context function will be called with a single argument, a 1064 // pointer to a struct: 1065 // 1066 // struct { 1067 // Context uintptr 1068 // } 1069 // 1070 // In C syntax, this struct will be 1071 // 1072 // struct { 1073 // uintptr_t Context; 1074 // }; 1075 // 1076 // If the Context field is 0, the context function is being called to 1077 // record the current traceback context. It should record in the 1078 // Context field whatever information is needed about the current 1079 // point of execution to later produce a stack trace, probably the 1080 // stack pointer and PC. In this case the context function will be 1081 // called from C code. 1082 // 1083 // If the Context field is not 0, then it is a value returned by a 1084 // previous call to the context function. This case is called when the 1085 // context is no longer needed; that is, when the Go code is returning 1086 // to its C code caller. This permits the context function to release 1087 // any associated resources. 1088 // 1089 // While it would be correct for the context function to record a 1090 // complete a stack trace whenever it is called, and simply copy that 1091 // out in the traceback function, in a typical program the context 1092 // function will be called many times without ever recording a 1093 // traceback for that context. Recording a complete stack trace in a 1094 // call to the context function is likely to be inefficient. 1095 // 1096 // The traceback function will be called with a single argument, a 1097 // pointer to a struct: 1098 // 1099 // struct { 1100 // Context uintptr 1101 // SigContext uintptr 1102 // Buf *uintptr 1103 // Max uintptr 1104 // } 1105 // 1106 // In C syntax, this struct will be 1107 // 1108 // struct { 1109 // uintptr_t Context; 1110 // uintptr_t SigContext; 1111 // uintptr_t* Buf; 1112 // uintptr_t Max; 1113 // }; 1114 // 1115 // The Context field will be zero to gather a traceback from the 1116 // current program execution point. In this case, the traceback 1117 // function will be called from C code. 1118 // 1119 // Otherwise Context will be a value previously returned by a call to 1120 // the context function. The traceback function should gather a stack 1121 // trace from that saved point in the program execution. The traceback 1122 // function may be called from an execution thread other than the one 1123 // that recorded the context, but only when the context is known to be 1124 // valid and unchanging. The traceback function may also be called 1125 // deeper in the call stack on the same thread that recorded the 1126 // context. The traceback function may be called multiple times with 1127 // the same Context value; it will usually be appropriate to cache the 1128 // result, if possible, the first time this is called for a specific 1129 // context value. 1130 // 1131 // If the traceback function is called from a signal handler on a Unix 1132 // system, SigContext will be the signal context argument passed to 1133 // the signal handler (a C ucontext_t* cast to uintptr_t). This may be 1134 // used to start tracing at the point where the signal occurred. If 1135 // the traceback function is not called from a signal handler, 1136 // SigContext will be zero. 1137 // 1138 // Buf is where the traceback information should be stored. It should 1139 // be PC values, such that Buf[0] is the PC of the caller, Buf[1] is 1140 // the PC of that function's caller, and so on. Max is the maximum 1141 // number of entries to store. The function should store a zero to 1142 // indicate the top of the stack, or that the caller is on a different 1143 // stack, presumably a Go stack. 1144 // 1145 // Unlike runtime.Callers, the PC values returned should, when passed 1146 // to the symbolizer function, return the file/line of the call 1147 // instruction. No additional subtraction is required or appropriate. 1148 // 1149 // On all platforms, the traceback function is invoked when a call from 1150 // Go to C to Go requests a stack trace. On linux/amd64, linux/ppc64le, 1151 // and freebsd/amd64, the traceback function is also invoked when a 1152 // signal is received by a thread that is executing a cgo call. The 1153 // traceback function should not make assumptions about when it is 1154 // called, as future versions of Go may make additional calls. 1155 // 1156 // The symbolizer function will be called with a single argument, a 1157 // pointer to a struct: 1158 // 1159 // struct { 1160 // PC uintptr // program counter to fetch information for 1161 // File *byte // file name (NUL terminated) 1162 // Lineno uintptr // line number 1163 // Func *byte // function name (NUL terminated) 1164 // Entry uintptr // function entry point 1165 // More uintptr // set non-zero if more info for this PC 1166 // Data uintptr // unused by runtime, available for function 1167 // } 1168 // 1169 // In C syntax, this struct will be 1170 // 1171 // struct { 1172 // uintptr_t PC; 1173 // char* File; 1174 // uintptr_t Lineno; 1175 // char* Func; 1176 // uintptr_t Entry; 1177 // uintptr_t More; 1178 // uintptr_t Data; 1179 // }; 1180 // 1181 // The PC field will be a value returned by a call to the traceback 1182 // function. 1183 // 1184 // The first time the function is called for a particular traceback, 1185 // all the fields except PC will be 0. The function should fill in the 1186 // other fields if possible, setting them to 0/nil if the information 1187 // is not available. The Data field may be used to store any useful 1188 // information across calls. The More field should be set to non-zero 1189 // if there is more information for this PC, zero otherwise. If More 1190 // is set non-zero, the function will be called again with the same 1191 // PC, and may return different information (this is intended for use 1192 // with inlined functions). If More is zero, the function will be 1193 // called with the next PC value in the traceback. When the traceback 1194 // is complete, the function will be called once more with PC set to 1195 // zero; this may be used to free any information. Each call will 1196 // leave the fields of the struct set to the same values they had upon 1197 // return, except for the PC field when the More field is zero. The 1198 // function must not keep a copy of the struct pointer between calls. 1199 // 1200 // When calling SetCgoTraceback, the version argument is the version 1201 // number of the structs that the functions expect to receive. 1202 // Currently this must be zero. 1203 // 1204 // The symbolizer function may be nil, in which case the results of 1205 // the traceback function will be displayed as numbers. If the 1206 // traceback function is nil, the symbolizer function will never be 1207 // called. The context function may be nil, in which case the 1208 // traceback function will only be called with the context field set 1209 // to zero. If the context function is nil, then calls from Go to C 1210 // to Go will not show a traceback for the C portion of the call stack. 1211 // 1212 // SetCgoTraceback should be called only once, ideally from an init function. 1213 func SetCgoTraceback(version int, traceback, context, symbolizer unsafe.Pointer) { 1214 if version != 0 { 1215 panic("unsupported version") 1216 } 1217 1218 if cgoTraceback != nil && cgoTraceback != traceback || 1219 cgoContext != nil && cgoContext != context || 1220 cgoSymbolizer != nil && cgoSymbolizer != symbolizer { 1221 panic("call SetCgoTraceback only once") 1222 } 1223 1224 cgoTraceback = traceback 1225 cgoContext = context 1226 cgoSymbolizer = symbolizer 1227 1228 // The context function is called when a C function calls a Go 1229 // function. As such it is only called by C code in runtime/cgo. 1230 if _cgo_set_context_function != nil { 1231 cgocall(_cgo_set_context_function, context) 1232 } 1233 } 1234 1235 var cgoTraceback unsafe.Pointer 1236 var cgoContext unsafe.Pointer 1237 var cgoSymbolizer unsafe.Pointer 1238 1239 // cgoTracebackArg is the type passed to cgoTraceback. 1240 type cgoTracebackArg struct { 1241 context uintptr 1242 sigContext uintptr 1243 buf *uintptr 1244 max uintptr 1245 } 1246 1247 // cgoContextArg is the type passed to the context function. 1248 type cgoContextArg struct { 1249 context uintptr 1250 } 1251 1252 // cgoSymbolizerArg is the type passed to cgoSymbolizer. 1253 type cgoSymbolizerArg struct { 1254 pc uintptr 1255 file *byte 1256 lineno uintptr 1257 funcName *byte 1258 entry uintptr 1259 more uintptr 1260 data uintptr 1261 } 1262 1263 // cgoTraceback prints a traceback of callers. 1264 func printCgoTraceback(callers *cgoCallers) { 1265 if cgoSymbolizer == nil { 1266 for _, c := range callers { 1267 if c == 0 { 1268 break 1269 } 1270 print("non-Go function at pc=", hex(c), "\n") 1271 } 1272 return 1273 } 1274 1275 var arg cgoSymbolizerArg 1276 for _, c := range callers { 1277 if c == 0 { 1278 break 1279 } 1280 printOneCgoTraceback(c, 0x7fffffff, &arg) 1281 } 1282 arg.pc = 0 1283 callCgoSymbolizer(&arg) 1284 } 1285 1286 // printOneCgoTraceback prints the traceback of a single cgo caller. 1287 // This can print more than one line because of inlining. 1288 // Returns the number of frames printed. 1289 func printOneCgoTraceback(pc uintptr, max int, arg *cgoSymbolizerArg) int { 1290 c := 0 1291 arg.pc = pc 1292 for { 1293 if c > max { 1294 break 1295 } 1296 callCgoSymbolizer(arg) 1297 if arg.funcName != nil { 1298 // Note that we don't print any argument 1299 // information here, not even parentheses. 1300 // The symbolizer must add that if appropriate. 1301 println(gostringnocopy(arg.funcName)) 1302 } else { 1303 println("non-Go function") 1304 } 1305 print("\t") 1306 if arg.file != nil { 1307 print(gostringnocopy(arg.file), ":", arg.lineno, " ") 1308 } 1309 print("pc=", hex(pc), "\n") 1310 c++ 1311 if arg.more == 0 { 1312 break 1313 } 1314 } 1315 return c 1316 } 1317 1318 // callCgoSymbolizer calls the cgoSymbolizer function. 1319 func callCgoSymbolizer(arg *cgoSymbolizerArg) { 1320 call := cgocall 1321 if panicking > 0 || getg().m.curg != getg() { 1322 // We do not want to call into the scheduler when panicking 1323 // or when on the system stack. 1324 call = asmcgocall 1325 } 1326 if msanenabled { 1327 msanwrite(unsafe.Pointer(arg), unsafe.Sizeof(cgoSymbolizerArg{})) 1328 } 1329 call(cgoSymbolizer, noescape(unsafe.Pointer(arg))) 1330 } 1331 1332 // cgoContextPCs gets the PC values from a cgo traceback. 1333 func cgoContextPCs(ctxt uintptr, buf []uintptr) { 1334 if cgoTraceback == nil { 1335 return 1336 } 1337 call := cgocall 1338 if panicking > 0 || getg().m.curg != getg() { 1339 // We do not want to call into the scheduler when panicking 1340 // or when on the system stack. 1341 call = asmcgocall 1342 } 1343 arg := cgoTracebackArg{ 1344 context: ctxt, 1345 buf: (*uintptr)(noescape(unsafe.Pointer(&buf[0]))), 1346 max: uintptr(len(buf)), 1347 } 1348 if msanenabled { 1349 msanwrite(unsafe.Pointer(&arg), unsafe.Sizeof(arg)) 1350 } 1351 call(cgoTraceback, noescape(unsafe.Pointer(&arg))) 1352 }