Skip to content

Add lifetimes command to analyze stack variable lifetimes#13

Merged
dylandreimerink merged 1 commit into
mainfrom
feature/lifetimes
Jul 16, 2026
Merged

Add lifetimes command to analyze stack variable lifetimes#13
dylandreimerink merged 1 commit into
mainfrom
feature/lifetimes

Conversation

@dylandreimerink

@dylandreimerink dylandreimerink commented Jul 16, 2026

Copy link
Copy Markdown
Member

This works adds a new command which analyzes the lifetimes of stack variables. It outputs an SVG graph which show each stack offset on the vertical axis and the instructions on the horizontal axis. Colored bars represent a lifetime, where a lifetime is the time between the first write and the last read of a stack variable. The writes are marked by black dots and the reads are marked by white dots.

The idea of this is that we should be able to see which lifetimes overlap and thus why more space was allocated. In theory showing us the places in the program where the least stack re-use was possible. Focusing on reducing stack usage at that point the the program should yield best results when reducing stack usage.

The code itself works by doing static analysis of the assembly code to get basic blocks. Then visiting all basic blocks and walking the instructions, keeping track of register and stack state. Sort of like a very limited shitty verifier. We record all reads and writes to the stack, including those done by helper functions.

Once we have all reads and writes, we iterate over all the reads and traverse the graph of basic blocks backwards, finding writes to the same stack offset. When we find them, we record a lifetime spanning the stack of basic blocks we traversed backwards. Overlapping lifetimes get merged since these are likely modifications of the same variable or variable reuse. Each lifetime gets its own color to allow users to see when a stack offset gets reused.

AI disclosure: AIL 2, core is handwritten, AI made modifications after review, everything manually reviewed.

Fixes: #2

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new lifetimes CLI command intended to statically analyze eBPF assembly, derive stack-slot read/write lifetimes across basic blocks, and render the result as an SVG timeline to help explain stack allocation/reuse decisions.

Changes:

  • Adds an internal/analyze package to build basic blocks / CFG metadata from asm.Instructions, with tests and benchmarks.
  • Adds stackwhere lifetimes to generate an SVG visualization of stack-slot lifetimes, plus supporting helper modeling.
  • Updates testdata build targets and introduces a new dump-dwarf command wiring in cmd/stackwhere/main.go, along with new Go test dependencies.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
testdata/spill.c Refactors test C source includes/macros for BPF test program.
testdata/Makefile Adds lifetimes to the testdata build target list.
internal/analyze/util.go Adds helper types/utilities for resolving jump targets and connecting call relationships.
internal/analyze/blocks.go Implements basic-block construction, iterators, and backtracking over a CFG.
internal/analyze/blocks_test.go Adds unit tests and benchmarks for block construction and iteration.
go.mod Adds testify and new indirect dependencies for tests.
go.sum Updates checksums for added dependencies.
cmd/stackwhere/main.go Registers the new lifetimes and dump-dwarf subcommands.
cmd/stackwhere/lifetimes.go Implements the lifetimes command, analysis visitor, lifetime discovery, and SVG output.
cmd/stackwhere/dwarf.go Adds a dump-dwarf command to inspect DWARF/subprogram mapping.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cmd/stackwhere/dwarf.go Outdated
Comment thread cmd/stackwhere/dwarf.go Outdated
Comment thread cmd/stackwhere/dwarf.go Outdated
Comment thread cmd/stackwhere/lifetimes.go Outdated
Comment thread cmd/stackwhere/lifetimes.go
Comment thread cmd/stackwhere/lifetimes.go Outdated
Comment thread internal/analyze/util.go
Comment thread internal/analyze/util.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 9 changed files in this pull request and generated 10 comments.

Comment thread cmd/stackwhere/lifetimes.go
Comment thread cmd/stackwhere/lifetimes.go
Comment thread cmd/stackwhere/lifetimes.go
Comment thread cmd/stackwhere/lifetimes.go
Comment thread cmd/stackwhere/lifetimes.go
Comment thread cmd/stackwhere/lifetimes.go
Comment thread cmd/stackwhere/lifetimes.go
Comment thread internal/analyze/util.go
Comment thread internal/analyze/util.go
Comment thread internal/analyze/blocks.go Outdated
This works adds a new command which analyzes the lifetimes of stack
variables. It outputs an SVG graph which show each stack offset on the
vertical axis and the instructions on the horizontal axis. Colored bars
represent a lifetime, where a lifetime is the time between the first
write and the last read of a stack variable. The writes are marked by
black dots and the reads are marked by white dots.

The idea of this is that we should be able to see which lifetimes
overlap and thus why more space was allocated. In theory showing us the
places in the program where the least stack re-use was possible.
Focusing on reducing stack usage at that point the the program should
yield best results when reducing stack usage.

The code itself works by doing static analysis of the assembly code to
get basic blocks. Then visiting all basic blocks and walking the
instructions, keeping track of register and stack state. Sort of like
a very limited shitty verifier. We record all reads and writes to the
stack, including those done by helper functions.

Once we have all reads and writes, we iterate over all the reads and
traverse the graph of basic blocks backwards, finding writes to the same
stack offset. When we find them, we record a lifetime spanning the stack
of basic blocks we traversed backwards. Overlapping lifetimes get merged
since these are likely modifications of the same variable or variable
reuse. Each lifetime gets its own color to allow users to see when
a stack offset gets reused.

Signed-off-by: Dylan Reimerink <dylan.reimerink@isovalent.com>
@dylandreimerink
dylandreimerink merged commit da98cd3 into main Jul 16, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: visualize variable lifetimes

2 participants