Skip to content

cl: make recursive runtime.Caller reachability order-independent #2320

Description

@cpunion

Problem

runtimeCallerAnalysis.fnMayReachRuntimeCaller can cache an order-dependent false result for a recursive call cycle.

When DFS reaches a function already present in visiting, it returns false. A caller in the same cycle may then memoize that provisional result before another member's direct runtime.Caller edge is visited.

Minimal shape:

package cycle

import "runtime"

func a() {
	b()
	runtime.Caller(0)
}

func b() {
	a()
}

If a is analyzed first, the a -> b -> a back-edge can cause b to be memoized as false before a reaches runtime.Caller. If b is analyzed first, both functions are classified correctly. The starting function comes from map iteration.

A local probe that rebuilt and analyzed this package 100 times omitted b from computeRuntimeCallerBaseSet in 79 runs.

Impact

Caller-frame tracking can under-approximate recursive SCCs and vary with map iteration order. This may allow a frame that can reach runtime.Caller to be inlined or tail-called.

Suggested direction

Compute reachability to caller consumers as a graph fixed point or over strongly connected components, so a positive edge propagates through the entire recursive component. Add a regression that repeats with controlled visitation orders rather than relying on randomized map iteration.

This behavior predates #2293 and was identified while handling its review; it should be fixed separately to keep that PR scoped to recover-visible panic-site tracking.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions