As requested, I did some gdb:ing.
tmp$ gcc -O2 -g -Wno-unused-result tmp.c -o bushmem
tmp$ gdb bushmem
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bushmem...done.
(gdb) break tmp.c:15
Breakpoint 1 at 0x40066c: file tmp.c, line 15.
(gdb) run
Starting program: /tmp/bushmem
Position:
-2
Value:
3
Breakpoint 1, insert_in_table (val=3, pos=-2) at tmp.c:15
15 table[pos] = val;
(gdb) info symbol table
table in section .bss of /tmp/bushmem
(gdb) info symbol &table[2]
table + 8 in section .bss of /tmp/bushmem
(gdb) info symbol &table[-2]
No symbol matches &table[-2].
(gdb) info proc mappings
process 20372
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x400000 0x401000 0x1000 0x0 /tmp/bushmem
0x600000 0x601000 0x1000 0x0 /tmp/bushmem
0x601000 0x602000 0x1000 0x1000 /tmp/bushmem
0x7ffff7a15000 0x7ffff7bd0000 0x1bb000 0x0 /lib/x86_64-linux-gnu/libc-2.19.so
0x7ffff7bd0000 0x7ffff7dcf000 0x1ff000 0x1bb000 /lib/x86_64-linux-gnu/libc-2.19.so
0x7ffff7dcf000 0x7ffff7dd3000 0x4000 0x1ba000 /lib/x86_64-linux-gnu/libc-2.19.so
0x7ffff7dd3000 0x7ffff7dd5000 0x2000 0x1be000 /lib/x86_64-linux-gnu/libc-2.19.so
0x7ffff7dd5000 0x7ffff7dda000 0x5000 0x0
0x7ffff7dda000 0x7ffff7dfd000 0x23000 0x0 /lib/x86_64-linux-gnu/ld-2.19.so
0x7ffff7fcd000 0x7ffff7fd0000 0x3000 0x0
0x7ffff7ff6000 0x7ffff7ffa000 0x4000 0x0
0x7ffff7ffa000 0x7ffff7ffc000 0x2000 0x0 [vdso]
0x7ffff7ffc000 0x7ffff7ffd000 0x1000 0x22000 /lib/x86_64-linux-gnu/ld-2.19.so
0x7ffff7ffd000 0x7ffff7ffe000 0x1000 0x23000 /lib/x86_64-linux-gnu/ld-2.19.so
0x7ffff7ffe000 0x7ffff7fff000 0x1000 0x0
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall]
(gdb) p/x &table[0]
$2 = 0x601080
(gdb) info symbol 0x601080
table in section .bss of /tmp/bushmem
(gdb) info symbol 0x601084
table + 4 in section .bss of /tmp/bushmem
(gdb) x/32 &table[-16]
0x601040: 0x00000000 0x00000000 0x00000000 0x00000000
0x601050: 0x00000000 0x00000000 0x00000000 0x00000000
0x601060 <completed.6973>: 0x00000000 0x00000000 0x00000000 0x00000000
0x601070: 0x00000000 0x00000000 0x00000000 0x00000000
0x601080 <table>: 0x00000000 0x00000000 0x00000000 0x00000000
0x601090 <table+16>: 0x00000000 0x00000000 0x00000000 0x00000000
0x6010a0 <table+32>: 0x00000000 0x00000000 0x00000000 0x00000000
0x6010b0 <table+48>: 0x00000000 0x00000000 0x00000000 0x00000000
You can use help <cmd>
in gdb to learn more about each command.
Okay, so what I did, in order:
- Set a breakpoint at the table-writing line. GDB will stop the program every time we reach this line.
- When we got there, I demonstrate the use of
info symbol <addr>
.
- In my case, there was no symbol match for &table[-2] -- but remember that I couldn't reproduce, so your case may be different.
info proc mappings
shows the virtual memory map of the program.
p/x
simple prints a value in hex -- here, we print the address of table[0]
, which turns out to be at 0x601080
. Note that this is in the third memory area, which started at 0x601000
.
- And as you can see,
info symbol 0x601080
tells us that this address belongs to the table
symbol. And 4 bytes later is table+4
, as expected.
- Finally, we print some memory contents, starting a bit before
table
. In my case, these were all zeroes -- in your case, they may have different values (or they may be zero, but that value was important for something).
After this, you should be able to run the continue
command, and gdb should catch where the crash happens for you. Use the bt
command to see where it happened. But the location of the crash is probably not the same as the location where your modified memory was read (and hence where things really started to go wrong).
If you want, you could try the rwatch
command in gdb. Setting it on &table[-2]
should make gdb stop when someone reads that memory, which may help you figure out what code is responsible for that. And maybe what it was used for.