This page contains resources to get familiar with the SFrame stack trace format. This page also contains the current status of SFrame support and current/future projects involving SFrame stack trace format.
If you have any questions, comments or would like to contribute, please get in touch at binutils@sourceware.org.
IRC channel: #sframe at irc.oftc.net
Monthly meetings: Two meetings monthly (one in Asia friendly timezone and the other in Europe friendly timezone). Please get in touch if interested in joining.
Contents
Specifications
Change History
GNU Binutils 2.40
SFrame Version 1 (Obsoleted, Do not use)
Support for x86_64, AArch64
GNU Binutils 2.41
SFrame Version 2
Fix for unaligned SFrame FDEs, Fix Rep Block representation
GNU Binutils 2.44
SFrame Version 2
Bugfixes
GNU Binutils 2.45
SFrame Version 2 (Errata 1)
Relocatable links fixed, Support for s390x
GNU Binutils 2.46
SFrame Version 3
TBD
Mark outermost frame, Support for text > 2GiB, ...
What is SFrame stack trace format?
Given an execution stack and a starting point in the form of a program counter, a "stack trace" is the sequence of program counters corresponding to the nested calls leading to the starting point. Determining these program counters involves examining the stack, starting at the stack frame corresponding to the starting point all the way to the bottom. Stack traces are useful for debugging and profiling purposes, where they allow to answer questions like "how did we come to this point in the program?".
It is obvious that just having access to a stack is generally not enough to create a stack trace. For starters, it is necessary to determine the location of the previous stack frame and, based on information stored there, somehow determine the call site location in the function that created that frame. Some of the information required to this is stored in the stack frames themselves, in a more or less suitable form. For example, a "return address" is sometimes stored in the stack frame of the callee by the caller function. More often than not, however, the return address may be stored in some register and not on the stack. Therefore the stack itself is not enough: we need some auxiliary extra information that must be found somewhere else. This is where stack trace formats come into play: these define the format of the metadata which is necessary in order to perform stack tracing.
SFrame is a stack trace format which keeps track of the minimal necessary information needed for generating stack traces. It is easy to read, easy to write, and easy to use, and it is particularly well suited for online operations such as tracing and error recovery. It shares many similarities with the kernel-specific ORC format, but unlike the latter SFrame is not limited to kernel code.
SFrame supports x86_64, aarch64 and s390x. The SFrame specification can be updated to add other architectures/ABIs.
Why SFrame?
The solution space of stack tracing methods is somewhat wide, with some solutions being ABI/arch specific. But in principle, the two most commonly used methods include : frame pointer based stack tracing and EH Frame based stack tracing.
Stack tracing using frame pointer is easy, but may be unreliable and may cost performance. On architectures where setting up the frame pointer is done non-atomically using a few instructions in prologue, stack tracing is going to be unreliable. A back-of-the-envelope estimate suggests a 5-7% of stack traces may be impacted with this (on x86_64 and AArch64). On some architectures, it is also a performance hit to enforce that the applications preserve frame pointer register at all times.
The other well-known method is using .eh_frame. EH Frame is a dwarf-based format, and provides reliable stack traces. However, EH Frame based stack tracer is undesirable in some usecases; it may be too bulky in some resource constrained environments.
These issues have already led to bifurcation in the space of stack tracing, leading to some projects adopting their own, in-house solutions for stack tracing. The Linux kernel uses its own in-house stack trace format called ORC. Other solutions have also come up while trying to solve the problem of system profiling in general.
SFrame stack trace format aims to provide a method to:
- enable fast and low-overhead stack tracing,
- reliable and asynchronous stack tracing
It does so without the need to preserve frame pointer in the application code. It can be used in cases when EH Frame based stack tracing is undesirable or infeasible.
Generating SFrame section
Since Binutils 2.41, when the command line option --gsframe is specified, GNU assembler generates a .sframe section in SFrame V2 format. When --gsframe is specified, GNU assembler consumes the.cfi_* directives to create an .sframe section. When the input object files contain .sframe section, GNU ld links the input .sframe sections and the final linked object then contains an allocatable section named .sframe. The .sframe section appears in a segment of its own, with the type set to PT_GNU_SFRAME.
$ gcc -Wa,--gsframe test.c -o test
$ objdump --sframe test
...
Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
Flags: SFRAME_F_FDE_SORTED
CFA fixed RA offset: -8
Num FDEs: 8
Num FREs: 26
Function Index :
...
func idx [5]: pc = 0x4005b0, size = 53 bytes
STARTPC CFA FP RA
00000000004005b0 sp+8 u f
00000000004005b1 sp+16 c-16 f
00000000004005b4 fp+16 c-16 f
00000000004005e4 sp+8 c-16 f
...Under the hood, the libsframe library in Binutils is used. It has APIs for reading, writing and linking .sframe sections. GNU ld uses libsframe to link SFrame sections; objdump and readelf use it to dump SFrame section data in textual format.
New in Binutils 2.45
SFrame V2 with erratum fix (new flag SFRAME_F_FUNC_START_ADDR_PCREL) will be released with Binutils 2.45. Also SFrame ELF sections will be of section type SHT_GNU_SFRAME. The GNU Binutils 2.45 release also includes other important bugfixes (TBD, list).
Note for Distro-wide enablement
We are aiming to use SFrame V3 for any distro wide builds for GNU/Linux ecosystem. If you are a distro and are interested in SFrame, please get in touch. The userspace stack tracer in the Linux kernel will support V3 and above, so there is little incentive to create SFrame V2 binaries distro wide.
Current Tasks
SFrame GNU Binutils work items
All open bug reports https://sourceware.org/bugzilla/buglist.cgi?quicksearch=sframe&list_id=86629
- Generate SFrame stack trace data for PLT and veneers on AArch64
- Find ways to set SFRAME_F_FRAME_POINTER reliably. Currently this flag is never set as the GNU assembler does not have enough visibility.
- Target SFrame V3 for Binutils 2.46 release.
Projects involving SFrame
This is a non-exhaustive list of projects involving SFrame.
SFrame based user space stack tracing in the Linux kernel
Userspace stack tracing in the Linux kernel is broken down into three sets of work:
- Deferred stack tracing infrastructure
- perf adapting to the deferred user space stack tracing infra
- SFrame based stack tracer
Deferred stack tracing infrastructure has been merged. Collecting userspace stack traces (using SFrame) from the kernel may require paging in memory, which is not allowed in certain contexts (e.g., NMI context). The solution is to defer the stack trace collection. The kernel requests a userspace stack trace and stores a "cookie" or token to identify it. The actual stack trace collection is postponed until the task is about to return to userspace, a point where it's safe to handle page faults. The stack trace is collected and then matched with the corresponding kernel context using the saved cookie.
Current perf patchset (and _2.44-Binutils_ based SFrame) info here.
Previous patchsets:
- [June 2025][unwind_deferred: Implement sframe handling]
- [June 2025][perf: Support the deferred unwinding infrastructure]
- [June 2025][unwind_user: x86: Deferred unwinding infrastructure]
- SFrame based user space stack tracing in the Linux kernel
- Adjust perf tools to support deferred user callchains
Kernel space stack tracing to enable livepatching (ARM64)
This is work in progress.
- SFrame based kernel space stack tracing to enable livepatching on ARM64
Following bugs are known to affect relocatable links:
- Incorrect .rela.sframe when using ld -r
(Bugzilla: https://sourceware.org/bugzilla/show_bug.cgi?id=32666 Status: FIXED in 2.45)
- function start address is zero in SFrame section dump
(Bugzilla: https://sourceware.org/bugzilla/show_bug.cgi?id=32589 Status: FIXED in 2.45)
Status: RFC patchset - (link), Proposed Patchset - (link)
Planned release in 2.45 (Summer 2025). This will be introduced using a new flag (SFRAME_F_FDE_FUNC_START_ADDR_PCREL) in the SFrame header flags in SFrame version 2.
Support SFrame based stack tracing in glibc backtrace
Provide signal-safe, SFrame based stack tracing in glibc. The current 'int backtrace (void **buffer, int size)' interface can then use SFrame based stack tracer under the hood (if SFrame stack trace data is available), with the current libgcc_s based stack tracer as the fallback stack tracer.
It is also required to ensure building glibc with SFrame enabled works well. On the aarch64 side, ensure correct SFrame for ARM64 vDSO.
SFrame support for backtrace () is available in glibc 2.42. V6 patchset.
Following bugs are known to affect glibc builds:
- sframe: wrong SFrame info for pltN and .plt.sec for -z ibtplt
(Bugzilla: https://sourceware.org/bugzilla/show_bug.cgi?id=32296 Status: FIXED in 2.44)
- sframe: bfd assertion with empty main on IBT enabled system
(Bugzilla: https://sourceware.org/bugzilla/show_bug.cgi?id=32297 Status: FIXED in 2.44)
- sframe: no SFrame stack trace info generated for .plt.got
(Bugzilla: https://sourceware.org/bugzilla/show_bug.cgi?id=32298 Status: FIXED in 2.44)
- sframe: Assembler internal error when translating cfi_def_cfa_register
(Bugzilla: https://sourceware.org/bugzilla/show_bug.cgi?id=32879 Status: FIXED in 2.45)
- sframe: incorrect handling of .cfi_undefined in gas
(Bugzilla: https://sourceware.org/bugzilla/show_bug.cgi?id=32952 Status: FIXED in 2.45)
- sframe: incorrect handling of .cfi_same_value in gas
(Bugzilla: https://sourceware.org/bugzilla/show_bug.cgi?id=32953 Status: FIXED in 2.45)
SFrame based stack tracing library for user-space applications
For the use case of in-process stack tracing and profiling, it is useful to provide means to user space applications to stack walk using .sframe section when available. elfutils has been suggested as a possible option for providing such a support.
SFrame for JIT
The goal of this project is to ensure that SFrame stack trace format can support the usecase of stacktracing for JIT compiled applications. The need to stack trace through a variety of frames (compiled/interpreted/native) with a variety of lifetimes is a distinct feature of JIT environments. Some parts of the application are short-lived and those address spaces are going to re-used over and over. The stack trace format should provide mechanisms so that the runtime can efficiently deal with long-running vs short-lived JIT code. The three main areas of discussion are:
- SFrame specification: Allow efficient addition, removal and update of data in .sframe sections.
- SFrame APIs with JIT: Efficient SFrame stack trace data manipulation by JIT.
- Interface with Linux kernel: Efficient SFrame stack trace data registration and update stack trace data.
SFrame V3
Version 3 of the SFrame specification is currently under development.
Resources
- "SFrame: fast, low-overhead stack traces"
- "SFrame: The Simple Frame stack trace format" at OSS NA 2023
- "Next steps for SFrame stack trace format" at GNU Tools Cauldron 2024
- "SFrame-based stack unwinding for the kernel"
- Blog: "Beyond EH Frame and Frame Pointers: The Technical Underpinnings of SFrame"
- "Deferred stack traces, how they work and the issues they have”, Tracing Summit 2025
- SFrame follow up at GNU Tools Cauldron 2025
- "s390: Stack tracing using Frame Pointer, Back Chain, and SFrame" at GNU Tools Cauldron 2025