我们的程序中有一个自定义内存管理器,我们所有的malloc / free调用都是由内存管理器管理的,但是在程序的初始阶段,getpwuid()将被调用,并且在某些客户的机器上使用nss_ldap激活它将从libc调用malloc而不是从我们的内存管理器调用,这导致我们的内存管理器出错,gdb的堆栈报告是:
Breakpoint 2, 0x0000003df8cc6eb0 in brk () from /lib64/libc.so.6
0 0x0000003df8cc6eb0 in brk () from /lib64/libc.so.6
1 0x0000003df8cc6f72 in sbrk () from /lib64/libc.so.6
2 0x0000003df8c73d29 in __default_morecore () from /lib64/libc.so.6
3 0x0000003df8c70090 in _int_malloc () from /lib64/libc.so.6
4 0x0000003df8c70c9d in malloc () from /lib64/libc.so.6
5 0x0000003df880fc65 in __tls_get_addr () from /lib64/ld-linux-x86-64.so.2
6 0x00002aaaae302a7c in _nss_ldap_inc_depth () from /lib64/libnss_ldap.so.2
7 0x00002aaaae2f91a4 in _nss_ldap_enter () from /lib64/libnss_ldap.so.2
8 0x00002aaaae2f942c in _nss_ldap_getbyname () from /lib64/libnss_ldap.so.2
9 0x00002aaaae2f9aa9 in _nss_ldap_getpwuid_r () from /lib64/libnss_ldap.so.2
10 0x0000003df8c947c5 in getpwuid_r@@GLIBC_2.2.5 () from /lib64/libc.so.6
11 0x0000003df8c9412f in getpwuid () from /lib64/libc.so.6
12 0x0000000001414be3 in lc_username ()
我已经跟踪了_nss_ldap_inc_depth()的代码,似乎__tls_get_addr()得到了调用,因为使用了线程本地存储,我试图将内存管理器更改为共享库,但是__tls_get_addr()仍然调用来自libc的malloc,如何让它调用我们的内存管理器而不是libc?
答案 0 :(得分:2)
您可以使用LD_PRELOAD
在任何其他库(包括glibc)之前加载您的库,它将被链接,例如:
$ LD_PRELOAD=/path/to/library/libmymalloc.so /bin/myprog
有一个教程here,它展示了它是如何工作的,它甚至有一个插入的例子malloc
答案 1 :(得分:0)
您可以更改内存管理器以使用mmap
的{{1}}实例读取。
进程中只能有一个brk
用户。因此,如果您尚未替换所有对brk
和相关功能(malloc
,calloc
等)的调用,则不得使用strdup
。
brk
没有这样的问题。您的记忆管理员可以使用mmap
,mmap
仍然可以并行工作。