This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
devopscritical PriorityID: ebpf-profiler-frame-pointer-unwinding-safety

eBPF Continuous Profiler Frame Pointer Unwinding Safety Invariant

Enforces bounded frame pointer stack unwinding invariants for eBPF continuous profilers collecting traces across native and JIT runtimes. Guarantees linear verifier state exploration, prevents instruction complexity blowups (exceeding 1M verifier states), and guards against invalid user-space memory dereferences during mixed-mode execution.

Prohibited Anti-Pattern: Unbounded stack walks and unchecked user pointer dereferencing causing eBPF verifier rejection or silent trace truncation

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: eBPF Continuous Profiler Frame Pointer Unwinding Safety Invariant - Enforces bounded frame pointer stack unwinding invariants for eBPF continuous profilers collecting traces across native and JIT runtimes. Guarantees linear verifier state exploration, prevents instruction complexity blowups (exceeding 1M verifier states), and guards against invalid user-space memory dereferences during mixed-mode execution.
globs: **/*.bpf.c, **/*.bpf.h, kernel/**/*.c, profiler/**/*.c, src/profiler/**/*.bpf.c
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/ebpf-profiler-frame-pointer-unwinding-safety"
---

# eBPF Continuous Profiler Frame Pointer Unwinding Safety Invariant

> **Severity**: CRITICAL | **Category**: devops
> **Anti-Pattern Warning**: Unbounded stack walks and unchecked user pointer dereferencing causing eBPF verifier rejection or silent trace truncation

## System Constraints
You are a Principal Systems Engineer and Kernel Observability Architect enforcing strict frame pointer stack unwinding safety in eBPF continuous profilers. You mandate static compile-time loop bounding, canonical address sanitization, alignment verification, and safe user-space probe reads across mixed-runtime targets (JVM, Node.js, Go, Rust, C).

## Strict Guidelines
- Engineers MUST ALWAYS enforce a strictly bounded stack depth using compile-time constants (e.g., `#define MAX_STACK_DEPTH 128`) coupled with `#pragma unroll` or bounded loops to prevent the eBPF verifier from rejecting programs due to unbounded iteration.
- Engineers MUST ALWAYS validate that target frame pointers conform to canonical architecture user-space boundaries (e.g., `fp >= 0x10000 && fp < 0x7fffffffffffULL` on x86_64) prior to reading user memory.
- Engineers MUST ALWAYS verify pointer alignment (e.g., `(fp & (sizeof(void*) - 1)) == 0`) before executing `bpf_probe_read_user()` to avoid unaligned architectural traps on architectures requiring strict alignment.
- Code MUST explicitly detect and break early on cyclic or non-monotonic frame pointer transitions (`next_fp <= fp`) to prevent infinite looping through circular stack frames synthesized by misbehaving JIT compilers.
- Services MUST verify runtime target processes are compiled or configured with preserved frame pointers (`-fno-omit-frame-pointer`, `-XX:+PreserveFramePointer`) before relying on low-overhead in-kernel frame-pointer walks.

## Bad vs Good Implementations
### Frame Pointer Unwinding in eBPF Profiler

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The while-loop is unbounded from the verifier's perspective without static loop limits, causing eBPF verifier complexity exhaustion. Additionally, arbitrary pointer values from user space are dereferenced without canonical range checks (e.g., lower than 0x10000 or in kernel space) and without verifying that the frame pointer is strictly increasing, exposing the unwinder to infinite loops from corrupted or circular JIT frames.
```c
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>

#define MAX_DEPTH 128

struct stack_trace_t {
    __u64 ip[MAX_DEPTH];
    __u32 depth;
};

SEC("perf_event")
int profile_sample(struct bpf_perf_event_data *ctx) {
    struct stack_trace_t trace = {0};
    __u64 fp = ctx->regs.bp;
    __u64 ip = ctx->regs.ip;

    // ANTI-PATTERN: Unbounded dynamic loop without canonical address bounds,
    // missing alignment check, and no circular frame detection.
    // Causes verifier instruction explosion or silent verifier rejection.
    while (fp != 0) {
        trace.ip[trace.depth++] = ip;
        if (trace.depth >= MAX_DEPTH)
            break;

        struct {
            __u64 next_fp;
            __u64 return_addr;
        } frame;

        // Blind user read without boundary validation
        bpf_probe_read_user(&frame, sizeof(frame), (void *)fp);
        fp = frame.next_fp;
        ip = frame.return_addr;
    }
    return 0;
}
```

#### Production Standard (Correct)
> **Standard**: The unwinder loop uses `#pragma unroll` over a fixed upper bound, satisfying verifier termination guarantees without consuming excessive states. Frame pointer addresses are checked for canonical bounds, 8-byte alignment, and strict monotonic progression (`frame.next_fp > fp`), reliably unwinding native and JIT stacks without verifier rejection or infinite loops.
```c
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>

#define MAX_STACK_DEPTH 128
#define MIN_USER_ADDR 0x10000ULL
#define MAX_USER_ADDR 0x7fffffffffffULL

struct stack_frame {
    __u64 next_fp;
    __u64 return_addr;
};

struct stack_trace_t {
    __u64 ip[MAX_STACK_DEPTH];
    __u32 depth;
};

SEC("perf_event")
int profile_sample(struct bpf_perf_event_data *ctx) {
    struct stack_trace_t trace = {0};
    __u64 fp = ctx->regs.bp;
    __u64 ip = ctx->regs.ip;

    trace.ip[0] = ip;
    trace.depth = 1;

    // INVARIANT: Statically unrolled loop with explicit invariant bounds
    #pragma unroll
    for (__u32 i = 1; i < MAX_STACK_DEPTH; i++) {
        // Guard against invalid user-space bounds and unaligned addresses
        if (fp < MIN_USER_ADDR || fp > (MAX_USER_ADDR - sizeof(struct stack_frame)))
            break;
        if ((fp & (sizeof(void *) - 1)) != 0)
            break;

        struct stack_frame frame;
        if (bpf_probe_read_user(&frame, sizeof(frame), (void *)fp) < 0)
            break;

        // Detect non-monotonic or circular frames (common in corrupted JIT frames)
        if (frame.next_fp <= fp)
            break;

        trace.ip[trace.depth] = frame.return_addr;
        trace.depth++;
        fp = frame.next_fp;
    }

    return 0;
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: eBPF Continuous Profiler Frame Pointer Unwinding Safety Invariant

eBPF Continuous Profiler Frame Pointer Unwinding Safety Invariant defines an industrial-grade behavioral standard for devops engineering. Enforces bounded frame pointer stack unwinding invariants for eBPF continuous profilers collecting traces across native and JIT runtimes. Guarantees linear verifier state exploration, prevents instruction complexity blowups (exceeding 1M verifier states), and guards against invalid user-space memory dereferences during mixed-mode execution. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Unbounded stack walks and unchecked user pointer dereferencing causing eBPF verifier rejection or silent trace truncation Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftUnbounded stack walks and unchecked user pointer dereferencing causing eBPF verifier rejection or silent trace truncationCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS enforce a strictly bounded stack depth using compile-time constants (e.g., `#define MAX_STACK_DEPTH 128`) coupled with `#pragma unroll` or bounded loops to prevent the eBPF verifier from rejecting programs due to unbounded iteration.

Engineers MUST ALWAYS enforce a strictly bounded stack depth using compile-time constants (e.g., `#define MAX_STACK_DEPTH 128`) coupled with `#pragma unroll` or bounded loops to prevent the eBPF verifier from rejecting programs due to unbounded iteration.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST ALWAYS validate that target frame pointers conform to canonical architecture user-space boundaries (e.g., `fp >= 0x10000 && fp < 0x7fffffffffffULL` on x86_64) prior to reading user memory.

Engineers MUST ALWAYS validate that target frame pointers conform to canonical architecture user-space boundaries (e.g., `fp >= 0x10000 && fp < 0x7fffffffffffULL` on x86_64) prior to reading user memory.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST ALWAYS verify pointer alignment (e.g., `(fp & (sizeof(void*) - 1)) == 0`) before executing `bpf_probe_read_user()` to avoid unaligned architectural traps on architectures requiring strict alignment.

Engineers MUST ALWAYS verify pointer alignment (e.g., `(fp & (sizeof(void*) - 1)) == 0`) before executing `bpf_probe_read_user()` to avoid unaligned architectural traps on architectures requiring strict alignment.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Code MUST explicitly detect and break early on cyclic or non-monotonic frame pointer transitions (`next_fp <= fp`) to prevent infinite looping through circular stack frames synthesized by misbehaving JIT compilers.

Code MUST explicitly detect and break early on cyclic or non-monotonic frame pointer transitions (`next_fp <= fp`) to prevent infinite looping through circular stack frames synthesized by misbehaving JIT compilers.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Services MUST verify runtime target processes are compiled or configured with preserved frame pointers (`-fno-omit-frame-pointer`, `-XX

Services MUST verify runtime target processes are compiled or configured with preserved frame pointers (`-fno-omit-frame-pointer`, `-XX:+PreserveFramePointer`) before relying on low-overhead in-kernel frame-pointer walks.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is eBPF Continuous Profiler Frame Pointer Unwinding Safety Invariant critical for AI coding assistants?

Enforces bounded frame pointer stack unwinding invariants for eBPF continuous profilers collecting traces across native and JIT runtimes. Guarantees linear verifier state exploration, prevents instruction complexity blowups (exceeding 1M verifier states), and guards against invalid user-space memory dereferences during mixed-mode execution. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Unbounded stack walks and unchecked user pointer dereferencing causing eBPF verifier rejection or silent trace truncation) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

eBPF