Skip to content

runtime, runtime/trace: EvGoCreate for empty function may lack stack #55116

@dominikh

Description

@dominikh

One of EvGoCreate's arguments is a stack for the called function. When the called function is empty, and it is the last function in the executable (I think), the stack's only frame has a PC of zero and no information. This is caused by this series of events:

  • runtime.traceGoCreate calls (*runtime.traceStackTable).put with the called function's PC and sys.PCQuantum added to it.
  • (*traceStackTable).dump, which is responsible for writing resolved stack frames to the trace, uses runtime.CallersFrames to turn the PCs into frames
  • (*runtime.Frames).Next calls runtime.findfunc, which calls runtime.findmoduledatap. findmoduledatap contains a loop, searching for the correct module, based on the module's minpc and maxpc: if datap.minpc <= pc && pc < datap.maxpc { return datap } - In our case, however, pc is equal to datap.maxpc.

Looking at an example binary, the last function in it is

000000000046ca60 <main.baz3>:
func baz3() {}
  46ca60:       c3                      ret    
  46ca61:       cc                      int3   
  46ca62:       cc                      int3   
  46ca63:       cc                      int3   
  46ca64:       cc                      int3   
  46ca65:       cc                      int3   
  46ca66:       cc                      int3   
  46ca67:       cc                      int3   
  46ca68:       cc                      int3   
  46ca69:       cc                      int3   
  46ca6a:       cc                      int3   
  46ca6b:       cc                      int3   
  46ca6c:       cc                      int3   
  46ca6d:       cc                      int3   
  46ca6e:       cc                      int3   
  46ca6f:       cc                      int3   

On go baz3, the EvGoCreate event contains a stack with the PC 46ca60 + 1 (I'm on amd64, where sys.PCQuantum is 1). The last module that findmoduledatap looks at has a maxpc of 46ca61, which equals our PC. findmoduledatap returns nil because it couldn't find a matching module, and that bubbles all the way up to (*runtime.Frames).Next returning an empty runtime.Frame.

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions