To verify that your malloc()
function overrides the sibling one in the C library and is called by printf()
, you can log a trace on the terminal (file descriptor number 1) by calling write()
system call:
#include <stdio.h>
#include <unistd.h>
void *malloc(size_t s) {
write(1, "I am called\n", sizeof("I am called\n") - 1);
};
int main() {
printf("lol");
}
After compilation, the programs displays:
$ gcc -g overm.c -o overm
$ ./overm
I am called
Segmentation fault (core dumped)
The analysis of the generated core dump file with a debugger like gdb
shows the state of the call stack at the time of the crash:
$ gdb overm core
[...]
Reading symbols from overm...
[New LWP 8494]
Core was generated by `./overm'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007fd4bf7d6dc8 in _IO_new_file_overflow (f=0x7fd4bf9336a0 <_IO_2_1_stdout_>, ch=108) at fileops.c:781
781 fileops.c: No such file or directory.
(gdb) where
#0 0x00007fd4bf7d6dc8 in _IO_new_file_overflow (f=0x7fd4bf9336a0 <_IO_2_1_stdout_>, ch=108) at fileops.c:781
#1 0x00007fd4bf7d8024 in __GI__IO_default_xsputn (n=<optimized out>, data=<optimized out>, f=<optimized out>) at libioP.h:948
#2 __GI__IO_default_xsputn (f=f@entry=0x7fd4bf9336a0 <_IO_2_1_stdout_>, data=<optimized out>, n=n@entry=3) at genops.c:370
#3 0x00007fd4bf7d56fa in _IO_new_file_xsputn (n=3, data=<optimized out>, f=<optimized out>) at fileops.c:1265
#4 _IO_new_file_xsputn (f=0x7fd4bf9336a0 <_IO_2_1_stdout_>, data=<optimized out>, n=3) at fileops.c:1197
#5 0x00007fd4bf7bc972 in __vfprintf_internal (s=0x7fd4bf9336a0 <_IO_2_1_stdout_>, format=0x5556655db011 "lol", ap=ap@entry=0x7fff657394a0,
mode_flags=mode_flags@entry=0) at ../libio/libioP.h:948
#6 0x00007fd4bf7a7d3f in __printf (format=<optimized out>) at printf.c:33
#7 0x00005556655da1ab in main () at overm.c:8
The above display shows that the crash occured while calling printf()
at line 33 of the source code. Let's set a breakpoint on the printf()
function and rerun the program from the debugger:
(gdb) br printf
Breakpoint 3 at 0x7ffff7e1ac90: file printf.c, line 28.
(gdb) run
Breakpoint 3, __printf (format=0x555555556011 "lol") at printf.c:28
28 printf.c: No such file or directory.
(gdb)
Once we are stopped at the printf()
call, add another breakpoint onto malloc()
function (we didn't do that before because malloc()
is called several times during program startup by internal code) and continue the execution:
(gdb) br malloc
(gdb) continue
Continuing.
Breakpoint 4, malloc (s=140737354002065) at overm.c:4
4 void *malloc(size_t s) {
(gdb) where
#0 malloc (s=140737354002065) at overm.c:4
#1 0x00007ffff7e3ad04 in __GI__IO_file_doallocate (fp=0x7ffff7fa66a0 <_IO_2_1_stdout_>) at filedoalloc.c:101
#2 0x00007ffff7e4aed0 in __GI__IO_doallocbuf (fp=fp@entry=0x7ffff7fa66a0 <_IO_2_1_stdout_>) at libioP.h:948
#3 0x00007ffff7e49f30 in _IO_new_file_overflow (f=0x7ffff7fa66a0 <_IO_2_1_stdout_>, ch=-1) at fileops.c:745
#4 0x00007ffff7e486b5 in _IO_new_file_xsputn (n=3, data=<optimized out>, f=<optimized out>) at libioP.h:948
#5 _IO_new_file_xsputn (f=0x7ffff7fa66a0 <_IO_2_1_stdout_>, data=<optimized out>, n=3) at fileops.c:1197
#6 0x00007ffff7e2f972 in __vfprintf_internal (s=0x7ffff7fa66a0 <_IO_2_1_stdout_>, format=0x555555556011 "lol", ap=ap@entry=0x7fffffffdd90,
mode_flags=mode_flags@entry=0) at ../libio/libioP.h:948
#7 0x00007ffff7e1ad3f in __printf (format=<optimized out>) at printf.c:33
#8 0x00005555555551ab in main () at overm.c:8
(gdb)
The displayed stack when we are stopped at the malloc()
call, shows that it is the result of the printf()
call from line 33 in the source code.