public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
From: "cvs-commit at gcc dot gnu.org" <sourceware-bugzilla@sourceware.org>
To: gdb-prs@sourceware.org
Subject: [Bug corefiles/25631] GDB cannot access unwritten-to mmap'd buffer from core file
Date: Wed, 22 Jul 2020 19:54:39 +0000	[thread overview]
Message-ID: <bug-25631-4717-bJPs5t4tWS@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-25631-4717@http.sourceware.org/bugzilla/>

https://sourceware.org/bugzilla/show_bug.cgi?id=25631

--- Comment #4 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Kevin Buettner <kevinb@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2735d4218ea81ea83458007a80e4132fa6e73668

commit 2735d4218ea81ea83458007a80e4132fa6e73668
Author: Kevin Buettner <kevinb@redhat.com>
Date:   Wed Mar 4 17:42:42 2020 -0700

    Provide access to non SEC_HAS_CONTENTS core file sections

    Consider the following program:

    - - - mkmmapcore.c - - -

    static char *buf;

    int
    main (int argc, char **argv)
    {
      buf = mmap (NULL, 8192, PROT_READ | PROT_WRITE,
                  MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
      abort ();
    }
    - - - end mkmmapcore.c - - -

    Compile it like this:

    gcc -g -o mkmmapcore mkmmapcore.c

    Now let's run it from GDB.  I've already placed a breakpoint on the
    line with the abort() call and have run to that breakpoint.

    Breakpoint 1, main (argc=1, argv=0x7fffffffd678) at mkmmapcore.c:11
    11        abort ();
    (gdb) x/x buf
    0x7ffff7fcb000: 0x00000000

    Note that we can examine the memory allocated via the call to mmap().

    Now let's try debugging a core file created by running this program.
    Depending on your system, in order to make a core file, you may have to
    run the following as root (or using sudo):

        echo core > /proc/sys/kernel/core_pattern

    It may also be necessary to do:

        ulimit -c unlimited

    I'm using Fedora 31. YMMV if you're using one of the BSDs or some other
    (non-Linux) system.

    This is what things look like when we debug the core file:

        [kev@f31-1 tmp]$ gdb -q ./mkmmapcore core.304767
        Reading symbols from ./mkmmapcore...
        [New LWP 304767]
        Core was generated by `/tmp/mkmmapcore'.
        Program terminated with signal SIGABRT, Aborted.
        #0  __GI_raise (sig=sig@entry=6) at
../sysdeps/unix/sysv/linux/raise.c:50
        50    return ret;
        (gdb) x/x buf
        0x7ffff7fcb000:     Cannot access memory at address 0x7ffff7fcb000

    Note that we can no longer access the memory region allocated by mmap().

    Back in 2007, a hack for GDB was added to _bfd_elf_make_section_from_phdr()
    in bfd/elf.c:

              /* Hack for gdb.  Segments that have not been modified do
                 not have their contents written to a core file, on the
                 assumption that a debugger can find the contents in the
                 executable.  We flag this case by setting the fake
                 section size to zero.  Note that "real" bss sections will
                 always have their contents dumped to the core file.  */
              if (bfd_get_format (abfd) == bfd_core)
                newsect->size = 0;

    You can find the entire patch plus links to other discussion starting
    here:

        https://sourceware.org/ml/binutils/2007-08/msg00047.html

    This hack sets the size of certain BFD sections to 0, which
    effectively causes GDB to ignore them.  I think it's likely that the
    bug described above existed even before this hack was added, but I
    have no easy way to test this now.

    The output from objdump -h shows the result of this hack:

     25 load13        00000000  00007ffff7fcb000  0000000000000000  00013000 
2**12
                      ALLOC

    (The first field, after load13, shows the size of 0.)

    Once the hack is removed, the output from objdump -h shows the correct
    size:

     25 load13        00002000  00007ffff7fcb000  0000000000000000  00013000 
2**12
                      ALLOC

    (This is a digression, but I think it's good that objdump will now show
    the correct size.)

    If we remove the hack from bfd/elf.c, but do nothing to GDB, we'll
    see the following regression:

    FAIL: gdb.base/corefile.exp: print coremaker_ro

    The reason for this is that all sections which have the BFD flag
    SEC_ALLOC set, but for which SEC_HAS_CONTENTS is not set no longer
    have zero size.  Some of these sections have data that can (and should)
    be read from the executable.  (Sections for which SEC_HAS_CONTENTS
    is set should be read from the core file; sections which do not have
    this flag set need to either be read from the executable or, failing
    that, from the core file using whatever BFD decides is the best value
    to present to the user - it uses zeros.)

    At present, due to the way that the target strata are traversed when
    attempting to access memory, the non-SEC_HAS_CONTENTS sections will be
    read as zeroes from the process_stratum (which in this case is the
    core file stratum) without first checking the file stratum, which is
    where the data might actually be found.

    What we should be doing is this:

    - Attempt to access core file data for SEC_HAS_CONTENTS sections.
    - Attempt to access executable file data if the above fails.
    - Attempt to access core file data for non SEC_HAS_CONTENTS sections, if
      both of the above fail.

    This corresponds to the analysis of Daniel Jacobowitz back in 2007
    when the hack was added to BFD:

        https://sourceware.org/legacy-ml/binutils/2007-08/msg00045.html

    The difference, observed by Pedro in his review of my v1 patches, is
    that I'm using "the section flags as proxy for the p_filesz/p_memsz
    checks."

    gdb/ChangeLog:

            PR corefiles/25631
            * corelow.c (core_target:xfer_partial):  Revise
            TARGET_OBJECT_MEMORY case to consider non-SEC_HAS_CONTENTS
            case after first checking the stratum beneath the core
            target.
            (has_all_memory): Return true.
            * target.c (raw_memory_xfer_partial): Revise comment
            regarding use of has_all_memory.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

  parent reply	other threads:[~2020-07-22 19:54 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <bug-25631-4717@http.sourceware.org/bugzilla/>
2020-07-22 19:54 ` cvs-commit at gcc dot gnu.org
2020-07-22 19:54 ` cvs-commit at gcc dot gnu.org [this message]
2020-07-22 19:54 ` cvs-commit at gcc dot gnu.org
2020-07-22 20:20 ` kevinb at redhat dot com
2020-07-22 20:22 ` kevinb at redhat dot com
2020-07-23 14:01 ` tromey at sourceware dot org
2020-09-01  1:55 ` cvs-commit at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-25631-4717-bJPs5t4tWS@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=gdb-prs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).