The escape analysis extension in QLStat enables integration of Go's compiler escape analysis data with CodeQL queries. This allows developers to analyze memory allocation patterns and identify variables that are allocated on the heap versus stack.
The architecture follows these steps:
- Compilation with Escape Analysis: The Go compiler is invoked with
-gcflags=-m=2 ./...to generate detailed escape analysis information during compilation. - Log Collection: The compiler's stderr output containing escape analysis results is captured in log files (e.g.,
m2.log). - Data Extraction: The escape_adapter tool parses these logs and extracts information about which variables are moved to the heap.
- Predicate Generation: The extracted data is converted into CSV format as external predicates for CodeQL.
- Query Integration: CodeQL queries can reference this external predicate data to correlate code patterns with memory allocation behavior.
This extension bridges static analysis (CodeQL) with compiler-level optimization insights, enabling sophisticated queries about memory usage patterns across large codebases.
The following example from movedtoheap_test.yaml demonstrates how to use the escape analysis extension:
# Configuration for escape analysis extension
externalGenGrps:
- genRepos:
- "-"
genScript: goescape # This triggers go build with -gcflags=-m=2 ./...
queryconfig:
queryGrps:
- queryRepos:
- escape
queries:
- escape_ext/moved_to_heap_var_test.ql # The queries you want to use
externals:
- movedToHeap # Reference the external predicate in your query groupIn this configuration:
genScript: goescapeinstructs the system to compile repositories with escape analysis enabledexternals: [movedToHeap]makes the escape analysis data available to the specified queries. The external data table is located in$dbRoot/<path/to/repo>/ext/movedToHeap.csv.- The query
escape_ext/moved_to_heap_var_test.qlcan then use themovedToHeappredicate to identify variables that escape to the heap
This enables queries that answer questions like "Which functions have parameters that always escape to the heap?" or "What patterns correlate with heap allocation in goroutines?"
You can also use demo.sh as your first try.
The following performance improvements are detected by escape_ext/heapvar_should_move.ql.
| Repository | Problematic Commit | Pull Request/Issue |
|---|---|---|
| rclone/rclone | 73bcae224 | rclone/rclone#9079 |
| junegunn/fzf | 416aff | junegunn/fzf#4739 |
| cli/cli | 8723e3b | cli/cli#13033 |
protoactor-go
plan
Repositories that have been scanned by escape_ext/heapvar_should_move.ql are listed in escape_analysis/repos_scanned.txt.
The alerts of escape_ext/heapvar_should_move.ql to be checked by human are listed in escape_analysis/alerts.yaml.
