I want to find out the base address and the imagesize of the program being debugged in gdb. As in, where it got loaded in memory. For shared libraries I can do "info sharedlibrary" and I get very nice output like so:

0x00007ffff7dd5f10  0x00007ffff7df4b20  Yes         /lib64/ld-linux-x86-64.so.2

How can i get this output for the main program i am debugging?

I know that gdb disables ASLR and I could just inspect the ELF file myself to find out, but there has to be a way via gdb too.

(Background: I am using gdb's mi, and I can keep a basic overview of where things are by parsing sharedlibrary-load messages. But it never sends such a message for the main program, which is the most important thing.)

Thanks!

  • 2
    pmap -x [pid] ( linux.die.net/man/1/pmap ) from the command line may probably help you without gdb – w s Oct 11 at 12:53
  • There is also the command info proc mappings <pid> – bernd feinman Oct 17 at 16:05
up vote 3 down vote accepted

You can do the following:

  • info inferior or print getpid() gives you a process id
  • shell pmap -x {the process id} gives you a memory map of the process (it is not functionality of gdb, pmap is other shell command, but it is a bit better then analyzing ELF)
  • You can also use shell cat /proc/{pid}/maps file (as far as I understand pmap just parses and prints its content)

You'll see something like this(it's a result of a process named opt which I am debugging just now):

6648:   /home/ubuntu/llvm-5.0.1.src/build/bin/opt
Address           Kbytes     RSS   Dirty Mode  Mapping
0000000000400000  100524   36380       8 r-x-- opt
0000000000400000       0       0       0 r-x-- opt
000000000682a000    4176     356     296 r---- opt
000000000682a000       0       0       0 r---- opt
0000000006c3e000     628      76      76 rw--- opt
0000000006c3e000       0       0       0 rw--- opt
0000000006cdb000     684     480     480 rw---   [ anon ]
0000000006cdb000       0       0       0 rw---   [ anon ]
00007ffff6908000    1792    1056       8 r-x-- libc-2.23.so
00007ffff6908000       0       0       0 r-x-- libc-2.23.so
00007ffff6ac8000    2048       0       0 ----- libc-2.23.so
00007ffff6ac8000       0       0       0 ----- libc-2.23.so
00007ffff6cc8000      16      16      16 r---- libc-2.23.so
00007ffff6cc8000       0       0       0 r---- libc-2.23.so
00007ffff6ccc000       8       8       8 rw--- libc-2.23.so
00007ffff6ccc000       0       0       0 rw--- libc-2.23.so
00007ffff6cce000      16      12      12 rw---   [ anon ]
00007ffff6cce000       0       0       0 rw---   [ anon ]
...
...

If I understand your question correctly the line

  0000000000400000  100524   36380       8 r-x-- opt

is what you need.

  • Thanks. I get that gdb isnt a rce tool, but it really bothers me that basic stuff like finding where your target is loaded in memory is so hard to come by. Another example is the starti command thatwas only added very recently. Anyways, thanks for solving this. – bernd feinman Oct 11 at 21:05

info file shows the memory map of the current process:

Local exec file:
        `/bin/less', file type elf64-x86-64.
        Entry point: 0x402080
        0x0000000000400238 - 0x0000000000400254 is .interp
        0x0000000000400254 - 0x0000000000400274 is .note.ABI-tag
        0x0000000000400274 - 0x0000000000400298 is .note.gnu.build-id
        0x0000000000400298 - 0x00000000004002e0 is .gnu.hash
        0x00000000004002e0 - 0x0000000000400b20 is .dynsym
        0x0000000000400b20 - 0x0000000000400e7d is .dynstr
        0x0000000000400e7e - 0x0000000000400f2e is .gnu.version
        0x0000000000400f30 - 0x0000000000400fa0 is .gnu.version_r
        0x0000000000400fa0 - 0x0000000000401000 is .rela.dyn
        0x0000000000401000 - 0x0000000000401708 is .rela.plt
        0x0000000000401708 - 0x0000000000401722 is .init
        0x0000000000401730 - 0x0000000000401bf0 is .plt
        0x0000000000401bf0 - 0x0000000000415824 is .text
        0x0000000000415824 - 0x000000000041582d is .fini
        0x0000000000415840 - 0x000000000041bd67 is .rodata
        0x000000000041bd68 - 0x000000000041c90c is .eh_frame_hdr
        0x000000000041c910 - 0x00000000004208e4 is .eh_frame
        0x0000000000620e00 - 0x0000000000620e08 is .init_array
        0x0000000000620e08 - 0x0000000000620e10 is .fini_array
        0x0000000000620e10 - 0x0000000000620e18 is .jcr
        0x0000000000620e18 - 0x0000000000620ff8 is .dynamic
        0x0000000000620ff8 - 0x0000000000621000 is .got
        0x0000000000621000 - 0x0000000000621270 is .got.plt
        0x0000000000621280 - 0x000000000062500c is .data
        0x00007fffff4001c8 - 0x00007fffff4001ec is .note.gnu.build-id in /lib64/ld-linux-x86-64.so.2
        0x00007fffff4001f0 - 0x00007fffff4002ac is .hash in /lib64/ld-linux-x86-64.so.2
        0x00007fffff4002b0 - 0x00007fffff40038c is .gnu.hash in /lib64/ld-linux-x86-64.so.2
        0x00007fffff400390 - 0x00007fffff400630 is .dynsym in /lib64/ld-linux-x86-64.so.2

Lines without a filename at the end are those for the main executable.

  • Thanks! In my specific case i need the segments, not sections, so I would have to do sketchy rounding using that info only .... but it seems this is as good as it gets with raw gdb. – bernd feinman Oct 11 at 21:06

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.