Please see test.c.
Running make testdbg executes the program in gdb.
The test runs 7 iterations, each iteration allocating a total of 1 GB, writing a few bytes to it, and then deallocating it.
Breakpoints at lines 12, 29 and 32.
Test platform Termux Linux 4.19.157 aarch64 Android.
- at line 12:
sbrk(0)=0x555555a000 - at line 29:
sbrk(0)=0x559555a0e0 - at line 32:
sbrk(0)=0x559555a0e0
- at line 12:
sbrk(0)=0x555555a000 - at line 29:
sbrk(0)=0x559555a0e0 - at line 32:
sbrk(0)=0x559555a0e0
Similar to 1st iteration
Difference in sbrk(0) in same iteration b/w lines 29 and 12 = 0x559555a0e0 - 0x555555a000 = 1 GB.
This indicates the allocator is properly allocating blocks.
Difference in sbrk(0) in same iteration b/w lines 32 and 29 = 0x559555a0e0 - 0x559555a0e0 = 0 B.
This indicates allocator is not updating brk unless the last allocated block is freed.
Difference in sbrk(0) b/w two iterations at line 12 of each iteration = 0x555555a000 - 0x555555a000 = 0 B.
This indicates the allocator is properly deallocating blocks.
Difference in sbrk(0) before and after run = 0 B.
Hence, allocator is functioning as expected.
On testing in a Linux 5.10.147+ x86_64, difference in sbrk(0) before and after run = 132 KB
It was observed that this allocation happened before the first call to xmalloc.
Most likely this was allocated by libc as printf uses malloc and that in turn uses sbrk (see Test (no malloc) Results).
- Address of
sbrk(0)before run =0x555555559000 - Address of 1st allocation of 0th iteration =
0x55555557a000 - Difference =
0x55555557a000-0x555555559000=132 KB
We still can conclude that deallocation is successful by inspecting pointers in gdb.
Please see test-fail.c. This test is designed to fail.
Running make test-fail-dbg executes the program in gdb.
brk init = 0x555555b000
libxalloc: aborted: buffer at '0x555559b050' overflowed
Program received signal SIGABRT, Aborted
The address 0x555559b050 is the address of the variable s1 (see test-fail.c:18).
It can be checked by running p s1 at frame of main from gdb.
Looking at the code at test-fail.c:23, note that we are indeed overflowing the buffer of s1 by 1 B.
As a result, memory is corrupted, and xmalloc at test-fail.c:26 fails.
Please see test-no-malloc.c.
Running make test-no-malloc-dbg executes the program in gdb.
The idea is to modify test.c, replacing *alloc and free functions of libc with custom overrides.
This is to prevent libc allocators from interfering with libxalloc.
The custom overrides provide the allocation dump.
It is observed that the difference in sbrk(0) at the end of execution is 0 B.
- First
48 B,8 Band48 Ballocations are not byprintf. - First
48 Ballocation causes allocator initialization (see Allocator Initialization). - Calling
malloc(0)(seetest-no-malloc.c:105) doesn't do anything in this case. - Brk init is calculated at this point, before 1st
printf. - Brk init is the ending address of initial
128 KB+40 Bbloc. - First
printfcauses allocation of1024 B. - After every print,
printfcallsfree(NULL)for some reason. printfnever frees the initial1024 B.- Brk exit is calculated before 2nd last
printf. - In the end, difference in
sbrk(0)is0 B. - Initial
128 KB+40 Bbloc is never freed.
- First
48 B,8 Band48 Ballocations never happen. - So,
malloc(0)causes allocator initialization in this case. - Otherwise, brk init will end up
128 KB+40 Bahead of brk end. - Brk init is calculated at this point, before 1st
printf. - Brk init is the ending address of initial
128 KB+40 Bbloc. - First
printfcauses allocation of1024 B. printfnever callsfree(NULL).printfnever frees the initial1024 B.- Brk exit is calculated before 2nd last
printf. - In the end, difference in
sbrk(0)is0 B. - Initial
128 KB+40 Bbloc is never freed.
- First
printfallocates1024 B. libxallocallocates128 KB+40 Bto reduce syscalls.printfnever frees the1024 B.- Extra occupied space at exit =
128 KB+40 B. - This occupied space can be inspected via
gdb.
1 GB=1073741824 B256 MB=268435456 B
Dump of make test-no-malloc-dbg.
Indented stuff is by the allocator, unindented stuff is by printf.
malloc: ptr = '0x555555b640', size = 48 B
malloc: ptr = '0x555555bcb0', size = 8 B
malloc: ptr = '0x555555c2f8', size = 48 B
malloc: ptr = '0x00', size = 0 B
malloc: ptr = '0x555555c968', size = 1024 B
brk init = 0x555557b028
free: ptr = '0x00', size = 0 B, freed = 0 B
malloc: ptr = '0x555557b668', size = 268435456 B
malloc: ptr = '0x556557b690', size = 268435456 B
malloc: ptr = '0x557557b6b8', size = 268435456 B
malloc: ptr = '0x558557b6e0', size = 268435456 B
0: abcdefghijklmnopqrstuvwxyz
free: ptr = '0x00', size = 0 B, freed = 0 B
free: ptr = '0x555557b668', size = 268435456 B, freed = 0 B
free: ptr = '0x556557b690', size = 268435456 B, freed = 0 B
free: ptr = '0x557557b6b8', size = 268435456 B, freed = 0 B
free: ptr = '0x558557b6e0', size = 268435456 B, freed = 1073741824 B
malloc: ptr = '0x555557b668', size = 268435456 B
malloc: ptr = '0x556557b690', size = 268435456 B
malloc: ptr = '0x557557b6b8', size = 268435456 B
malloc: ptr = '0x558557b6e0', size = 268435456 B
1: abcdefghijklmnopqrstuvwxyz
free: ptr = '0x00', size = 0 B, freed = 0 B
free: ptr = '0x555557b668', size = 268435456 B, freed = 0 B
free: ptr = '0x556557b690', size = 268435456 B, freed = 0 B
free: ptr = '0x557557b6b8', size = 268435456 B, freed = 0 B
free: ptr = '0x558557b6e0', size = 268435456 B, freed = 1073741824 B
malloc: ptr = '0x555557b668', size = 268435456 B
malloc: ptr = '0x556557b690', size = 268435456 B
malloc: ptr = '0x557557b6b8', size = 268435456 B
malloc: ptr = '0x558557b6e0', size = 268435456 B
2: abcdefghijklmnopqrstuvwxyz
free: ptr = '0x00', size = 0 B, freed = 0 B
free: ptr = '0x555557b668', size = 268435456 B, freed = 0 B
free: ptr = '0x556557b690', size = 268435456 B, freed = 0 B
free: ptr = '0x557557b6b8', size = 268435456 B, freed = 0 B
free: ptr = '0x558557b6e0', size = 268435456 B, freed = 1073741824 B
malloc: ptr = '0x555557b668', size = 268435456 B
malloc: ptr = '0x556557b690', size = 268435456 B
malloc: ptr = '0x557557b6b8', size = 268435456 B
malloc: ptr = '0x558557b6e0', size = 268435456 B
3: abcdefghijklmnopqrstuvwxyz
free: ptr = '0x00', size = 0 B, freed = 0 B
free: ptr = '0x555557b668', size = 268435456 B, freed = 0 B
free: ptr = '0x556557b690', size = 268435456 B, freed = 0 B
free: ptr = '0x557557b6b8', size = 268435456 B, freed = 0 B
free: ptr = '0x558557b6e0', size = 268435456 B, freed = 1073741824 B
malloc: ptr = '0x555557b668', size = 268435456 B
malloc: ptr = '0x556557b690', size = 268435456 B
malloc: ptr = '0x557557b6b8', size = 268435456 B
malloc: ptr = '0x558557b6e0', size = 268435456 B
4: abcdefghijklmnopqrstuvwxyz
free: ptr = '0x00', size = 0 B, freed = 0 B
free: ptr = '0x555557b668', size = 268435456 B, freed = 0 B
free: ptr = '0x556557b690', size = 268435456 B, freed = 0 B
free: ptr = '0x557557b6b8', size = 268435456 B, freed = 0 B
free: ptr = '0x558557b6e0', size = 268435456 B, freed = 1073741824 B
malloc: ptr = '0x555557b668', size = 268435456 B
malloc: ptr = '0x556557b690', size = 268435456 B
malloc: ptr = '0x557557b6b8', size = 268435456 B
malloc: ptr = '0x558557b6e0', size = 268435456 B
5: abcdefghijklmnopqrstuvwxyz
free: ptr = '0x00', size = 0 B, freed = 0 B
free: ptr = '0x555557b668', size = 268435456 B, freed = 0 B
free: ptr = '0x556557b690', size = 268435456 B, freed = 0 B
free: ptr = '0x557557b6b8', size = 268435456 B, freed = 0 B
free: ptr = '0x558557b6e0', size = 268435456 B, freed = 1073741824 B
malloc: ptr = '0x555557b668', size = 268435456 B
malloc: ptr = '0x556557b690', size = 268435456 B
malloc: ptr = '0x557557b6b8', size = 268435456 B
malloc: ptr = '0x558557b6e0', size = 268435456 B
6: abcdefghijklmnopqrstuvwxyz
free: ptr = '0x00', size = 0 B, freed = 0 B
free: ptr = '0x555557b668', size = 268435456 B, freed = 0 B
free: ptr = '0x556557b690', size = 268435456 B, freed = 0 B
free: ptr = '0x557557b6b8', size = 268435456 B, freed = 0 B
free: ptr = '0x558557b6e0', size = 268435456 B, freed = 1073741824 B
brk exit = 0x555557b028
free: ptr = '0x00', size = 0 B, freed = 0 B
brk difference = 0 B
free: ptr = '0x00', size = 0 B, freed = 0 B