Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using gdb and gdbserver with a 32 bit binary on a 64 bit machine with Centos 5 complains about memory access or badly formatted data

I have two identical 64 bit Centos 5 machines, that are networked, and share their /home mount. I compile a simple Hello World program on one, and then I have figured out how to use gdb on one machine to remotely debug it running on the other machine. That seems to work fine when everyone defaults to 64 bitness.

However, if I compile my Hello World with -m32 to generate a 32 bit binary, the way our full up system is being compiled, then I cannot figure out how to get gdb and gdbserver to correctly connect. Before I try it on our full up system, I figure I should get it working with hello. Depending on how I try connecting gdb and gdbserver, I either get messages about badly formatted registers, warnings about architecture mismatches, or illegal memory references.

I seem to have little understanding of what the implications of -m32 are in my compile and no idea of how to start gdb and gdbserver or the right order to specify architecture or files or something. :(

What does it take to use gdb and gdbserver on a 32 bit (-m32) executable on a 64 bit linux box?

Examples below, and thank you,

Jerry

hello.cpp:

#include <iostream>
int main(int argc, char *argv[])
{
    std::cout << "Hello World." << std::endl;
    return -1;

}

Here are three runs:

  1. In gdb, set architecture i386 / then connect to gdbserver => bad architecture
  2. In gdb, set architecture i386 / file hello / then connect to gdbserver => bad architecture
  3. In gdb, set architecture (incorrectly) i386:x86-64 / file hello / then connect to gdbserver => Cannot access memory

Or in a bit more detail:

==============================

For each run, the remote gdbserver said:


    $ gdbserver --multi rdev6:2010 hello
    Process hello created; pid = 32603
    Listening on port 2010
    Remote debugging from host 134.51.26.149
    readchar: Got EOF
    Remote side has terminated connection.  GDBserver will reopen the connection.
    Listening on port 2010

And on our local:

==============================

  • Assuming it is i386 32 bit, setting archi to i386, then connecting note: on the gdb side, the executable hasn't been specified or loaded

    $ gdb
    GNU gdb Fedora (6.8-37.el5)
    his GDB was configured as "x86_64-redhat-linux-gnu".
    (gdb) set archi i386
    The target architecture is assumed to be i386
    (gdb) target extended-remote rdev6:2010
    Remote debugging using rdev6:2010
    warning: Selected architecture i386 is not compatible with reported target architecture i386:x86-64
    Remote register badly formatted: T0506:0000000000000000;07:b0dcdfff00000000;10:1018620000000000;thread:7f5b;
    here: 0000000;07:b0dcdfff00000000;10:1018620000000000;thread:7f5b;
    Try to load the executable by `file' first,
    you may also check `set/show architecture'.
    (gdb)

==============================

  • Assuming it is i386 32 bit, setting archi to i386, then connecting note: on the gdb side, the executable has been loaded with file

    $ gdb
    GNU gdb Fedora (6.8-37.el5)
    his GDB was configured as "x86_64-redhat-linux-gnu".
    (gdb) set archi i386
    The target architecture is assumed to be i386
    (gdb) file hello
    Reading symbols from /home/j/hello...done.
    (gdb) target extended-remote rdev6:2010
    Remote debugging using rdev6:2010
    warning: Selected architecture i386 is not compatible with reported target architecture i386:x86-64
    Remote register badly formatted: T0506:0000000000000000;07:b0dcdfff00000000;10:1018620000000000;thread:7f5b;
    here: 0000000;07:b0dcdfff00000000;10:1018620000000000;thread:7f5b;
    Try to load the executable by `file' first,
    you may also check `set/show architecture'.
    (gdb) sho archi
    The target architecture is assumed to be i386
    (gdb)

==============================

  • Assuming (which should be incorrect) that it is i386:x86-64, setting archi to i386:x86-64, then connecting note: on the gdb side, the executable has been loaded with file

    $ gdb
    GNU gdb Fedora (6.8-37.el5)
    This GDB was configured as "x86_64-redhat-linux-gnu".
    (gdb) set archi i386:x86-64
    The target architecture is assumed to be i386:x86-64
    (gdb) file hello
    Reading symbols from /home/j/hello...done.
    (gdb) show archi
    The target architecture is assumed to be i386:x86-64
    (gdb) target extended-remote rdev6:2010
    Remote debugging using rdev6:2010
    [New Thread 32667]
    Cannot access memory at address 0x800000008
    (gdb)
like image 772
Jerry Asher Avatar asked Jun 18 '10 22:06

Jerry Asher


1 Answers

If you want to debug 32-bit process using 64-bit gdb/gdbserver, you need a newer version of GDB. In particular, you need this:

gdbserver/ChangeLog:

2009-05-12  Doug Evans  <[email protected]>

        Biarch support for i386/amd64 gdbserver.

Alternatively, you can build gdb/gdbserver you already have from source in 32-bit mode by running

./configure CC='gcc -m32'

and use gdb32/gdbserver32 to debug your processes. I don't see any advantage of doing this though -- newer versions of GDB have many fixes, speedups, and STL pretty printers are nice.

like image 195
Employed Russian Avatar answered Sep 29 '22 11:09

Employed Russian