This is the mail archive of the gdb-prs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug server/20414] x32 gdbserver always crashes inferior


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

--- Comment #2 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Pedro Alves <palves@sourceware.org>:

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

commit 6598661d14c90cabac1daa5e683d1e17883b2e41
Author: Pedro Alves <palves@redhat.com>
Date:   Tue Jul 26 22:21:27 2016 +0100

    Fix PR server/20414 - x32 gdbserver always crashes inferior

    Debugging an x32 process with an x32 gdbserver always results in:

     (gdb) c
     Continuing.

     Program received signal SIGSEGV, Segmentation fault.
     0xf7de9600 in _dl_debug_state () from target:/libx32/ld-linux-x32.so.2
     (gdb)

    Looking at the remote debug logs reveals the problem, here:

      Packet received:
T05swbreak:;06:a0d4ffff00000000;07:b8d3ffff00000000;10:0096def701000000;thread:p7d7a.7d7a;core:1;
                                                                             
^^^^^^^^^^^^^^^^

    The underlined value is the expedited value of RIP (in little endian).
    But notice that 01 in 0x01f7de9600, while gdb says the program stopped
    at 0xf7de9600.  0x01ffffffff is over 32 bits, which indicates that
    something wen't wrong somewhere in gdbserver.

    The problem turns out to be in gdbserver's x86_get_pc / x86_set_pc
    routines, where "unsigned long" is used assuming that it can fit a
    64-bit value, while unsigned long is actually 32-bit on x32.  The
    result is that collect_register_by_name / supply_register_by_name end
    up reading/writing random bytes off the stack.

    Fix this by using explicit uint64_t instead of unsigned long.
    For consistency, use uint32_t instead of unsigned int in the 32-bit
    paths.

    gdb/gdbserver/ChangeLog:
    2016-07-26  Pedro Alves  <palves@redhat.com>

        PR server/20414
        * linux-x86-low.c (x86_get_pc, x86_set_pc): Use uint64_t instead
        of unsigned long for 64-bit registers and use uint32_t instead of
        unsigned int for 32-bit registers.

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]