callgraphutil

package
v0.0.0-...-3011e23 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 26, 2025 License: MPL-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package callgraphutil implements utilities for golang.org/x/tools/go/callgraph including path searching, graph construction, printing, and more.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddFunction

func AddFunction(cg *callgraph.Graph, target *ssa.Function, allFns map[*ssa.Function]bool) error

AddFunction analyzes the given target SSA function, adding information to the call graph.

Based on the implementation of golang.org/x/tools/cmd/guru/callers.go: https://cs.opensource.google/go/x/tools/+/master:cmd/guru/callers.go;drc=3e0d083b858b3fdb7d095b5a3deb184aa0a5d35e;bpv=1;bpt=1;l=90

func CreateMultiRootCallGraph

func CreateMultiRootCallGraph(prog *ssa.Program, srcFns []*ssa.Function) (*callgraph.Graph, *ssa.Function, error)

CreateMultiRootCallGraph creates a callgraph for library packages by using multiple potential entry points. It creates a callgraph by trying different entry points and selecting the one that produces the most semantically meaningful analysis.

func GraphString

func GraphString(g *callgraph.Graph) string

GraphString returns a string representation of the call graph, which is a sequence of nodes separated by newlines, with the callees of each node indented by a tab.

func InstructionsFor

func InstructionsFor(root *callgraph.Node, v ssa.Value) (si ssa.Instruction)

InstructionsFor returns the ssa.Instruction for the given ssa.Value using the given node as the root of the call graph that is searched.

func NewGraph

func NewGraph(root *ssa.Function, srcFns ...*ssa.Function) (*callgraph.Graph, error)

NewGraph returns a new Graph with the specified root node.

Typically, the root node is the main function of the program, and the srcFns are the source functions that are of interest to the caller. But, the root node can be any function, and the srcFns can be any set of functions.

This algorithm attempts to add all source functions reachable from the root node by traversing the SSA IR and adding edges to the graph; it handles calls to functions, methods, closures, and interfaces. It may miss some complex edges today, such as stucts containing function fields accessed via slice or map indexing. This is a known limitation, but something we hope to improve in the near future. https://github.com/picatz/taint/issues/23

Performance optimizations: - Caches AllFunctions results per SSA program for massive speedup on large codebases - Early exits to skip non-relevant instructions (~90% reduction) - Pre-allocated data structures to minimize allocations - Streamlined processing paths for common cases - Comprehensive logging for progress tracking on large codebases

The function respects context cancellation and provides detailed progress logging when a logger is present in the context via WithLogger().

func NewGraphWithContext

func NewGraphWithContext(ctx context.Context, root *ssa.Function, srcFns ...*ssa.Function) (*callgraph.Graph, error)

NewGraphWithContext creates a new call graph with context support for cancellation and logging

func NewVulncheckCallGraph

func NewVulncheckCallGraph(ctx context.Context, prog *ssa.Program, entries []*ssa.Function) (*callgraph.Graph, error)

NewVulncheckCallGraph builds a call graph of prog based on VTA analysis, straight from the govulncheck project. This is used to demonstrate the difference between the call graph built by this package's algorithm and govulncheck's algorithm (based on CHA and VTA analysis).

This method is based on the following: https://github.com/golang/vuln/blob/7335627909c99e391cf911fcd214badcb8aa6d7d/internal/vulncheck/utils.go#L63

func PathsSearchCallToAdvanced

func PathsSearchCallToAdvanced(start *callgraph.Node, pattern string) ([]Path, MatchStrategy, error)

PathsSearchCallToAdvanced provides advanced function matching with automatic strategy detection. This is the standard function for finding paths from a single starting node to functions matching a pattern. The pattern format determines the matching strategy:

  • "pattern" or "exact:pattern" → exact string matching
  • "fuzzy:pattern" → substring/fuzzy matching
  • "glob:pattern" → shell-style glob matching
  • "regex:pattern" → regular expression matching

Returns all discovered paths, the detected strategy, and any error that occurred.

func PathsSearchCallToAdvancedAllNodes

func PathsSearchCallToAdvancedAllNodes(graph *callgraph.Graph, pattern string) ([]Path, MatchStrategy, error)

PathsSearchCallToAdvancedAllNodes provides comprehensive function matching across all nodes in a callgraph. Unlike PathsSearchCallToAdvanced, this function handles disconnected callgraphs by searching beyond just the nodes reachable from the root, making it ideal for library analysis where functions may not be directly connected to the main entry point.

The function uses a two-phase approach:

  1. First attempts normal path search from the callgraph root
  2. If no paths found, scans all nodes for matches and finds direct callers

Returns all discovered paths, the matching strategy used, and any error that occurred.

func WithLogger

func WithLogger(ctx context.Context, logger *Logger) context.Context

WithLogger adds a logger to the context

func WriteCSV

func WriteCSV(w io.Writer, g *callgraph.Graph) error

WriteCSV writes the given callgraph.Graph to the given io.Writer in CSV format. This format can be used to generate a visual representation of the call graph using many different tools.

func WriteCosmograph

func WriteCosmograph(graph, metadata io.Writer, g *callgraph.Graph) error

WriteComsmograph writes the given callgraph.Graph to the given io.Writer in CSV format, which can be used to generate a visual representation of the call graph using Comsmograph.

https://cosmograph.app/run/

func WriteDOT

func WriteDOT(w io.Writer, g *callgraph.Graph) error

WriteDOT writes the given callgraph.Graph to the given io.Writer in the DOT format, which can be used to generate a visual representation of the call graph using Graphviz.

Types

type Edges

type Edges = []*callgraph.Edge

Edges is a handy alias for a slice of callgraph.Edges.

type FunctionMatcher

type FunctionMatcher struct {
	// contains filtered or unexported fields
}

FunctionMatcher provides flexible function name matching with multiple strategies

func NewFunctionMatcher

func NewFunctionMatcher(pattern string, strategy MatchStrategy) (*FunctionMatcher, error)

NewFunctionMatcher creates a new matcher with explicit strategy

func NewFunctionMatcherFromString

func NewFunctionMatcherFromString(input string) (*FunctionMatcher, error)

NewFunctionMatcherFromString creates a matcher by parsing a pattern with optional prefix Supported formats:

  • "exact:pattern" - exact matching
  • "fuzzy:pattern" - substring matching
  • "glob:pattern" - glob pattern matching
  • "regex:pattern" - regular expression matching
  • "pattern" - defaults to exact matching

func (*FunctionMatcher) Match

func (m *FunctionMatcher) Match(funcName string) bool

Match returns true if the function name matches according to the strategy

func (*FunctionMatcher) Pattern

func (m *FunctionMatcher) Pattern() string

Pattern returns the pattern being matched

func (*FunctionMatcher) Strategy

func (m *FunctionMatcher) Strategy() MatchStrategy

Strategy returns the matching strategy being used

func (*FunctionMatcher) String

func (m *FunctionMatcher) String() string

String returns a string representation of the matcher

type LogLevel

type LogLevel int

LogLevel represents different levels of logging detail

const (
	LogLevelSilent LogLevel = iota
	LogLevelInfo
	LogLevelDebug
	LogLevelTrace
)

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

Logger provides structured logging for call graph operations

func FromContext

func FromContext(ctx context.Context) *Logger

FromContext retrieves a logger from the context, returning a no-op logger if none exists

func NewLogger

func NewLogger(level LogLevel, writer io.Writer) *Logger

NewLogger creates a new logger with the specified level and output

func (*Logger) Debug

func (l *Logger) Debug(format string, args ...interface{})

Debug logs debug messages (visible in debug and trace modes)

func (*Logger) Error

func (l *Logger) Error(format string, args ...interface{})

Error logs error messages (always visible except silent mode)

func (*Logger) Info

func (l *Logger) Info(format string, args ...interface{})

Info logs informational messages (always visible except silent mode)

func (*Logger) Progress

func (l *Logger) Progress(operation string, current, total int, elapsed time.Duration)

Progress logs progress information with timing

func (*Logger) Step

func (l *Logger) Step(step string, details ...string)

Step logs a processing step with context

func (*Logger) Trace

func (l *Logger) Trace(format string, args ...interface{})

Trace logs detailed trace messages (visible only in trace mode)

func (*Logger) Warning

func (l *Logger) Warning(format string, args ...interface{})

Warning logs warning messages

func (*Logger) WithPrefix

func (l *Logger) WithPrefix(prefix string) *Logger

WithPrefix returns a new logger with an additional prefix

type MatchStrategy

type MatchStrategy int

MatchStrategy represents different ways to match function names

const (
	// MatchExact requires an exact string match (default)
	MatchExact MatchStrategy = iota
	// MatchFuzzy uses substring matching
	MatchFuzzy
	// MatchGlob uses shell-style pattern matching with *, ?, []
	MatchGlob
	// MatchRegex uses regular expression matching
	MatchRegex
)

func ParseMatchStrategy

func ParseMatchStrategy(strategy string) MatchStrategy

ParseMatchStrategy parses a strategy string into a MatchStrategy

func (MatchStrategy) String

func (m MatchStrategy) String() string

String returns a human-readable description of the match strategy

type Nodes

type Nodes = []*callgraph.Node

Nodes is a handy alias for a slice of callgraph.Nodes.

func CalleesOf

func CalleesOf(caller *callgraph.Node) Nodes

CalleesOf returns nodes that are called by the caller node.

func CallersOf

func CallersOf(callee *callgraph.Node) Nodes

CallersOf returns nodes that call the callee node.

type Path

type Path []*callgraph.Edge

Path is a sequence of callgraph.Edges, where each edge represents a call from a caller to a callee, making up a "chain" of calls, e.g.: main → foo → bar → baz.

func PathSearch

func PathSearch(start *callgraph.Node, isMatch func(*callgraph.Node) bool) Path

PathSearch returns the first path found from the start node to a node that matches the isMatch function. This is a depth first search, so it will return the first path found, which may not be the shortest path.

To find all paths, use PathsSearch, which returns a collection of paths.

func PathSearchCallTo

func PathSearchCallTo(start *callgraph.Node, fn string) Path

PathSearchCallTo returns the first path found from the start node to a node that matches the function name.

func (Path) Empty

func (p Path) Empty() bool

Empty returns true if the path is empty, false otherwise.

func (Path) First

func (p Path) First() *callgraph.Edge

First returns the first edge in the path, or nil if the path is empty.

func (Path) Last

func (p Path) Last() *callgraph.Edge

Last returns the last edge in the path, or nil if the path is empty.

func (Path) String

func (p Path) String() string

String returns a string representation of the path which is a sequence of edges separated by " → ".

Intended to be used while debugging.

type Paths

type Paths []Path

Paths is a collection of paths, which may be logically grouped together, e.g.: all paths from main to foo, or all paths from main to bar.

func PathsSearch

func PathsSearch(start *callgraph.Node, isMatch func(*callgraph.Node) bool) Paths

PathsSearch returns all paths found from the start node to a node that matches the isMatch function. Under the hood, this is a depth first search.

To find the first path (which may not be the shortest), use PathSearch.

func PathsSearchCallTo

func PathsSearchCallTo(start *callgraph.Node, fn string) Paths

PathsSearchCallTo returns the paths that call the given function name, which uses SSA function name syntax, e.g.: "(*database/sql.DB).Query".

func PathsSearchCallToAdvancedWithStrategy

func PathsSearchCallToAdvancedWithStrategy(start *callgraph.Node, pattern string, strategy MatchStrategy) (Paths, error)

PathsSearchCallToAdvancedWithStrategy provides advanced function matching with explicit strategy

func PathsSearchCallToPartial

func PathsSearchCallToPartial(start *callgraph.Node, partialName string) Paths

PathsSearchCallToPartial returns the paths that call functions containing the given substring. This is a legacy function that provides simple substring matching. Consider using PathsSearchCallToAdvancedAllNodes with "fuzzy:pattern" for more comprehensive matching that handles disconnected callgraphs better.

func PathsSearchCallToWithMatcher

func PathsSearchCallToWithMatcher(start *callgraph.Node, matcher *FunctionMatcher) Paths

PathsSearchCallToWithMatcher returns paths that call functions matching the given matcher

func (Paths) Longest

func (p Paths) Longest() Path

Longest returns the longest path in the collection of paths.

If there are no paths, this returns nil. If there are multiple paths of the same length, the first path found is returned.

func (Paths) Shortest

func (p Paths) Shortest() Path

Shortest returns the shortest path in the collection of paths.

If there are no paths, this returns nil. If there are multiple paths of the same length, this returns the first path found.

type ProgressTracker

type ProgressTracker struct {
	// contains filtered or unexported fields
}

ProgressTracker tracks progress of long-running operations with intelligent batching

func NewProgressTracker

func NewProgressTracker(ctx context.Context, name string, total int) *ProgressTracker

NewProgressTracker creates a new progress tracker

func (*ProgressTracker) Complete

func (pt *ProgressTracker) Complete()

Complete marks the operation as finished

func (*ProgressTracker) Update

func (pt *ProgressTracker) Update(message string)

Update increments progress and logs intelligently

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL