# Understanding the Base Attach Implementation Interface in bpftime

> Discover the base attach implementation interface in bpftime defined in base_attach_impl.hpp. Learn how abstract classes ensure consistent attach type inheritance for better BPF program management.

- Repository: [eunomia-bpf/bpftime](https://github.com/eunomia-bpf/bpftime)
- Tags: internals
- Published: 2026-03-01

---

**The base attach implementation interface in bpftime is defined in [`attach/base_attach_impl/base_attach_impl.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/attach/base_attach_impl/base_attach_impl.hpp), which declares the abstract class `bpftime::attach::base_attach_impl` that all specific attach types must inherit from.**

The **bpftime** project provides a userspace eBPF runtime that requires a pluggable mechanism for attaching eBPF programs to various execution points. The base attach implementation interface serves as the foundational contract that enables different attach mechanisms—such as uprobes, syscall interceptors, or GPU hooks—to integrate seamlessly with the runtime.

## Location of the Base Attach Interface

The core interface declaration resides in **[`attach/base_attach_impl/base_attach_impl.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/attach/base_attach_impl/base_attach_impl.hpp)**. This header file defines the `bpftime::attach::base_attach_impl` abstract class within the `bpftime::attach` namespace. The file is part of the `base_attach_impl` module, which also includes [`attach_private_data.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/attach_private_data.hpp) for per-attach private data structures and the corresponding [`CMakeLists.txt`](https://github.com/eunomia-bpf/bpftime/blob/main/CMakeLists.txt) for build configuration.

## Core Methods of the Base Attach Implementation Interface

The `base_attach_impl` class defines several pure virtual methods that concrete implementations must override, along with utility methods for ID management and optional helper registration.

### Detaching Attach Points

The **`detach_by_id`** method provides the mechanism to remove an active attach entry:

```cpp
virtual int detach_by_id(int id) = 0;

```

Concrete implementations must override this to clean up resources associated with the specified local attach ID. For example, a uprobe implementation would remove the breakpoint or trampoline installed at the target address.

### Creating Attachments with eBPF Callbacks

The **`create_attach_with_ebpf_callback`** method is the primary interface for establishing new attach points:

```cpp
virtual int create_attach_with_ebpf_callback(
    ebpf_run_callback &&cb,
    const attach_private_data &private_data,
    int attach_type) = 0;

```

This method accepts an eBPF run callback, private data specific to the attach type, and an attach type identifier. The concrete implementation prepares the execution context—such as setting up argument marshaling for uprobes or configuring syscall interception—and returns a local attach ID.

### Helper Registration and Custom Functions

The interface includes optional extension points for attach-specific functionality:

**`register_custom_helpers`** allows attach types to expose additional eBPF helper functions:

```cpp
virtual void register_custom_helpers(
    ebpf_helper_register_callback register_callback) {}

```

**`call_attach_specific_function`** provides a generic mechanism for invoking implementation-specific operations:

```cpp
virtual void *call_attach_specific_function(
    const std::string &name, void *data) {
    SPDLOG_WARN("Not implemented yet: call_attach_specific_function");
    return nullptr;
}

```

The class also provides **`allocate_id`** for generating unique attach entry identifiers, incrementing an internal `next_id` counter starting from 1.

## Implementing a Custom Attach Type

To create a new attach mechanism, inherit from `base_attach_impl` and override the required virtual methods. Below is a minimal example demonstrating the implementation pattern:

```cpp
#include "bpftime/attach/base_attach_impl/base_attach_impl.hpp"
#include "bpftime/attach/base_attach_impl/attach_private_data.hpp"

class my_dummy_attach : public bpftime::attach::base_attach_impl {
public:
    int detach_by_id(int id) override {
        spdlog::info("Detaching dummy attach id {}", id);
        return 0;
    }

    int create_attach_with_ebpf_callback(
        ebpf_run_callback &&cb,
        const attach_private_data &private_data,
        int /*attach_type*/) override
    {
        stored_cb = std::move(cb);
        spdlog::info("Dummy attach created, id {}", allocate_id());
        return 0;
    }

    void register_custom_helpers(
        ebpf_helper_register_callback register_callback) override
    {
        register_callback(1000, "my_const_helper", 
            [](unsigned, const char*, void*) { return 42; });
    }

private:
    ebpf_run_callback stored_cb;
};

```

The runtime interacts with concrete implementations through the base interface pointer, allowing the attach manager to operate polymorphically across different attach types without knowing their specific implementation details.

## Summary

- The **base attach implementation interface in bpftime** is defined in [`attach/base_attach_impl/base_attach_impl.hpp`](https://github.com/eunomia-bpf/bpftime/blob/main/attach/base_attach_impl/base_attach_impl.hpp) as the abstract class `bpftime::attach::base_attach_impl`.
- Concrete attach types (uprobe, syscall, GPU) must inherit from this class and implement `detach_by_id` and `create_attach_with_ebpf_callback`.
- The interface supports optional extension through `register_custom_helpers` and `call_attach_specific_function`.
- ID management is handled automatically via `allocate_id`, with implementations responsible for resource cleanup in `detach_by_id`.

## Frequently Asked Questions

### What is the purpose of the base_attach_impl class in bpftime?

The `base_attach_impl` class serves as the abstract foundation for all attach implementations in the bpftime userspace eBPF runtime. It defines the mandatory interface that specific attach mechanisms—such as uprobes, syscall interceptors, or GPU hooks—must implement to integrate with the runtime's attach manager. This abstraction enables polymorphic management of different attach types through a unified API.

### Which methods must be overridden when implementing a custom attach type?

Developers must override two pure virtual methods: `detach_by_id(int id)` to handle cleanup of attach resources when an entry is removed, and `create_attach_with_ebpf_callback` to establish the attach point and register the eBPF program callback. Additionally, implementations may override `register_custom_helpers` to expose attach-specific eBPF helpers, or `call_attach_specific_function` to support implementation-specific control operations.

### How does bpftime manage unique identifiers for attach entries?

The `base_attach_impl` class provides the `allocate_id()` method, which automatically generates sequential unique identifiers starting from 1 using an internal `next_id` counter. Concrete implementations call this method when creating new attach entries to obtain a local attach ID, which is later used to reference the entry during detachment operations via `detach_by_id`. This centralized ID management ensures consistency across different attach implementations within the runtime.