I have Debian with the Linux 2.6 kernel and am trying to understand how the heap works / behaves with malloc()
and free()
. I tried to find the malloc()
and free()
algorithm and the heap structure, but I could not find anything useful. And, unfortunately, I know too little about Linux and how memory works to understand the source code of free()
and malloc()
.
This is a sample code:
int main(int argc, char **argv) { char *a, *b, *c; a = malloc(32); b = malloc(32); c = malloc(32); strcpy(a, argv[1]); strcpy(b, argv[2]); strcpy(c, argv[3]); free(c); free(b); free(a); }
With gdb
and run AAAA BBBB CCCC
I can check a bunch. This is the state after strcpys
, but before frees
:
(gdb) x/32x 0x804c000 0x804c000: 0x00000000 0x00000029 0x41414141 0x00000000 0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029 0x804c030: 0x42424242 0x00000000 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000029 0x43434343 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
Char arrays can be seen very well. Then I tried to find out why 0x29 (dec 41) exists. I would expect something like 0x20 (dec 32) or 0x24 (dec 36).
- Why does the malloc algorithm spend this space?
- How was the decision made that it was 0x29?
- And what does 0xf89 mean at the end?
- How does the program track what is allocated and what is free?
In particular, I want to understand how free()
works. After three releases, the heap looks like this:
(gdb) x/32x 0x804c000 0x804c000: 0x00000000 0x00000029 0x0804c028 0x00000000 0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029 0x804c030: 0x0804c050 0x00000000 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
- Why is the char array replaced with this specific address?
- What is a pseudo code that does for free?
Take a look at this example:
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDDDD BBBB CCCC ... (gdb) x/32x 0x804c000 0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141 0x804c010: 0x41414141 0x41414141 0x41414141 0x41414141 0x804c020: 0x41414141 0x41414141 0x44444444 0x00000044 0x804c030: 0x42424242 0x00000000 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000029 0x43434343 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89 ... (gdb) c Program exited with code 021.
I overwrote 0x29, but the program completed normally. But when I add another byte, I encounter a segmentation error:
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDDDD BBBB CCCC ... (gdb) x/32x 0x804c000 0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141 0x804c010: 0x41414141 0x41414141 0x41414141 0x41414141 0x804c020: 0x41414141 0x41414141 0x44444444 0x00004444 0x804c030: 0x42424242 0x00000000 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000029 0x43434343 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89 ... (gdb) c Program received signal SIGSEGV, Segmentation fault. 0x080498b9 in free (mem=0x804c030) at common/malloc.c:3631
The most important question for me:
- Why do you get a segmentation error in
free()
when overwriting more bytes? - and how does the
free()
algorithm work? - and how to make malloc and track addresses for free?
Thanks so much for reading, good wishes