/******************************************************************************
 * Remote Debugging Module - Main Module Implementation
 *
 * This file contains the main module initialization, the RemoteUnwinder
 * class implementation, and utility functions.
 ******************************************************************************/

#include "_remote_debugging.h"
#include "binary_io.h"
#include "debug_offsets_validation.h"
#include "gc_stats.h"

/* Forward declarations for clinic-generated code */
typedef struct {
    PyObject_HEAD
    BinaryWriter *writer;
    uint64_t cached_total_samples;  /* Preserved after finalize */
} BinaryWriterObject;

typedef struct {
    PyObject_HEAD
    BinaryReader *reader;
} BinaryReaderObject;

#include "clinic/module.c.h"

/* ============================================================================
 * STRUCTSEQ TYPE DEFINITIONS
 * ============================================================================ */

// TaskInfo structseq type
static PyStructSequence_Field TaskInfo_fields[] = {
    {"task_id", "Task ID (memory address)"},
    {"task_name", "Task name"},
    {"coroutine_stack", "Coroutine call stack"},
    {"awaited_by", "Tasks awaiting this task"},
    {NULL}
};

PyStructSequence_Desc TaskInfo_desc = {
    "_remote_debugging.TaskInfo",
    "Information about an asyncio task",
    TaskInfo_fields,
    4
};

// LocationInfo structseq type
static PyStructSequence_Field LocationInfo_fields[] = {
    {"lineno", "Line number"},
    {"end_lineno", "End line number"},
    {"col_offset", "Column offset"},
    {"end_col_offset", "End column offset"},
    {NULL}
};

PyStructSequence_Desc LocationInfo_desc = {
    "_remote_debugging.LocationInfo",
    "Source location information: (lineno, end_lineno, col_offset, end_col_offset)",
    LocationInfo_fields,
    4
};

// FrameInfo structseq type
static PyStructSequence_Field FrameInfo_fields[] = {
    {"filename", "Source code filename"},
    {"location", "LocationInfo structseq or None for synthetic frames"},
    {"funcname", "Function name"},
    {"opcode", "Opcode being executed (None if not gathered)"},
    {NULL}
};

PyStructSequence_Desc FrameInfo_desc = {
    "_remote_debugging.FrameInfo",
    "Information about a frame",
    FrameInfo_fields,
    4
};

// CoroInfo structseq type
static PyStructSequence_Field CoroInfo_fields[] = {
    {"call_stack", "Coroutine call stack"},
    {"task_name", "Task name"},
    {NULL}
};

PyStructSequence_Desc CoroInfo_desc = {
    "_remote_debugging.CoroInfo",
    "Information about a coroutine",
    CoroInfo_fields,
    2
};

// ThreadInfo structseq type
static PyStructSequence_Field ThreadInfo_fields[] = {
    {"thread_id", "Thread ID"},
    {"status", "Thread status (flags: HAS_GIL, ON_CPU, UNKNOWN or legacy enum)"},
    {"frame_info", "Frame information"},
    {NULL}
};

PyStructSequence_Desc ThreadInfo_desc = {
    "_remote_debugging.ThreadInfo",
    "Information about a thread",
    ThreadInfo_fields,
    3
};

// InterpreterInfo structseq type
static PyStructSequence_Field InterpreterInfo_fields[] = {
    {"interpreter_id", "Interpreter ID"},
    {"threads", "List of threads in this interpreter"},
    {NULL}
};

PyStructSequence_Desc InterpreterInfo_desc = {
    "_remote_debugging.InterpreterInfo",
    "Information about an interpreter",
    InterpreterInfo_fields,
    2
};

// AwaitedInfo structseq type
static PyStructSequence_Field AwaitedInfo_fields[] = {
    {"thread_id", "Thread ID"},
    {"awaited_by", "List of tasks awaited by this thread"},
    {NULL}
};

PyStructSequence_Desc AwaitedInfo_desc = {
    "_remote_debugging.AwaitedInfo",
    "Information about what a thread is awaiting",
    AwaitedInfo_fields,
    2
};

// GCStatsInfo structseq type
static PyStructSequence_Field GCStatsInfo_fields[] = {
    {"gen", "GC generation number"},
    {"iid", "Interpreter ID"},
    {"ts_start", "Raw timestamp at collection start"},
    {"ts_stop", "Raw timestamp at collection stop"},
    {"collections", "Total number of collections"},
    {"collected", "Total number of collected objects"},
    {"uncollectable", "Total number of uncollectable objects"},
    {"candidates", "Total objects considered and traversed"},
    {"heap_size", "Number of live objects"},
    {"duration", "Total collection time, in seconds"},
    {NULL}
};

PyStructSequence_Desc GCStatsInfo_desc = {
    "_remote_debugging.GCStatsInfo",
    "Information about a garbage collector stats sample",
    GCStatsInfo_fields,
    10
};

/* ============================================================================
 * UTILITY FUNCTIONS
 * ============================================================================ */

void
cached_code_metadata_destroy(void *ptr)
{
    CachedCodeMetadata *meta = (CachedCodeMetadata *)ptr;
    Py_DECREF(meta->func_name);
    Py_DECREF(meta->file_name);
    Py_DECREF(meta->linetable);
    Py_XDECREF(meta->last_frame_info);
    PyMem_RawFree(meta);
}

RemoteDebuggingState *
RemoteDebugging_GetState(PyObject *module)
{
    void *state = _PyModule_GetState(module);
    assert(state != NULL);
    return (RemoteDebuggingState *)state;
}

RemoteDebuggingState *
RemoteDebugging_GetStateFromType(PyTypeObject *type)
{
    PyObject *module = PyType_GetModule(type);
    assert(module != NULL);
    return RemoteDebugging_GetState(module);
}

RemoteDebuggingState *
RemoteDebugging_GetStateFromObject(PyObject *obj)
{
    RemoteUnwinderObject *unwinder = (RemoteUnwinderObject *)obj;
    if (unwinder->cached_state == NULL) {
        unwinder->cached_state = RemoteDebugging_GetStateFromType(Py_TYPE(obj));
    }
    return unwinder->cached_state;
}

int
RemoteDebugging_InitState(RemoteDebuggingState *st)
{
    return 0;
}

int
is_prerelease_version(uint64_t version)
{
    return (version & 0xF0) != 0xF0;
}

int
validate_debug_offsets(struct _Py_DebugOffsets *debug_offsets)
{
    if (memcmp(debug_offsets->cookie, _Py_Debug_Cookie, sizeof(debug_offsets->cookie)) != 0) {
        // The remote is probably running a Python version predating debug offsets.
        PyErr_SetString(
            PyExc_RuntimeError,
            "Can't determine the Python version of the remote process");
        return -1;
    }

    // Assume debug offsets could change from one pre-release version to another,
    // or one minor version to another, but are stable across patch versions.
    if (is_prerelease_version(Py_Version) && Py_Version != debug_offsets->version) {
        PyErr_SetString(
            PyExc_RuntimeError,
            "Can't attach from a pre-release Python interpreter"
            " to a process running a different Python version");
        return -1;
    }

    if (is_prerelease_version(debug_offsets->version) && Py_Version != debug_offsets->version) {
        PyErr_SetString(
            PyExc_RuntimeError,
            "Can't attach to a pre-release Python interpreter"
            " from a process running a different Python version");
        return -1;
    }

    unsigned int remote_major = (debug_offsets->version >> 24) & 0xFF;
    unsigned int remote_minor = (debug_offsets->version >> 16) & 0xFF;

    if (PY_MAJOR_VERSION != remote_major || PY_MINOR_VERSION != remote_minor) {
        PyErr_Format(
            PyExc_RuntimeError,
            "Can't attach from a Python %d.%d process to a Python %d.%d process",
            PY_MAJOR_VERSION, PY_MINOR_VERSION, remote_major, remote_minor);
        return -1;
    }

    // The debug offsets differ between free threaded and non-free threaded builds.
    if (_Py_Debug_Free_Threaded && !debug_offsets->free_threaded) {
        PyErr_SetString(
            PyExc_RuntimeError,
            "Cannot attach from a free-threaded Python process"
            " to a process running a non-free-threaded version");
        return -1;
    }

    if (!_Py_Debug_Free_Threaded && debug_offsets->free_threaded) {
        PyErr_SetString(
            PyExc_RuntimeError,
            "Cannot attach to a free-threaded Python process"
            " from a process running a non-free-threaded version");
        return -1;
    }

    return _PyRemoteDebug_ValidateDebugOffsetsLayout(debug_offsets);
}

/* ============================================================================
 * REMOTEUNWINDER CLASS IMPLEMENTATION
 * ============================================================================ */

/*[clinic input]
module _remote_debugging
class _remote_debugging.RemoteUnwinder "RemoteUnwinderObject *" "&RemoteUnwinder_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=12b4dce200381115]*/

/*[clinic input]
@permit_long_summary
_remote_debugging.RemoteUnwinder.__init__
    pid: pid_t
    *
    all_threads: bool = False
    only_active_thread: bool = False
    mode: int = 0
    debug: bool = False
    skip_non_matching_threads: bool = True
    native: bool = False
    gc: bool = False
    opcodes: bool = False
    cache_frames: bool = False
    stats: bool = False

Initialize a new RemoteUnwinder object for debugging a remote Python process.

Args:
    pid: Process ID of the target Python process to debug
    all_threads: If True, initialize state for all threads in the
        process.  If False, only initialize for the main thread.
    only_active_thread: If True, only sample the thread holding the GIL.
    mode: Profiling mode: 0=WALL (wall-time), 1=CPU (cpu-time), 2=GIL
        (gil-time).  Cannot be used together with all_threads=True.
    debug: If True, chain exceptions to explain the sequence of events
        that lead to the exception.
    skip_non_matching_threads: If True, skip threads that don't match
        the selected mode.  If False, include all threads regardless of
        mode.
    native: If True, include artificial "<native>" frames to denote
        calls to non-Python code.
    gc: If True, include artificial "<GC>" frames to denote active
        garbage collection.
    opcodes: If True, gather bytecode opcode information for
        instruction-level profiling.
    cache_frames: If True, enable frame caching optimization to avoid
        re-reading unchanged parent frames between samples.
    stats: If True, collect statistics about cache hits, memory reads,
        etc.  Use get_stats() to retrieve the collected statistics.

The RemoteUnwinder provides functionality to inspect and debug a running
Python process, including examining thread states, stack frames and
other runtime data.

Raises:
    PermissionError: If access to the target process is denied
    OSError: If unable to attach to the target process or access its
        memory
    RuntimeError: If unable to read debug information from the target
        process
    ValueError: If both all_threads and only_active_thread are True
[clinic start generated code]*/

static int
_remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self,
                                               pid_t pid, int all_threads,
                                               int only_active_thread,
                                               int mode, int debug,
                                               int skip_non_matching_threads,
                                               int native, int gc,
                                               int opcodes, int cache_frames,
                                               int stats)
/*[clinic end generated code: output=acfe554c8a92cf6b input=3b5a5ad153709125]*/
{
    // Validate that all_threads and only_active_thread are not both True
    if (all_threads && only_active_thread) {
        PyErr_SetString(PyExc_ValueError,
                       "all_threads and only_active_thread cannot both be True");
        return -1;
    }

#ifdef Py_GIL_DISABLED
    if (only_active_thread) {
        PyErr_SetString(PyExc_ValueError,
                       "only_active_thread is not supported in free-threaded builds");
        return -1;
    }
#endif

    self->native = native;
    self->gc = gc;
    self->opcodes = opcodes;
    self->cache_frames = cache_frames;
    self->collect_stats = stats;
    self->stale_invalidation_counter = 0;
    self->cached_tstate_interpreter_addr = 0;
    self->cached_tstate_addr = 0;
    memset(self->cached_tstates, 0, sizeof(self->cached_tstates));
    memset(self->cached_generations, 0, sizeof(self->cached_generations));
    self->debug = debug;
    self->only_active_thread = only_active_thread;
    self->mode = mode;
    self->skip_non_matching_threads = skip_non_matching_threads;
    self->cached_state = NULL;
    self->frame_cache = NULL;
#ifdef Py_REMOTE_DEBUG_SUPPORTS_BLOCKING
    self->threads_stopped = 0;
#endif
    // Initialize stats to zero
    memset(&self->stats, 0, sizeof(self->stats));
    if (_Py_RemoteDebug_InitProcHandle(&self->handle, pid) < 0) {
        set_exception_cause(self, PyExc_RuntimeError, "Failed to initialize process handle");
        return -1;
    }

    self->runtime_start_address = _Py_RemoteDebug_GetPyRuntimeAddress(&self->handle);
    if (self->runtime_start_address == 0) {
        set_exception_cause(self, PyExc_RuntimeError, "Failed to get Python runtime address");
        return -1;
    }

    if (_Py_RemoteDebug_ReadDebugOffsets(&self->handle,
                                         &self->runtime_start_address,
                                         &self->debug_offsets) < 0)
    {
        set_exception_cause(self, PyExc_RuntimeError, "Failed to read debug offsets");
        return -1;
    }

    // Validate that the debug offsets are valid
    if (validate_debug_offsets(&self->debug_offsets) == -1) {
        set_exception_cause(self, PyExc_RuntimeError, "Invalid debug offsets found");
        return -1;
    }

    // Try to read async debug offsets, but don't fail if they're not available
    self->async_debug_offsets_available = 1;
    int async_debug_result = read_async_debug(self);
    if (async_debug_result == PY_REMOTE_DEBUG_INVALID_ASYNC_DEBUG_OFFSETS) {
        return -1;
    }
    if (async_debug_result < 0) {
        if (_Py_RemoteDebug_HasPermissionError()) {
            return -1;
        }
        PyErr_Clear();
        memset(&self->async_debug_offsets, 0, sizeof(self->async_debug_offsets));
        self->async_debug_offsets_available = 0;
    }

    if (populate_initial_state_data(all_threads, self, self->runtime_start_address,
                    &self->interpreter_addr ,&self->tstate_addr) < 0)
    {
        set_exception_cause(self, PyExc_RuntimeError, "Failed to populate initial state data");
        return -1;
    }

    self->code_object_cache = _Py_hashtable_new_full(
        _Py_hashtable_hash_ptr,
        _Py_hashtable_compare_direct,
        NULL,  // keys are stable pointers, don't destroy
        cached_code_metadata_destroy,
        NULL
    );
    if (self->code_object_cache == NULL) {
        PyErr_NoMemory();
        set_exception_cause(self, PyExc_MemoryError, "Failed to create code object cache");
        return -1;
    }

#ifdef Py_GIL_DISABLED
    // Initialize TLBC cache
    self->tlbc_generation = 0;
    self->tlbc_cache = _Py_hashtable_new_full(
        _Py_hashtable_hash_ptr,
        _Py_hashtable_compare_direct,
        NULL,  // keys are stable pointers, don't destroy
        tlbc_cache_entry_destroy,
        NULL
    );
    if (self->tlbc_cache == NULL) {
        PyErr_NoMemory();
        set_exception_cause(self, PyExc_MemoryError, "Failed to create TLBC cache");
        return -1;
    }
#endif

#if defined(__APPLE__)
    self->thread_id_offset = 0;
    self->thread_id_offset_initialized = 0;
#endif

#ifdef MS_WINDOWS
    self->win_process_buffer = NULL;
    self->win_process_buffer_size = 0;
#endif
#ifdef __linux__
    self->thread_tids = NULL;
    self->thread_tids_capacity = 0;
#endif

    if (cache_frames && frame_cache_init(self) < 0) {
        return -1;
    }

    // Clear stale profiler anchors from previous profilers. This prevents us
    // from stopping frame walking early due to stale frame pointers.
    if (cache_frames) {
        clear_last_profiled_frames(self);
    }

    return 0;
}

static inline size_t
interpreter_thread_cache_index(uintptr_t interpreter_addr)
{
    // Direct-mapped table indexed by the remote interpreter address. Each entry
    // stores the full address and verifies it on lookup, so hash collisions
    // degrade to misses and cannot return a value from the wrong interpreter.
    return (size_t)_Py_HashPointerRaw((const void *)interpreter_addr)
        & (INTERPRETER_THREAD_CACHE_SIZE - 1);
}

static inline uintptr_t
get_cached_tstate_for_interpreter(
    RemoteUnwinderObject *self,
    uintptr_t interpreter_addr)
{
    if (interpreter_addr == 0) {
        return 0;
    }

    if (self->cached_tstate_interpreter_addr == interpreter_addr) {
        return self->cached_tstate_addr;
    }

    InterpreterTstateCacheEntry *entry =
        &self->cached_tstates[interpreter_thread_cache_index(interpreter_addr)];
    if (entry->interpreter_addr == interpreter_addr) {
        self->cached_tstate_interpreter_addr = interpreter_addr;
        self->cached_tstate_addr = entry->thread_state_addr;
        return entry->thread_state_addr;
    }
    return 0;
}

static inline void
set_cached_tstate_for_interpreter(
    RemoteUnwinderObject *self,
    uintptr_t interpreter_addr,
    uintptr_t thread_state_addr)
{
    if (interpreter_addr == 0 || thread_state_addr == 0) {
        return;
    }

    self->cached_tstate_interpreter_addr = interpreter_addr;
    self->cached_tstate_addr = thread_state_addr;

    InterpreterTstateCacheEntry *entry =
        &self->cached_tstates[interpreter_thread_cache_index(interpreter_addr)];
    entry->interpreter_addr = interpreter_addr;
    entry->thread_state_addr = thread_state_addr;
}

static void
refresh_generation_caches_from_interp_state(
    RemoteUnwinderObject *self,
    uintptr_t interpreter_addr,
    const char *interp_state_buffer)
{
    uint64_t code_object_generation = GET_MEMBER(uint64_t, interp_state_buffer,
            self->debug_offsets.interpreter_state.code_object_generation);

    if (self->cached_generation_interpreter_addr == interpreter_addr) {
        if (code_object_generation != self->cached_code_object_generation) {
            self->cached_code_object_generation = code_object_generation;
            _Py_hashtable_clear(self->code_object_cache);
        }
    }
    else {
        InterpreterGenerationCacheEntry *entry =
            &self->cached_generations[interpreter_thread_cache_index(interpreter_addr)];
        // A slot rebound from another interpreter must be treated as changed:
        // the code_object_cache is global, so even if the new generation
        // numerically matches what the previous occupant had, stale entries
        // from that occupant could still be served.
        int changed = entry->interpreter_addr != interpreter_addr
                   || entry->code_object_generation != code_object_generation;
        entry->interpreter_addr = interpreter_addr;
        entry->code_object_generation = code_object_generation;
        if (changed) {
            _Py_hashtable_clear(self->code_object_cache);
        }
        self->cached_generation_interpreter_addr = interpreter_addr;
        self->cached_code_object_generation = code_object_generation;
    }

#ifdef Py_GIL_DISABLED
    uint32_t current_tlbc_generation = GET_MEMBER(uint32_t, interp_state_buffer,
                                                  self->debug_offsets.interpreter_state.tlbc_generation);
    if (current_tlbc_generation != self->tlbc_generation) {
        self->tlbc_generation = current_tlbc_generation;
        _Py_hashtable_clear(self->tlbc_cache);
    }
#endif
}

static int
refresh_generation_caches_for_interpreter(
    RemoteUnwinderObject *self,
    uintptr_t interpreter_addr)
{
    char interp_state_buffer[INTERP_STATE_BUFFER_SIZE];
    if (_Py_RemoteDebug_ReadRemoteMemory(
            &self->handle,
            interpreter_addr,
            INTERP_STATE_BUFFER_SIZE,
            interp_state_buffer) < 0) {
        set_exception_cause(self, PyExc_RuntimeError,
                            "Failed to read interpreter state buffer");
        return -1;
    }
    refresh_generation_caches_from_interp_state(self, interpreter_addr, interp_state_buffer);
    return 0;
}

static int
read_interp_state_and_maybe_thread_frame(
    RemoteUnwinderObject *unwinder,
    uintptr_t interpreter_addr,
    char *interp_state_buffer,
    char *tstate_buffer,
    char *frame_buffer,
    RemoteReadPrefetch *prefetch)
{
    prefetch->tstate = NULL;
    prefetch->frame = NULL;
    if (prefetch->tstate_addr != 0) {
        size_t tstate_size = (size_t)unwinder->debug_offsets.thread_state.size;
        _Py_RemoteReadSegment segments[3] = {
            {interpreter_addr, interp_state_buffer, INTERP_STATE_BUFFER_SIZE},
            {prefetch->tstate_addr, tstate_buffer, tstate_size},
            {prefetch->frame_addr, frame_buffer, SIZEOF_INTERP_FRAME},
        };
        int nsegs = prefetch->frame_addr != 0 ? 3 : 2;
        Py_ssize_t nread = _Py_RemoteDebug_BatchedReadRemoteMemory(
            &unwinder->handle, segments, nsegs);
        int completed = 0;
        if (nread >= (Py_ssize_t)INTERP_STATE_BUFFER_SIZE) {
            completed = 1;
            Py_ssize_t with_tstate = (Py_ssize_t)INTERP_STATE_BUFFER_SIZE
                + (Py_ssize_t)tstate_size;
            if (nread >= with_tstate) {
                completed = 2;
            }
            if (nsegs == 3
                    && nread == with_tstate + (Py_ssize_t)SIZEOF_INTERP_FRAME) {
                completed = 3;
            }
        }
        STATS_BATCHED_READ(unwinder, nsegs, completed);
        if (completed >= 1) {
            if (completed >= 2) {
                prefetch->tstate = tstate_buffer;
            }
            if (completed >= 3) {
                prefetch->frame = frame_buffer;
            }
            return 0;
        }
    }
    return _Py_RemoteDebug_ReadRemoteMemory(
        &unwinder->handle,
        interpreter_addr,
        INTERP_STATE_BUFFER_SIZE,
        interp_state_buffer);
}

/*[clinic input]
@critical_section
_remote_debugging.RemoteUnwinder.get_stack_trace

Returns stack traces for all interpreters and threads in process.

Each element in the returned list is a tuple of (interpreter_id,
thread_list), where:
- interpreter_id is the interpreter identifier
- thread_list is a list of tuples (thread_id, frame_list) for
  threads in that interpreter
  - thread_id is the OS thread identifier
  - frame_list is a list of tuples (function_name, filename,
    line_number) representing the Python stack frames for that
    thread, ordered from most recent to oldest

The threads returned depend on the initialization parameters:
- If only_active_thread was True: returns only the thread holding
  the GIL across all interpreters
- If all_threads was True: returns all threads across all
  interpreters
- Otherwise: returns only the main thread of each interpreter

Example:
    [
        (0, [  # Main interpreter
            (1234, [
                ('process_data', 'worker.py', 127),
                ('run_worker', 'worker.py', 45),
                ('main', 'app.py', 23)
            ]),
            (1235, [
                ('handle_request', 'server.py', 89),
                ('serve_forever', 'server.py', 52)
            ])
        ]),
        (1, [  # Sub-interpreter
            (1236, [
                ('sub_worker', 'sub.py', 15)
            ])
        ])
    ]

Raises:
    RuntimeError: If there is an error copying memory from the
        target process
    OSError: If there is an error accessing the target process
    PermissionError: If access to the target process is denied
    UnicodeDecodeError: If there is an error decoding strings from
        the target process

[clinic start generated code]*/

static PyObject *
_remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self)
/*[clinic end generated code: output=666192b90c69d567 input=86a992b853f48aa9]*/
{
    STATS_INC(self, total_samples);

    PyObject* result = PyList_New(0);
    if (!result) {
        set_exception_cause(self, PyExc_MemoryError, "Failed to create stack trace result list");
        return NULL;
    }

    // Iterate over all interpreters
    uintptr_t current_interpreter = self->interpreter_addr;
    while (current_interpreter != 0) {
        // Read interpreter state to get the interpreter ID
        char interp_state_buffer[INTERP_STATE_BUFFER_SIZE];
        char prefetched_tstate[SIZEOF_THREAD_STATE];
        char prefetched_frame[SIZEOF_INTERP_FRAME];
        RemoteReadPrefetch prefetch = {0};
        if (self->cache_frames) {
            prefetch.tstate_addr = get_cached_tstate_for_interpreter(
                self, current_interpreter);
        }
        if (prefetch.tstate_addr != 0) {
            FrameCacheEntry *entry = frame_cache_find_by_tstate(self, prefetch.tstate_addr);
            if (entry && entry->num_addrs > 0) {
                prefetch.frame_addr = entry->addrs[0];
            }
        }

        if (read_interp_state_and_maybe_thread_frame(
                self,
                current_interpreter,
                interp_state_buffer,
                prefetched_tstate,
                prefetched_frame,
                &prefetch) < 0) {
            set_exception_cause(self, PyExc_RuntimeError, "Failed to read interpreter state buffer");
            Py_CLEAR(result);
            goto exit;
        }
        refresh_generation_caches_from_interp_state(self, current_interpreter, interp_state_buffer);

        uintptr_t gc_frame = 0;
        if (self->gc) {
            gc_frame = GET_MEMBER(uintptr_t, interp_state_buffer,
                                  self->debug_offsets.interpreter_state.gc
                                  + self->debug_offsets.gc.frame);
        }

        int64_t interpreter_id = GET_MEMBER(int64_t, interp_state_buffer,
                self->debug_offsets.interpreter_state.id);

        // Create a list to hold threads for this interpreter
        PyObject *interpreter_threads = PyList_New(0);
        if (!interpreter_threads) {
            set_exception_cause(self, PyExc_MemoryError, "Failed to create interpreter threads list");
            Py_CLEAR(result);
            goto exit;
        }

        // Get the GIL holder for this interpreter (needed for GIL_WAIT logic)
        uintptr_t gil_holder_tstate = 0;
        int gil_locked = GET_MEMBER(int, interp_state_buffer,
            self->debug_offsets.interpreter_state.gil_runtime_state_locked);
        if (gil_locked) {
            gil_holder_tstate = (uintptr_t)GET_MEMBER(PyThreadState*, interp_state_buffer,
                self->debug_offsets.interpreter_state.gil_runtime_state_holder);
        }

        uintptr_t current_tstate;
        if (self->only_active_thread) {
            // Find the GIL holder for THIS interpreter
            if (!gil_locked) {
                // This interpreter's GIL is not locked, skip it
                Py_DECREF(interpreter_threads);
                goto next_interpreter;
            }

            current_tstate = gil_holder_tstate;
        } else if (self->tstate_addr == 0) {
            // Get all threads for this interpreter
            current_tstate = GET_MEMBER(uintptr_t, interp_state_buffer,
                    self->debug_offsets.interpreter_state.threads_head);
        } else {
            // Target specific thread (only process first interpreter)
            current_tstate = self->tstate_addr;
        }
        if (current_tstate != 0 && self->cache_frames) {
            set_cached_tstate_for_interpreter(self, current_interpreter, current_tstate);
        }

        // Acquire main thread state information
        uintptr_t main_thread_tstate = GET_MEMBER(uintptr_t, interp_state_buffer,
                self->debug_offsets.interpreter_state.threads_main);

        while (current_tstate != 0) {
            uintptr_t prev_tstate = current_tstate;
            PyObject* frame_info = unwind_stack_for_thread(self, &current_tstate,
                                                           gil_holder_tstate,
                                                           gc_frame,
                                                           main_thread_tstate,
                                                           &prefetch);
            if (!frame_info) {
                // Check if this was an intentional skip due to mode-based filtering
                if ((self->mode == PROFILING_MODE_CPU || self->mode == PROFILING_MODE_GIL ||
                     self->mode == PROFILING_MODE_EXCEPTION) && !PyErr_Occurred()) {
                    // Detect cycle: if current_tstate didn't advance, we have corrupted data
                    if (current_tstate == prev_tstate) {
                        Py_DECREF(interpreter_threads);
                        PyErr_Format(PyExc_RuntimeError,
                            "Thread list cycle detected at address 0x%lx (corrupted remote memory)",
                            current_tstate);
                        set_exception_cause(self, PyExc_RuntimeError,
                            "Thread list cycle detected (corrupted remote memory)");
                        Py_CLEAR(result);
                        goto exit;
                    }
                    // Thread was skipped due to mode filtering, continue to next thread
                    continue;
                }
                // This was an actual error
                Py_DECREF(interpreter_threads);
                set_exception_cause(self, PyExc_RuntimeError, "Failed to unwind stack for thread");
                Py_CLEAR(result);
                goto exit;
            }

            if (PyList_Append(interpreter_threads, frame_info) == -1) {
                Py_DECREF(frame_info);
                Py_DECREF(interpreter_threads);
                set_exception_cause(self, PyExc_RuntimeError, "Failed to append thread frame info");
                Py_CLEAR(result);
                goto exit;
            }
            Py_DECREF(frame_info);

            // If targeting specific thread or only active thread, process just one
            if (self->tstate_addr || self->only_active_thread) {
                break;
            }
        }

        // Create the InterpreterInfo StructSequence
        RemoteDebuggingState *state = RemoteDebugging_GetStateFromObject((PyObject*)self);
        PyObject *interpreter_info = PyStructSequence_New(state->InterpreterInfo_Type);
        if (!interpreter_info) {
            Py_DECREF(interpreter_threads);
            set_exception_cause(self, PyExc_MemoryError, "Failed to create InterpreterInfo");
            Py_CLEAR(result);
            goto exit;
        }

        PyObject *interp_id = PyLong_FromLongLong(interpreter_id);
        if (!interp_id) {
            Py_DECREF(interpreter_threads);
            Py_DECREF(interpreter_info);
            set_exception_cause(self, PyExc_MemoryError, "Failed to create interpreter ID");
            Py_CLEAR(result);
            goto exit;
        }

        PyStructSequence_SetItem(interpreter_info, 0, interp_id);  // steals reference
        PyStructSequence_SetItem(interpreter_info, 1, interpreter_threads);  // steals reference

        // Add this interpreter to the result list
        if (PyList_Append(result, interpreter_info) == -1) {
            Py_DECREF(interpreter_info);
            set_exception_cause(self, PyExc_RuntimeError, "Failed to append interpreter info");
            Py_CLEAR(result);
            goto exit;
        }
        Py_DECREF(interpreter_info);

next_interpreter:

        // Get the next interpreter address
        current_interpreter = GET_MEMBER(uintptr_t, interp_state_buffer,
                self->debug_offsets.interpreter_state.next);

        // If we're targeting a specific thread, stop after first interpreter
        if (self->tstate_addr != 0) {
            break;
        }
    }

exit:
    // Invalidate cache entries for threads not seen in this sample.
    // Only do this every 1024 iterations to avoid performance overhead.
    if (self->cache_frames && result) {
        if (++self->stale_invalidation_counter >= 1024) {
            self->stale_invalidation_counter = 0;
            frame_cache_invalidate_stale(self, result);
        }
    }
    _Py_RemoteDebug_ClearCache(&self->handle);
    return result;
}

/*[clinic input]
@permit_long_docstring_body
@critical_section
_remote_debugging.RemoteUnwinder.get_all_awaited_by

Get awaited_by relationships for tasks in the remote process.

Returns:
    A list of AwaitedInfo objects, where each object contains:

    - thread_id (int): Identifier of the thread, or 0 for tasks in the
      interpreter's fallback task list.
    - awaited_by (list[TaskInfo]): Tasks registered with this thread.

Each TaskInfo contains:
    - task_id (int): Identifier of the task.
    - task_name (str): Name of the task.
    - coroutine_stack (list[CoroInfo]): Stack of coroutine frames.
    - awaited_by (list[CoroInfo]): Coroutine information for tasks or futures
      awaiting this task.

Each CoroInfo contains:
    - call_stack (list[FrameInfo]): Call stack frames for the coroutine.
    - task_name (int): Identifier of the task or future.

Raises:
    RuntimeError: If AsyncioDebug section is not available in the
        remote process
    MemoryError: If memory allocation fails
    OSError: If reading from the remote process fails

Example output:

    [
        AwaitedInfo(
            thread_id=12345,
            awaited_by=[
                TaskInfo(
                    task_id=1,
                    task_name="Task-1",
                    coroutine_stack=[...],
                    awaited_by=[]
                )
            ]
        )
    ]
[clinic start generated code]*/

static PyObject *
_remote_debugging_RemoteUnwinder_get_all_awaited_by_impl(RemoteUnwinderObject *self)
/*[clinic end generated code: output=6a49cd345e8aec53 input=79e556b3973d21a8]*/
{
    if (ensure_async_debug_offsets(self) < 0) {
        return NULL;
    }
    if (refresh_generation_caches_for_interpreter(self, self->interpreter_addr) < 0) {
        return NULL;
    }

    PyObject *result = PyList_New(0);
    if (result == NULL) {
        set_exception_cause(self, PyExc_MemoryError, "Failed to create awaited_by result list");
        goto result_err;
    }

    // Process all threads
    if (iterate_threads(self, process_thread_for_awaited_by, result) < 0) {
        goto result_err;
    }

    uintptr_t head_addr = self->interpreter_addr
        + (uintptr_t)self->async_debug_offsets.asyncio_interpreter_state.asyncio_tasks_head;

    // On top of a per-thread task lists used by default by asyncio to avoid
    // contention, there is also a fallback per-interpreter list of tasks;
    // any tasks still pending when a thread is destroyed will be moved to the
    // per-interpreter task list.  It's unlikely we'll find anything here, but
    // interesting for debugging.
    if (append_awaited_by(self, 0, head_addr, result))
    {
        set_exception_cause(self, PyExc_RuntimeError, "Failed to append interpreter awaited_by in get_all_awaited_by");
        goto result_err;
    }

    _Py_RemoteDebug_ClearCache(&self->handle);
    return result;

result_err:
    _Py_RemoteDebug_ClearCache(&self->handle);
    Py_XDECREF(result);
    return NULL;
}

/*[clinic input]
@permit_long_summary
@critical_section
_remote_debugging.RemoteUnwinder.get_async_stack_trace

Get the currently running async tasks and their dependency graphs from the remote process.

This returns information about running tasks and all tasks that are
waiting for them, forming a complete dependency graph for each
thread's active task.

For each thread with a running task, returns the running task plus
all tasks that transitively depend on it (tasks waiting for the
running task, tasks waiting for those tasks, etc.).

Returns a list of per-thread results, where each thread result
contains:
- Thread ID
- List of task information for the running task and all its waiters

Each task info contains:
- Task ID (memory address)
- Task name
- Call stack frames: List of (func_name, filename, lineno)
- List of tasks waiting for this task (recursive structure)

Raises:
    RuntimeError: If AsyncioDebug section is not available in the
        target process
    MemoryError: If memory allocation fails
    OSError: If reading from the remote process fails

Example output (similar structure to get_all_awaited_by but only for
running tasks):
[
    # Thread 140234 results
    (140234, [
        # Running task and its complete waiter dependency graph
        (4345585712, 'main_task',
         [("run_server", "server.py", 127), ("main", "app.py", 23)],
         [
             # Tasks waiting for main_task
             (4345585800, 'worker_1', [...], [...]),
             (4345585900, 'worker_2', [...], [...])
         ])
    ])
]

[clinic start generated code]*/

static PyObject *
_remote_debugging_RemoteUnwinder_get_async_stack_trace_impl(RemoteUnwinderObject *self)
/*[clinic end generated code: output=6433d52b55e87bbe input=bc802e4221c99399]*/
{
    if (ensure_async_debug_offsets(self) < 0) {
        return NULL;
    }
    if (refresh_generation_caches_for_interpreter(self, self->interpreter_addr) < 0) {
        return NULL;
    }

    PyObject *result = PyList_New(0);
    if (result == NULL) {
        set_exception_cause(self, PyExc_MemoryError, "Failed to create result list in get_async_stack_trace");
        return NULL;
    }

    // Process all threads
    if (iterate_threads(self, process_thread_for_async_stack_trace, result) < 0) {
        goto result_err;
    }

    _Py_RemoteDebug_ClearCache(&self->handle);
    return result;
result_err:
    _Py_RemoteDebug_ClearCache(&self->handle);
    Py_XDECREF(result);
    return NULL;
}

/*[clinic input]
@critical_section
_remote_debugging.RemoteUnwinder.get_stats

Get collected statistics about profiling performance.

Returns a dictionary containing statistics about cache performance,
memory reads, and other profiling metrics. Only available if the
RemoteUnwinder was created with stats=True.

Returns:
    dict: A dictionary containing:
        - total_samples: Total number of get_stack_trace calls
        - frame_cache_hits: Full cache hits (entire stack unchanged)
        - frame_cache_misses: Cache misses requiring full walk
        - frame_cache_partial_hits: Partial hits (stopped at cached
          frame)
        - frames_read_from_cache: Total frames retrieved from cache
        - frames_read_from_memory: Total frames read from remote
          memory
        - memory_reads: Total remote memory read operations
        - memory_bytes_read: Total bytes read from remote memory
        - code_object_cache_hits: Code object cache hits
        - code_object_cache_misses: Code object cache misses
        - stale_cache_invalidations: Times stale cache entries were
          cleared
        - batched_read_attempts: Batched remote-read attempts
        - batched_read_successes: Attempts that read all requested
          segments
        - batched_read_misses: Attempts that fell back or partially
          read
        - batched_read_segments_requested: Segments requested by
          batched reads
        - batched_read_segments_completed: Segments completed by
          batched reads
        - frame_cache_hit_rate: Percentage of samples that hit the
          cache
        - code_object_cache_hit_rate: Percentage of code object
          lookups that hit cache
        - batched_read_success_rate: Percentage of batched reads
          that completed all segments
        - batched_read_segment_completion_rate: Percentage of
          requested segments read by batched reads

Raises:
    RuntimeError: If stats collection was not enabled (stats=False)
[clinic start generated code]*/

static PyObject *
_remote_debugging_RemoteUnwinder_get_stats_impl(RemoteUnwinderObject *self)
/*[clinic end generated code: output=21e36477122be2a0 input=87905c65038fb06e]*/
{
    if (!self->collect_stats) {
        PyErr_SetString(PyExc_RuntimeError,
                       "Statistics collection was not enabled. "
                       "Create RemoteUnwinder with stats=True to collect statistics.");
        return NULL;
    }

    PyObject *result = PyDict_New();
    if (!result) {
        return NULL;
    }

#define ADD_STAT(name) do { \
    PyObject *val = PyLong_FromUnsignedLongLong(self->stats.name); \
    if (!val || PyDict_SetItemString(result, #name, val) < 0) { \
        Py_XDECREF(val); \
        Py_DECREF(result); \
        return NULL; \
    } \
    Py_DECREF(val); \
} while(0)

    ADD_STAT(total_samples);
    ADD_STAT(frame_cache_hits);
    ADD_STAT(frame_cache_misses);
    ADD_STAT(frame_cache_partial_hits);
    ADD_STAT(frames_read_from_cache);
    ADD_STAT(frames_read_from_memory);
    ADD_STAT(memory_reads);
    ADD_STAT(memory_bytes_read);
    ADD_STAT(code_object_cache_hits);
    ADD_STAT(code_object_cache_misses);
    ADD_STAT(stale_cache_invalidations);
    ADD_STAT(batched_read_attempts);
    ADD_STAT(batched_read_successes);
    ADD_STAT(batched_read_misses);
    ADD_STAT(batched_read_segments_requested);
    ADD_STAT(batched_read_segments_completed);

#undef ADD_STAT

#define ADD_DERIVED_STAT(name, value) do { \
    PyObject *val = PyFloat_FromDouble(value); \
    if (!val || PyDict_SetItemString(result, name, val) < 0) { \
        Py_XDECREF(val); \
        Py_DECREF(result); \
        return NULL; \
    } \
    Py_DECREF(val); \
} while(0)

    // Calculate and add derived statistics
    // Hit rate is calculated as (hits + partial_hits) / total_cache_lookups
    double frame_cache_hit_rate = 0.0;
    uint64_t total_cache_lookups = self->stats.frame_cache_hits + self->stats.frame_cache_partial_hits + self->stats.frame_cache_misses;
    if (total_cache_lookups > 0) {
        frame_cache_hit_rate = 100.0 * (double)(self->stats.frame_cache_hits + self->stats.frame_cache_partial_hits)
                               / (double)total_cache_lookups;
    }
    ADD_DERIVED_STAT("frame_cache_hit_rate", frame_cache_hit_rate);

    double code_object_hit_rate = 0.0;
    uint64_t total_code_lookups = self->stats.code_object_cache_hits + self->stats.code_object_cache_misses;
    if (total_code_lookups > 0) {
        code_object_hit_rate = 100.0 * (double)self->stats.code_object_cache_hits / (double)total_code_lookups;
    }
    ADD_DERIVED_STAT("code_object_cache_hit_rate", code_object_hit_rate);

    double batched_read_success_rate = 0.0;
    if (self->stats.batched_read_attempts > 0) {
        batched_read_success_rate =
            100.0 * (double)self->stats.batched_read_successes
            / (double)self->stats.batched_read_attempts;
    }
    ADD_DERIVED_STAT("batched_read_success_rate", batched_read_success_rate);

    double batched_read_segment_completion_rate = 0.0;
    if (self->stats.batched_read_segments_requested > 0) {
        batched_read_segment_completion_rate =
            100.0 * (double)self->stats.batched_read_segments_completed
            / (double)self->stats.batched_read_segments_requested;
    }
    ADD_DERIVED_STAT("batched_read_segment_completion_rate",
                     batched_read_segment_completion_rate);

#undef ADD_DERIVED_STAT

    return result;
}

/*[clinic input]
@critical_section
_remote_debugging.RemoteUnwinder.pause_threads

Pause all threads in the target process.

This stops all threads in the target process to allow for consistent
memory reads during sampling. Must be paired with a call to
resume_threads().

Returns True if threads were successfully paused, False if they were
already paused.

Raises:
    RuntimeError: If there is an error stopping the threads
[clinic start generated code]*/

static PyObject *
_remote_debugging_RemoteUnwinder_pause_threads_impl(RemoteUnwinderObject *self)
/*[clinic end generated code: output=aaf2bdc0a725750c input=b91dde5517c9dde2]*/
{
#ifdef Py_REMOTE_DEBUG_SUPPORTS_BLOCKING
    if (self->threads_stopped) {
        Py_RETURN_FALSE;
    }

    _Py_RemoteDebug_InitThreadsState(self, &self->threads_state);
    if (_Py_RemoteDebug_StopAllThreads(self, &self->threads_state) < 0) {
        return NULL;
    }

    self->threads_stopped = 1;
    Py_RETURN_TRUE;
#else
    PyErr_SetString(PyExc_NotImplementedError,
                    "pause_threads is not supported on this platform");
    return NULL;
#endif
}

/*[clinic input]
@critical_section
_remote_debugging.RemoteUnwinder.resume_threads

Resume all threads in the target process.

This resumes threads that were previously paused with
pause_threads().

Returns True if threads were successfully resumed, False if they
were not paused.
[clinic start generated code]*/

static PyObject *
_remote_debugging_RemoteUnwinder_resume_threads_impl(RemoteUnwinderObject *self)
/*[clinic end generated code: output=8d6781ea37095536 input=130758d55d46897a]*/
{
#ifdef Py_REMOTE_DEBUG_SUPPORTS_BLOCKING
    if (!self->threads_stopped) {
        Py_RETURN_FALSE;
    }

    _Py_RemoteDebug_ResumeAllThreads(self, &self->threads_state);
    self->threads_stopped = 0;
    Py_RETURN_TRUE;
#else
    PyErr_SetString(PyExc_NotImplementedError,
                    "resume_threads is not supported on this platform");
    return NULL;
#endif
}

static PyMethodDef RemoteUnwinder_methods[] = {
    _REMOTE_DEBUGGING_REMOTEUNWINDER_GET_STACK_TRACE_METHODDEF
    _REMOTE_DEBUGGING_REMOTEUNWINDER_GET_ALL_AWAITED_BY_METHODDEF
    _REMOTE_DEBUGGING_REMOTEUNWINDER_GET_ASYNC_STACK_TRACE_METHODDEF
    _REMOTE_DEBUGGING_REMOTEUNWINDER_GET_STATS_METHODDEF
    _REMOTE_DEBUGGING_REMOTEUNWINDER_PAUSE_THREADS_METHODDEF
    _REMOTE_DEBUGGING_REMOTEUNWINDER_RESUME_THREADS_METHODDEF
    {NULL, NULL}
};

static void
RemoteUnwinder_dealloc(PyObject *op)
{
    RemoteUnwinderObject *self = RemoteUnwinder_CAST(op);
    PyTypeObject *tp = Py_TYPE(self);

#ifdef Py_REMOTE_DEBUG_SUPPORTS_BLOCKING
    if (self->threads_stopped) {
        _Py_RemoteDebug_ResumeAllThreads(self, &self->threads_state);
        self->threads_stopped = 0;
    }
#endif
#ifdef __linux__
    if (self->thread_tids != NULL) {
        PyMem_RawFree(self->thread_tids);
        self->thread_tids = NULL;
    }
#endif

    if (self->code_object_cache) {
        _Py_hashtable_destroy(self->code_object_cache);
    }
#ifdef MS_WINDOWS
    if (self->win_process_buffer != NULL) {
        PyMem_Free(self->win_process_buffer);
    }
#endif

#ifdef Py_GIL_DISABLED
    if (self->tlbc_cache) {
        _Py_hashtable_destroy(self->tlbc_cache);
    }
#endif
    if (self->handle.pid != 0) {
        _Py_RemoteDebug_ClearCache(&self->handle);
        _Py_RemoteDebug_CleanupProcHandle(&self->handle);
    }
    frame_cache_cleanup(self);
    PyObject_Del(self);
    Py_DECREF(tp);
}

static PyType_Slot RemoteUnwinder_slots[] = {
    {Py_tp_doc, (void *)"RemoteUnwinder(pid): Inspect stack of a remote Python process."},
    {Py_tp_methods, RemoteUnwinder_methods},
    {Py_tp_init, _remote_debugging_RemoteUnwinder___init__},
    {Py_tp_dealloc, RemoteUnwinder_dealloc},
    {0, NULL}
};

static PyType_Spec RemoteUnwinder_spec = {
    .name = "_remote_debugging.RemoteUnwinder",
    .basicsize = sizeof(RemoteUnwinderObject),
    .flags = (
        Py_TPFLAGS_DEFAULT
        | Py_TPFLAGS_IMMUTABLETYPE
    ),
    .slots = RemoteUnwinder_slots,
};

/* ============================================================================
 * GCMONITOR CLASS IMPLEMENTATION
 * ============================================================================ */

static void
cleanup_runtime_offsets(RuntimeOffsets *offsets)
{
    if (offsets->handle.pid != 0) {
        _Py_RemoteDebug_ClearCache(&offsets->handle);
        _Py_RemoteDebug_CleanupProcHandle(&offsets->handle);
    }
}

static int
init_runtime_offsets(RuntimeOffsets *offsets, pid_t pid, int debug)
{
    offsets->debug = debug;
    if (_Py_RemoteDebug_InitProcHandle(&offsets->handle, pid) < 0) {
        set_exception_cause(offsets, PyExc_RuntimeError, "Failed to initialize process handle");
        return -1;
    }
    offsets->runtime_start_address = _Py_RemoteDebug_GetPyRuntimeAddress(&offsets->handle);
    if (offsets->runtime_start_address == 0) {
        set_exception_cause(offsets, PyExc_RuntimeError, "Failed to get Python runtime address");
        goto error;
    }
    if (_Py_RemoteDebug_ReadDebugOffsets(&offsets->handle,
                                         &offsets->runtime_start_address,
                                         &offsets->debug_offsets) < 0)
    {
        set_exception_cause(offsets, PyExc_RuntimeError, "Failed to read debug offsets");
        goto error;
    }
    if (validate_debug_offsets(&offsets->debug_offsets) == -1) {
        set_exception_cause(offsets, PyExc_RuntimeError, "Invalid debug offsets found");
        goto error;
    }
    return 0;

error:
    cleanup_runtime_offsets(offsets);
    return -1;
}

/*[clinic input]
class _remote_debugging.GCMonitor "GCMonitorObject *" "&GCMonitor_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ebc229325a5e5154]*/

/*[clinic input]
@permit_long_summary
_remote_debugging.GCMonitor.__init__
    pid: pid_t
    *
    debug: bool = False

Initialize a new GCMonitor object for monitoring GC events from remote process.

Args:
    pid: Process ID of the target Python process to monitor
    debug: If True, chain exceptions to explain the sequence of
           events that lead to the exception.

The GCMonitor provides functionality to read GC statistics from
a running Python process.

Raises:
    PermissionError: If access to the target process is denied
    OSError: If unable to attach to the target process or access
        its memory
    RuntimeError: If unable to read debug information from the
        target process
[clinic start generated code]*/

static int
_remote_debugging_GCMonitor___init___impl(GCMonitorObject *self, pid_t pid,
                                          int debug)
/*[clinic end generated code: output=03b4c92bef0673ad input=dcc6ee2ec5a16fa1]*/
{
    return init_runtime_offsets(&self->offsets, pid, debug);
}

/*[clinic input]
@critical_section
_remote_debugging.GCMonitor.get_gc_stats

    all_interpreters: bool = False
        If True, return GC statistics from all interpreters.
        If False, return only from main interpreter.

Get garbage collector statistics from external Python process.

Returns a list of GCStatsInfo objects with GC statistics data.

Returns:
    list of GCStatsInfo: A list of stats samples containing:
        - gen: GC generation number.
        - iid: Interpreter ID.
        - ts_start: Raw timestamp at collection start.
        - ts_stop: Raw timestamp at collection stop.
        - collections: Total number of collections.
        - collected: Total number of collected objects.
        - uncollectable: Total number of uncollectable objects.
        - candidates: Total objects considered and traversed.
        - heap_size: number of live objects.
        - duration: Total collection time, in seconds.

Raises:
    RuntimeError: If the target process cannot be inspected or if
        its debug offsets or GC stats layout are incompatible.
[clinic start generated code]*/

static PyObject *
_remote_debugging_GCMonitor_get_gc_stats_impl(GCMonitorObject *self,
                                              int all_interpreters)
/*[clinic end generated code: output=f73f365725224f7a input=ec016bc4be6dd003]*/
{
    RemoteDebuggingState *st = RemoteDebugging_GetStateFromType(Py_TYPE(self));
    return get_gc_stats(&self->offsets, all_interpreters, st->GCStatsInfo_Type);
}

static PyMethodDef GCMonitor_methods[] = {
    _REMOTE_DEBUGGING_GCMONITOR_GET_GC_STATS_METHODDEF
    {NULL, NULL}
};

static void
GCMonitor_dealloc(PyObject *op)
{
    GCMonitorObject *self = GCMonitor_CAST(op);
    PyTypeObject *tp = Py_TYPE(self);

    cleanup_runtime_offsets(&self->offsets);
    PyObject_Del(self);
    Py_DECREF(tp);
}

static PyType_Slot GCMonitor_slots[] = {
    {Py_tp_doc, (void *)"GCMonitor(pid): Monitor GC events of a remote Python process."},
    {Py_tp_methods, GCMonitor_methods},
    {Py_tp_init, _remote_debugging_GCMonitor___init__},
    {Py_tp_dealloc, GCMonitor_dealloc},
    {0, NULL}
};

static PyType_Spec GCMonitor_spec = {
    .name = "_remote_debugging.GCMonitor",
    .basicsize = sizeof(GCMonitorObject),
    .flags = (
        Py_TPFLAGS_DEFAULT
        | Py_TPFLAGS_IMMUTABLETYPE
    ),
    .slots = GCMonitor_slots,
};

/* Forward declarations for type specs defined later */
static PyType_Spec BinaryWriter_spec;
static PyType_Spec BinaryReader_spec;

/* ============================================================================
 * MODULE INITIALIZATION
 * ============================================================================ */

static int
_remote_debugging_exec(PyObject *m)
{
    RemoteDebuggingState *st = RemoteDebugging_GetState(m);
#define CREATE_TYPE(mod, type, spec)                                        \
    do {                                                                    \
        type = (PyTypeObject *)PyType_FromMetaclass(NULL, mod, spec, NULL); \
        if (type == NULL) {                                                 \
            return -1;                                                      \
        }                                                                   \
    } while (0)

    CREATE_TYPE(m, st->RemoteDebugging_Type, &RemoteUnwinder_spec);

    if (PyModule_AddType(m, st->RemoteDebugging_Type) < 0) {
        return -1;
    }

    CREATE_TYPE(m, st->GCMonitor_Type, &GCMonitor_spec);
    if (PyModule_AddType(m, st->GCMonitor_Type) < 0) {
        return -1;
    }

    // Initialize structseq types
    st->TaskInfo_Type = PyStructSequence_NewType(&TaskInfo_desc);
    if (st->TaskInfo_Type == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, st->TaskInfo_Type) < 0) {
        return -1;
    }

    st->LocationInfo_Type = PyStructSequence_NewType(&LocationInfo_desc);
    if (st->LocationInfo_Type == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, st->LocationInfo_Type) < 0) {
        return -1;
    }

    st->FrameInfo_Type = PyStructSequence_NewType(&FrameInfo_desc);
    if (st->FrameInfo_Type == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, st->FrameInfo_Type) < 0) {
        return -1;
    }

    st->CoroInfo_Type = PyStructSequence_NewType(&CoroInfo_desc);
    if (st->CoroInfo_Type == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, st->CoroInfo_Type) < 0) {
        return -1;
    }

    st->ThreadInfo_Type = PyStructSequence_NewType(&ThreadInfo_desc);
    if (st->ThreadInfo_Type == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, st->ThreadInfo_Type) < 0) {
        return -1;
    }

    st->InterpreterInfo_Type = PyStructSequence_NewType(&InterpreterInfo_desc);
    if (st->InterpreterInfo_Type == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, st->InterpreterInfo_Type) < 0) {
        return -1;
    }

    st->AwaitedInfo_Type = PyStructSequence_NewType(&AwaitedInfo_desc);
    if (st->AwaitedInfo_Type == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, st->AwaitedInfo_Type) < 0) {
        return -1;
    }

    st->GCStatsInfo_Type = PyStructSequence_NewType(&GCStatsInfo_desc);
    if (st->GCStatsInfo_Type == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, st->GCStatsInfo_Type) < 0) {
        return -1;
    }

    // Create BinaryWriter and BinaryReader types
    CREATE_TYPE(m, st->BinaryWriter_Type, &BinaryWriter_spec);
    if (PyModule_AddType(m, st->BinaryWriter_Type) < 0) {
        return -1;
    }

    CREATE_TYPE(m, st->BinaryReader_Type, &BinaryReader_spec);
    if (PyModule_AddType(m, st->BinaryReader_Type) < 0) {
        return -1;
    }

    int rc = PyModule_AddIntConstant(m, "PROCESS_VM_READV_SUPPORTED", HAVE_PROCESS_VM_READV);
    if (rc < 0) {
        return -1;
    }

    // Add thread status flag constants
    if (PyModule_AddIntConstant(m, "THREAD_STATUS_HAS_GIL", THREAD_STATUS_HAS_GIL) < 0) {
        return -1;
    }
    if (PyModule_AddIntConstant(m, "THREAD_STATUS_ON_CPU", THREAD_STATUS_ON_CPU) < 0) {
        return -1;
    }
    if (PyModule_AddIntConstant(m, "THREAD_STATUS_UNKNOWN", THREAD_STATUS_UNKNOWN) < 0) {
        return -1;
    }
    if (PyModule_AddIntConstant(m, "THREAD_STATUS_GIL_REQUESTED", THREAD_STATUS_GIL_REQUESTED) < 0) {
        return -1;
    }
    if (PyModule_AddIntConstant(m, "THREAD_STATUS_HAS_EXCEPTION", THREAD_STATUS_HAS_EXCEPTION) < 0) {
        return -1;
    }
    if (PyModule_AddIntConstant(m, "THREAD_STATUS_MAIN_THREAD", THREAD_STATUS_MAIN_THREAD) < 0) {
        return -1;
    }

    if (RemoteDebugging_InitState(st) < 0) {
        return -1;
    }
    return 0;
}

static int
remote_debugging_traverse(PyObject *mod, visitproc visit, void *arg)
{
    RemoteDebuggingState *state = RemoteDebugging_GetState(mod);
    Py_VISIT(state->RemoteDebugging_Type);
    Py_VISIT(state->TaskInfo_Type);
    Py_VISIT(state->LocationInfo_Type);
    Py_VISIT(state->FrameInfo_Type);
    Py_VISIT(state->CoroInfo_Type);
    Py_VISIT(state->ThreadInfo_Type);
    Py_VISIT(state->InterpreterInfo_Type);
    Py_VISIT(state->AwaitedInfo_Type);
    Py_VISIT(state->GCStatsInfo_Type);
    Py_VISIT(state->BinaryWriter_Type);
    Py_VISIT(state->BinaryReader_Type);
    Py_VISIT(state->GCMonitor_Type);
    return 0;
}

static int
remote_debugging_clear(PyObject *mod)
{
    RemoteDebuggingState *state = RemoteDebugging_GetState(mod);
    Py_CLEAR(state->RemoteDebugging_Type);
    Py_CLEAR(state->TaskInfo_Type);
    Py_CLEAR(state->LocationInfo_Type);
    Py_CLEAR(state->FrameInfo_Type);
    Py_CLEAR(state->CoroInfo_Type);
    Py_CLEAR(state->ThreadInfo_Type);
    Py_CLEAR(state->InterpreterInfo_Type);
    Py_CLEAR(state->AwaitedInfo_Type);
    Py_CLEAR(state->GCStatsInfo_Type);
    Py_CLEAR(state->BinaryWriter_Type);
    Py_CLEAR(state->BinaryReader_Type);
    Py_CLEAR(state->GCMonitor_Type);
    return 0;
}

static void
remote_debugging_free(void *mod)
{
    (void)remote_debugging_clear((PyObject *)mod);
}

/* ============================================================================
 * BINARY WRITER CLASS
 * ============================================================================ */

#define BinaryWriter_CAST(op) ((BinaryWriterObject *)(op))

/*[clinic input]
class _remote_debugging.BinaryWriter "BinaryWriterObject *" "&PyBinaryWriter_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e948838b90a2003c]*/

/*[clinic input]
_remote_debugging.BinaryWriter.__init__
    filename: object
    sample_interval_us: unsigned_long_long
    start_time_us: unsigned_long_long
    *
    compression: int = 0
    mode: int = -1
    capture_features: int = -1

High-performance binary writer for profiling data.

Arguments:
    filename: Path to output file
    sample_interval_us: Sampling interval in microseconds
    start_time_us: Start timestamp in microseconds (from
        time.monotonic() * 1e6)
    compression: 0=none, 1=zstd (default: 0)
    mode: Profiling mode, or -1 if unknown (default: -1)
    capture_features: Capture feature bit mask, or -1 if unknown
        (default: -1)

Use as a context manager or call finalize() when done.
[clinic start generated code]*/

static int
_remote_debugging_BinaryWriter___init___impl(BinaryWriterObject *self,
                                             PyObject *filename,
                                             unsigned long long sample_interval_us,
                                             unsigned long long start_time_us,
                                             int compression, int mode,
                                             int capture_features)
/*[clinic end generated code: output=3c1c9576795658ce input=98add735b20403ad]*/
{
    if (mode < -1 || mode > PROFILING_MODE_EXCEPTION) {
        PyErr_SetString(PyExc_ValueError, "invalid profiling mode");
        return -1;
    }
    if (capture_features < -1 ||
        capture_features > (int)PROFILING_FEATURE_MASK) {
        PyErr_SetString(PyExc_ValueError, "invalid capture features");
        return -1;
    }
    if (self->writer) {
        binary_writer_destroy(self->writer);
    }

    self->writer = binary_writer_create(
        filename, sample_interval_us, compression, start_time_us, mode,
        capture_features);
    if (!self->writer) {
        return -1;
    }

    return 0;
}

/*[clinic input]
_remote_debugging.BinaryWriter.write_sample
    stack_frames: object
    timestamp_us: unsigned_long_long

Write a sample to the binary file.

Arguments:
    stack_frames: List of InterpreterInfo objects
    timestamp_us: Current timestamp in microseconds (from
        time.monotonic() * 1e6)
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryWriter_write_sample_impl(BinaryWriterObject *self,
                                                 PyObject *stack_frames,
                                                 unsigned long long timestamp_us)
/*[clinic end generated code: output=24d5b86679b4128f input=5033f1ae7fa135f1]*/
{
    if (!self->writer) {
        PyErr_SetString(PyExc_ValueError, "Writer is closed");
        return NULL;
    }

    if (self->writer->state == BINARY_WRITER_BROKEN) {
        PyErr_SetString(PyExc_ValueError, "Writer is broken");
        return NULL;
    }
    self->writer->state = BINARY_WRITER_OPEN;
    if (binary_writer_write_sample(self->writer, stack_frames, timestamp_us) < 0) {
        if (self->writer->state != BINARY_WRITER_LIMIT_REACHED) {
            self->writer->state = BINARY_WRITER_BROKEN;
        }
        return NULL;
    }

    Py_RETURN_NONE;
}

/*[clinic input]
_remote_debugging.BinaryWriter.set_stats
    duration_sec: double
    sample_rate: double
    error_rate: object = None
    missed_samples: object = None

Store measured profile statistics in the binary file.
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryWriter_set_stats_impl(BinaryWriterObject *self,
                                              double duration_sec,
                                              double sample_rate,
                                              PyObject *error_rate,
                                              PyObject *missed_samples)
/*[clinic end generated code: output=28ab1bdd7c631a97 input=1646e7182f4c2259]*/
{
    if (!self->writer) {
        PyErr_SetString(PyExc_ValueError, "Writer is closed");
        return NULL;
    }
    uint32_t present = 0;
    double error_rate_value = 0.0;
    double missed_samples_value = 0.0;
    if (error_rate != Py_None) {
        error_rate_value = PyFloat_AsDouble(error_rate);
        if (error_rate_value == -1.0 && PyErr_Occurred()) {
            return NULL;
        }
        present |= PROFILE_STATS_ERROR_RATE;
    }
    if (missed_samples != Py_None) {
        missed_samples_value = PyFloat_AsDouble(missed_samples);
        if (missed_samples_value == -1.0 && PyErr_Occurred()) {
            return NULL;
        }
        present |= PROFILE_STATS_MISSED;
    }
    if (binary_writer_set_stats(self->writer, duration_sec, sample_rate,
                                error_rate_value, missed_samples_value,
                                present) < 0) {
        return NULL;
    }
    Py_RETURN_NONE;
}

/* Finalize the writer, cache total_samples, and destroy it.
 *
 * The cache assignment must happen AFTER binary_writer_finalize(): finalize
 * flushes pending RLE records and updates the file header before the writer is
 * destroyed. Caching before finalize would preserve a count for a file that
 * might still fail to finish. */
static int
binary_writer_finalize_and_cache(BinaryWriterObject *self)
{
    if (self->writer->state == BINARY_WRITER_BROKEN) {
        PyErr_SetString(PyExc_ValueError, "Writer is broken");
        return -1;
    }
    if (binary_writer_finalize(self->writer) < 0) {
        self->writer->state = BINARY_WRITER_BROKEN;
        return -1;
    }
    self->cached_total_samples = self->writer->total_samples;
    binary_writer_destroy(self->writer);
    self->writer = NULL;
    return 0;
}

/*[clinic input]
_remote_debugging.BinaryWriter.finalize

Finalize and close the binary file.

Writes string/frame tables, footer, and updates header.
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryWriter_finalize_impl(BinaryWriterObject *self)
/*[clinic end generated code: output=3534b88c6628de88 input=c02191750682f6a2]*/
{
    if (!self->writer) {
        PyErr_SetString(PyExc_ValueError, "Writer is already closed");
        return NULL;
    }

    if (binary_writer_finalize_and_cache(self) < 0) {
        return NULL;
    }

    Py_RETURN_NONE;
}

/*[clinic input]
_remote_debugging.BinaryWriter.close

Close the writer without finalizing (discards data).
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryWriter_close_impl(BinaryWriterObject *self)
/*[clinic end generated code: output=9571bb2256fd1fd2 input=6e0da206e60daf16]*/
{
    if (self->writer) {
        binary_writer_destroy(self->writer);
        self->writer = NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
_remote_debugging.BinaryWriter.__enter__

Enter context manager.
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryWriter___enter___impl(BinaryWriterObject *self)
/*[clinic end generated code: output=8eb95f61daf2d120 input=8ef14ee18da561d2]*/
{
    Py_INCREF(self);
    return (PyObject *)self;
}

/*[clinic input]
_remote_debugging.BinaryWriter.__exit__
    exc_type: object = None
    exc_val: object = None
    exc_tb: object = None

Exit context manager, finalizing the file.
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryWriter___exit___impl(BinaryWriterObject *self,
                                             PyObject *exc_type,
                                             PyObject *exc_val,
                                             PyObject *exc_tb)
/*[clinic end generated code: output=61831f47c72a53c6 input=12334ce1009af37f]*/
{
    if (self->writer) {
        if (self->writer->state != BINARY_WRITER_BROKEN) {
            if (binary_writer_finalize_and_cache(self) < 0) {
                if (self->writer) {
                    binary_writer_destroy(self->writer);
                    self->writer = NULL;
                }
                return NULL;
            }
        }
        else {
            binary_writer_destroy(self->writer);
            self->writer = NULL;
        }
    }
    Py_RETURN_FALSE;
}

/*[clinic input]
_remote_debugging.BinaryWriter.get_stats

Get encoding statistics for the writer.

Returns a dict with encoding statistics including
repeat/full/suffix/pop-push record counts, frames written/saved, and
compression ratio.
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryWriter_get_stats_impl(BinaryWriterObject *self)
/*[clinic end generated code: output=06522cd52544df89 input=a8bb8c8682ccd34b]*/
{
    if (!self->writer) {
        PyErr_SetString(PyExc_ValueError, "Writer is closed");
        return NULL;
    }
    return binary_writer_get_stats(self->writer);
}

static PyObject *
BinaryWriter_get_total_samples(PyObject *op, void *closure)
{
    BinaryWriterObject *self = BinaryWriter_CAST(op);
    if (!self->writer) {
        /* Use cached value after finalize/close */
        return PyLong_FromUnsignedLongLong(self->cached_total_samples);
    }
    return PyLong_FromUnsignedLongLong(self->writer->total_samples);
}

static PyObject *
BinaryWriter_get_limit_reached(PyObject *op, void *closure)
{
    BinaryWriter *writer = BinaryWriter_CAST(op)->writer;
    return PyBool_FromLong(writer && writer->state == BINARY_WRITER_LIMIT_REACHED);
}

static PyGetSetDef BinaryWriter_getset[] = {
    {"total_samples", BinaryWriter_get_total_samples, NULL, "Total samples written", NULL},
    {"limit_reached", BinaryWriter_get_limit_reached, NULL,
     "A format limit was reached; the collected samples can still be finalized", NULL},
    {NULL}
};

static PyMethodDef BinaryWriter_methods[] = {
    _REMOTE_DEBUGGING_BINARYWRITER_WRITE_SAMPLE_METHODDEF
    _REMOTE_DEBUGGING_BINARYWRITER_SET_STATS_METHODDEF
    _REMOTE_DEBUGGING_BINARYWRITER_FINALIZE_METHODDEF
    _REMOTE_DEBUGGING_BINARYWRITER_CLOSE_METHODDEF
    _REMOTE_DEBUGGING_BINARYWRITER___ENTER___METHODDEF
    _REMOTE_DEBUGGING_BINARYWRITER___EXIT___METHODDEF
    _REMOTE_DEBUGGING_BINARYWRITER_GET_STATS_METHODDEF
    {NULL, NULL, 0, NULL}
};

static void
BinaryWriter_dealloc(PyObject *op)
{
    BinaryWriterObject *self = BinaryWriter_CAST(op);
    PyTypeObject *tp = Py_TYPE(self);
    if (self->writer) {
        binary_writer_destroy(self->writer);
    }
    tp->tp_free(self);
    Py_DECREF(tp);
}

static PyType_Slot BinaryWriter_slots[] = {
    {Py_tp_getset, BinaryWriter_getset},
    {Py_tp_methods, BinaryWriter_methods},
    {Py_tp_init, _remote_debugging_BinaryWriter___init__},
    {Py_tp_dealloc, BinaryWriter_dealloc},
    {0, NULL}
};

static PyType_Spec BinaryWriter_spec = {
    .name = "_remote_debugging.BinaryWriter",
    .basicsize = sizeof(BinaryWriterObject),
    .flags = (
        Py_TPFLAGS_DEFAULT
        | Py_TPFLAGS_IMMUTABLETYPE
    ),
    .slots = BinaryWriter_slots,
};

/* ============================================================================
 * BINARY READER CLASS
 * ============================================================================ */

#define BinaryReader_CAST(op) ((BinaryReaderObject *)(op))

/*[clinic input]
class _remote_debugging.BinaryReader "BinaryReaderObject *" "&PyBinaryReader_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=36400aaf6f53216d]*/

/*[clinic input]
_remote_debugging.BinaryReader.__init__
    filename: object

High-performance binary reader for profiling data.

Arguments:
    filename: Path to input file

Use as a context manager or call close() when done.
[clinic start generated code]*/

static int
_remote_debugging_BinaryReader___init___impl(BinaryReaderObject *self,
                                             PyObject *filename)
/*[clinic end generated code: output=f04b33ee5c5e6dbf input=9d7cbe8b4f1a97c9]*/
{
    if (self->reader) {
        binary_reader_close(self->reader);
    }

    self->reader = binary_reader_open(filename);
    if (!self->reader) {
        return -1;
    }

    return 0;
}

/*[clinic input]
_remote_debugging.BinaryReader.replay
    collector: object
    progress_callback: object = None

Replay samples through a collector.

Arguments:
    collector: Collector object with collect() method
    progress_callback: Optional callable(current, total)

Returns:
    Number of samples replayed
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryReader_replay_impl(BinaryReaderObject *self,
                                           PyObject *collector,
                                           PyObject *progress_callback)
/*[clinic end generated code: output=442345562574b61c input=ebb687aed3e0f4f1]*/
{
    if (!self->reader) {
        PyErr_SetString(PyExc_ValueError, "Reader is closed");
        return NULL;
    }

    Py_ssize_t replayed = binary_reader_replay(self->reader, collector, progress_callback);
    if (replayed < 0) {
        return NULL;
    }

    return PyLong_FromSsize_t(replayed);
}

/*[clinic input]
_remote_debugging.BinaryReader.get_info

Get metadata about the binary file.

Returns:
    Dict with file metadata
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryReader_get_info_impl(BinaryReaderObject *self)
/*[clinic end generated code: output=7f641fbd39147391 input=02e75e39c8a6cd1f]*/
{
    if (!self->reader) {
        PyErr_SetString(PyExc_ValueError, "Reader is closed");
        return NULL;
    }

    return binary_reader_get_info(self->reader);
}

/*[clinic input]
_remote_debugging.BinaryReader.get_stats

Get reconstruction statistics from replay.

Returns a dict with statistics about record types decoded and
samples reconstructed during replay.
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryReader_get_stats_impl(BinaryReaderObject *self)
/*[clinic end generated code: output=628b9ab5e4c4fd36 input=15b8d8f89ccf3726]*/
{
    if (!self->reader) {
        PyErr_SetString(PyExc_ValueError, "Reader is closed");
        return NULL;
    }
    return binary_reader_get_stats(self->reader);
}

/*[clinic input]
_remote_debugging.BinaryReader.close

Close the reader and free resources.
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryReader_close_impl(BinaryReaderObject *self)
/*[clinic end generated code: output=ad0238cf5240b4f8 input=b919a66c737712d5]*/
{
    if (self->reader) {
        binary_reader_close(self->reader);
        self->reader = NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
_remote_debugging.BinaryReader.__enter__

Enter context manager.
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryReader___enter___impl(BinaryReaderObject *self)
/*[clinic end generated code: output=fade133538e93817 input=4794844c9efdc4f6]*/
{
    Py_INCREF(self);
    return (PyObject *)self;
}

/*[clinic input]
_remote_debugging.BinaryReader.__exit__
    exc_type: object = None
    exc_val: object = None
    exc_tb: object = None

Exit context manager, closing the file.
[clinic start generated code]*/

static PyObject *
_remote_debugging_BinaryReader___exit___impl(BinaryReaderObject *self,
                                             PyObject *exc_type,
                                             PyObject *exc_val,
                                             PyObject *exc_tb)
/*[clinic end generated code: output=2acdd36cfdc14e4a input=87284243d7935835]*/
{
    if (self->reader) {
        binary_reader_close(self->reader);
        self->reader = NULL;
    }
    Py_RETURN_FALSE;
}

static PyObject *
BinaryReader_get_sample_count(BinaryReaderObject *self, void *closure)
{
    if (!self->reader) {
        return PyLong_FromLong(0);
    }
    return PyLong_FromUnsignedLongLong(self->reader->sample_count);
}

static PyObject *
BinaryReader_get_sample_interval_us(BinaryReaderObject *self, void *closure)
{
    if (!self->reader) {
        return PyLong_FromLong(0);
    }
    return PyLong_FromUnsignedLongLong(self->reader->sample_interval_us);
}

static PyGetSetDef BinaryReader_getset[] = {
    {"sample_count", (getter)BinaryReader_get_sample_count, NULL, "Number of samples in file", NULL},
    {"sample_interval_us", (getter)BinaryReader_get_sample_interval_us, NULL, "Sample interval in microseconds", NULL},
    {NULL}
};

static PyMethodDef BinaryReader_methods[] = {
    _REMOTE_DEBUGGING_BINARYREADER_REPLAY_METHODDEF
    _REMOTE_DEBUGGING_BINARYREADER_GET_INFO_METHODDEF
    _REMOTE_DEBUGGING_BINARYREADER_GET_STATS_METHODDEF
    _REMOTE_DEBUGGING_BINARYREADER_CLOSE_METHODDEF
    _REMOTE_DEBUGGING_BINARYREADER___ENTER___METHODDEF
    _REMOTE_DEBUGGING_BINARYREADER___EXIT___METHODDEF
    {NULL, NULL, 0, NULL}
};

static void
BinaryReader_dealloc(PyObject *op)
{
    BinaryReaderObject *self = BinaryReader_CAST(op);
    PyTypeObject *tp = Py_TYPE(self);
    if (self->reader) {
        binary_reader_close(self->reader);
    }
    tp->tp_free(self);
    Py_DECREF(tp);
}

static PyType_Slot BinaryReader_slots[] = {
    {Py_tp_getset, BinaryReader_getset},
    {Py_tp_methods, BinaryReader_methods},
    {Py_tp_init, _remote_debugging_BinaryReader___init__},
    {Py_tp_dealloc, BinaryReader_dealloc},
    {0, NULL}
};

static PyType_Spec BinaryReader_spec = {
    .name = "_remote_debugging.BinaryReader",
    .basicsize = sizeof(BinaryReaderObject),
    .flags = (
        Py_TPFLAGS_DEFAULT
        | Py_TPFLAGS_IMMUTABLETYPE
    ),
    .slots = BinaryReader_slots,
};

/* ============================================================================
 * MODULE METHODS
 * ============================================================================ */

/*[clinic input]
_remote_debugging.zstd_available

Check if zstd compression is available.

Returns:
    True if zstd available, False otherwise
[clinic start generated code]*/

static PyObject *
_remote_debugging_zstd_available_impl(PyObject *module)
/*[clinic end generated code: output=55e35a70ef280cdd input=a1b4d41bc09c7cf9]*/
{
    return PyBool_FromLong(binary_io_zstd_available());
}

/* ============================================================================
 * MODULE-LEVEL FUNCTIONS
 * ============================================================================ */

/*[clinic input]
_remote_debugging.get_child_pids

    pid: pid_t
        Process ID of the parent process
    *
    recursive: bool = True
        If True, return all descendants (children, grandchildren, etc.).
        If False, return only direct children.

Get all child process IDs of the given process.

Returns a list of child process IDs.  Returns an empty list if no
children are found.

This function provides a snapshot of child processes at a moment in
time.  Child processes may exit or new ones may be created after the
list is returned.

Raises:
    OSError: If unable to enumerate processes
    NotImplementedError: If not supported on this platform
[clinic start generated code]*/

static PyObject *
_remote_debugging_get_child_pids_impl(PyObject *module, pid_t pid,
                                      int recursive)
/*[clinic end generated code: output=fa3dfd1b02eed29b input=3325d95e9f39d75d]*/
{
    return enumerate_child_pids(pid, recursive);
}

/*[clinic input]
_remote_debugging.is_python_process

    pid: pid_t

Check if a process is a Python process.
[clinic start generated code]*/

static PyObject *
_remote_debugging_is_python_process_impl(PyObject *module, pid_t pid)
/*[clinic end generated code: output=63541478c889e536 input=ff998fef4aeef433]*/
{
    proc_handle_t handle;

    if (_Py_RemoteDebug_InitProcHandle(&handle, pid) < 0) {
        PyErr_Clear();
        Py_RETURN_FALSE;
    }

    uintptr_t runtime_start_address = _Py_RemoteDebug_GetPyRuntimeAddress(&handle);
    _Py_RemoteDebug_CleanupProcHandle(&handle);

    if (runtime_start_address == 0) {
        PyErr_Clear();
        Py_RETURN_FALSE;
    }

    Py_RETURN_TRUE;
}

/*[clinic input]
_remote_debugging.get_gc_stats

    pid: pid_t
    *
    all_interpreters: bool = False
        If True, return GC statistics from all interpreters.
        If False, return only from main interpreter.

Get garbage collector statistics from external Python process.

Returns:
    list of GCStatsInfo: A list of stats samples containing:
        - gen: GC generation number.
        - iid: Interpreter ID.
        - ts_start: Raw timestamp at collection start.
        - ts_stop: Raw timestamp at collection stop.
        - collections: Total number of collections.
        - collected: Total number of collected objects.
        - uncollectable: Total number of uncollectable objects.
        - candidates: Total objects considered and traversed.
        - duration: Total collection time, in seconds.

Raises:
    RuntimeError: If the target process cannot be inspected or if its
        debug offsets or GC stats layout are incompatible.
[clinic start generated code]*/

static PyObject *
_remote_debugging_get_gc_stats_impl(PyObject *module, pid_t pid,
                                    int all_interpreters)
/*[clinic end generated code: output=dd33199ccb6a56e9 input=41399e77788aa369]*/
{
    RuntimeOffsets offsets;
    if (init_runtime_offsets(&offsets, pid, /*debug=*/1) < 0) {
        return NULL;
    }

    RemoteDebuggingState *st = RemoteDebugging_GetState(module);
    PyObject *result = get_gc_stats(&offsets, all_interpreters,
                                    st->GCStatsInfo_Type);

    cleanup_runtime_offsets(&offsets);
    return result;
}

static PyMethodDef remote_debugging_methods[] = {
    _REMOTE_DEBUGGING_ZSTD_AVAILABLE_METHODDEF
    _REMOTE_DEBUGGING_GET_CHILD_PIDS_METHODDEF
    _REMOTE_DEBUGGING_IS_PYTHON_PROCESS_METHODDEF
    _REMOTE_DEBUGGING_GET_GC_STATS_METHODDEF
    {NULL, NULL, 0, NULL},
};

static PyModuleDef_Slot remote_debugging_slots[] = {
    _Py_ABI_SLOT,
    {Py_mod_exec, _remote_debugging_exec},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL},
};

static struct PyModuleDef remote_debugging_module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_remote_debugging",
    .m_size = sizeof(RemoteDebuggingState),
    .m_methods = remote_debugging_methods,
    .m_slots = remote_debugging_slots,
    .m_traverse = remote_debugging_traverse,
    .m_clear = remote_debugging_clear,
    .m_free = remote_debugging_free,
};

PyMODINIT_FUNC
PyInit__remote_debugging(void)
{
    return PyModuleDef_Init(&remote_debugging_module);
}
