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.

Specifications

Change History

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:

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

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 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:

Kernel space stack tracing to enable livepatching (ARM64)

This is work in progress.

Following bugs are known to affect relocatable links:

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 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 V3

Version 3 of the SFrame specification is currently under development.

Resources

None: sframe (last edited 2025-11-04 19:23:52 by InduBhagat)

All content (C) 2008 Free Software Foundation. For terms of use, redistribution, and modification, please see the WikiLicense page.