Bug 2498425 - gdb SIGABRT (double free) loading a core file with repeated file-backed mappings (KDE/Wayland /memfd:wayland-shm)
Summary: gdb SIGABRT (double free) loading a core file with repeated file-backed mappi...
Keywords:
Status: CLOSED DUPLICATE of bug 2498034
Alias: None
Product: Fedora
Classification: Fedora
Component: gdb
Version: 44
Hardware: x86_64
OS: Linux
unspecified
high
Target Milestone: ---
Assignee: Kevin Buettner
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-07-09 08:04 UTC by umut.erdem
Modified: 2026-07-13 14:39 UTC (History)
10 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2026-07-13 14:39:04 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
Proposed one-line fix: reserve() in gdb_read_core_file_mappings (corelow.c) (1.56 KB, patch)
2026-07-09 08:04 UTC, umut.erdem
no flags Details | Diff
Self-contained minimal reproducer (no KDE required) (1.63 KB, text/plain)
2026-07-09 08:04 UTC, umut.erdem
no flags Details

Description umut.erdem 2026-07-09 08:04:06 UTC
Description of problem:
gdb aborts with a glibc heap error (SIGABRT, "free(): double free detected
in tcache 2") when opening a core file that contains the same file-backed
mapping name at two non-adjacent address ranges with many other distinct
mapped files in between. This is the normal memory layout of KDE / Wayland
programs, whose "/memfd:wayland-shm (deleted)" mappings appear several times
scattered across the address space.

Because ABRT runs gdb to generate a backtrace for every crashed program,
every crash of a KDE/Wayland application makes gdb itself crash, so no usable
backtrace is produced and coredumpctl fills up with "gdb killed by SIGABRT".

Version-Release number of selected component:
gdb-17.2-1.fc44 (also reproducible with the same code in current upstream;
introduced by the core_mapped_file / gdb_read_core_file_mappings refactor,
present since GDB 16).

How reproducible:
Always, given a matching core file.

Steps to Reproduce:
A self-contained reproducer (no KDE needed):

    /* gdb-corefile-doublefree-reproducer.c */
    #define _GNU_SOURCE
    #include <sys/mman.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #define N 200
    #define PAGE 4096
    int main(void) {
        long total = (long)(N + 2) * PAGE;
        char *base = mmap(NULL, total, PROT_NONE,
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
        int shared = memfd_create("wayland-shm", 0);
        ftruncate(shared, PAGE);
        mmap(base, PAGE, PROT_READ, MAP_SHARED | MAP_FIXED, shared, 0);
        for (int i = 0; i < N; i++) {
            char nm[32]; snprintf(nm, sizeof nm, "distinct-%d", i);
            int fd = memfd_create(nm, 0); ftruncate(fd, PAGE);
            mmap(base + (long)(i + 1) * PAGE, PAGE, PROT_READ,
                 MAP_SHARED | MAP_FIXED, fd, 0);
        }
        mmap(base + (long)(N + 1) * PAGE, PAGE, PROT_READ,
             MAP_SHARED | MAP_FIXED, shared, 0);
        abort();
    }

    gcc -g -O0 -o rep gdb-corefile-doublefree-reproducer.c
    ./rep
    coredumpctl dump ./rep --output=rep.core
    gdb -batch -ex 'set debuginfod enabled off' \
        -ex 'file ./rep' -ex 'core-file ./rep.core'

Actual results:
    warning: Can't open file /memfd:wayland-shm (deleted) during file-backed mapping note processing
    free(): double free detected in tcache 2
    A fatal error internal to GDB has been detected, further
    debugging is not possible.  GDB will now terminate.

Backtrace of the abort:
    #6  malloc_printerr                     malloc.c:5341
    #7  tcache_double_free_verify           malloc.c:3159
    #8  core_target::build_file_mappings()  corelow.c:582   (vector<core_mapped_file> dtor)
    #9  core_target::core_target()          corelow.c:351
    #10 core_target_open(char const*, int)  corelow.c

Expected results:
gdb loads the core file and prints a normal backtrace.

Additional info / root cause:
gdb_read_core_file_mappings() in gdb/corelow.c builds a
std::vector<core_mapped_file> results, and its internal map_entry keeps a raw
core_mapped_file* pointing into that vector:

    results.emplace_back ();
    map_entry entry (&results.back ());          // raw pointer into results
    ...
    core_mapped_file &file_data = *iter->second.file_data;
    file_data.regions.emplace_back (start, end, file_ofs);

Every new distinct filename does another results.emplace_back(), which can
reallocate the vector and leave all previously stored file_data pointers
dangling. When a filename recurs at a later, non-adjacent address (e.g. the
second wayland-shm mapping), file_data is a stale pointer and the
regions.emplace_back writes into freed memory -> heap corruption -> abort when
results is destroyed at the end of build_file_mappings().

The pre-loop callback is already handed the exact mapping count
(pre_loop_cb(count) in linux-tdep.c) but currently ignores it. Reserving
results up front (the number of distinct filenames is at most the mapping
count) prevents the reallocation and fixes the crash:

    --- a/gdb/corelow.c
    +++ b/gdb/corelow.c
    @@ gdb_read_core_file_mappings, pre-loop lambda
    -    [&] (ULONGEST)
    +    [&] (ULONGEST count)
           {
    +        /* Reserve so RESULTS never reallocates while the per-mapping
    +           lambda runs; each map_entry holds a raw core_mapped_file*
    +           into RESULTS that would otherwise dangle on reallocation.  */
    +        results.reserve (count);
           },

With this one-line change the reproducer above and real KDE/Wayland core files
load correctly and produce a proper backtrace.

Comment 1 umut.erdem 2026-07-09 08:04:34 UTC
Created attachment 2148107 [details]
Proposed one-line fix: reserve() in gdb_read_core_file_mappings (corelow.c)

Comment 2 umut.erdem 2026-07-09 08:04:36 UTC
Created attachment 2148108 [details]
Self-contained minimal reproducer (no KDE required)

Comment 3 Andrew Burgess 2026-07-13 14:39:04 UTC

*** This bug has been marked as a duplicate of bug 2498034 ***


Note You need to log in before you can comment on or make changes to this bug.