Reputation: 41
When I try to pass --wrap=malloc
to the ld linker for hooking malloc
, I find that getline
will not call __wrap_malloc
, but call glibc's malloc
.
// foo.c
void* __wrap_malloc(size_t sz) {
printf("abc");
return __reall_malloc(sz);
}
int main() {
char *line = NULL;
size_t n = 0;
getline(&line, &n, stdin); // will call malloc
....
}
Run as:
$ gcc foo.c -Wl,--wrap=malloc && ./a.out
It doesn't print "abc", it seems that __wrap_malloc
isn't called.
But run as:
$ gcc -static foo.c -Wl,--wrap=malloc && ./a.out
I got a segment fault, print the backtrace:
#0 0x00000000004490e7 in vfprintf ()
#1 0x0000000000407a76 in printf ()
#2 0x0000000000400ab7 in __wrap_malloc (size=1024) at foo.c:26
#3 0x0000000000456a2b in _IO_file_doallocate ()
#4 0x000000000040d4a5 in _IO_doallocbuf ()
#5 0x000000000040c4d8 in _IO_new_file_overflow ()
#6 0x000000000040b421 in _IO_new_file_xsputn ()
#7 0x000000000044921f in vfprintf ()
#8 0x0000000000407a76 in printf ()
#9 0x0000000000400ab7 in __wrap_malloc (size=1024) at foo.c:26
....
It seems that __wrap_malloc
(called in printf
initally) is called recursively, which means that getline
call __wrap_malloc
instead of glibc's malloc
.
What happened if -static
passed to linker? How can I force getline
call __wrap_malloc
instead of glibc's malloc
?
Upvotes: 4
Views: 150
Reputation: 33717
If -static
is passed to the link editor, the link editor can see all internal calls to malloc
and will try to wrap them, causing the infinite recursion because your own malloc
implementation calls printf
, which in turn calls malloc
in some cases.
Without -static
, the link editor cannot rewrite the internal malloc
references within libc.so.6
, so internal calls in glibc are never redirected. There is no infinite recursion, but you do not see those internal calls, either.
glibc supports replacing malloc
using ELF symbol interposition (as far as such a thing is possible):
You still need to be careful to avoid triggering infinite recursion, though.
Upvotes: 2