2012-11-21 40 views
6

Có một trình quản lý bộ nhớ tùy chỉnh trong chương trình của chúng tôi, tất cả cuộc gọi/cuộc gọi miễn phí của chúng tôi được quản lý bởi bộ quản lý bộ nhớ, nhưng ban đầu của chương trình getpwuid() sẽ được gọi và trong một số máy của khách hàng với nss_ldap kích hoạt nó sẽ gọi malloc từ libc không từ người quản lý bộ nhớ của chúng tôi mà dẫn đến sai sót trong quản lý bộ nhớ của chúng tôi, báo cáo chồng từ gdb là:Quản lý bộ nhớ tùy chỉnh với bộ nhớ cục bộ tùy chỉnh

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 [email protected]@GLIBC_2.2.5() from /lib64/libc.so.6 
11 0x0000003df8c9412f in getpwuid() from /lib64/libc.so.6 
12 0x0000000001414be3 in lc_username() 

tôi đã bắt nguồn từ mã của _nss_ldap_inc_depth(), có vẻ như __tls_get_addr() nhận cuộc gọi vì lưu trữ cục bộ luồng được sử dụng, tôi đã cố gắng thay đổi trình quản lý bộ nhớ thành thư viện được chia sẻ nhưng hàm __tls_get_addr() vẫn gọi malloc từ libc, làm cách nào để gọi nó quản lý bộ nhớ thay vì libc's ??

+2

không khôi phục các chỉnh sửa :) – iabdalkader

+0

có vẻ như vấn đề bắt nguồn từ 'lc_username()' bạn có thể đăng mã đó không? – iabdalkader

+0

Tôi nghĩ rằng đó không phải là vì lc_username(), tôi đã thực hiện một cuộc gọi trực tiếp đến getpwuid() và nhận được kết quả tương tự. – DreamLinuxer

Trả lời

2

Bạn có thể sử dụng LD_PRELOAD để tải thư viện của bạn trước khi bất kỳ thư viện khác (bao gồm glibc) và nó sẽ được liên kết thay vào đó, một cái gì đó như:

$ LD_PRELOAD=/path/to/library/libmymalloc.so /bin/myprog 

Có một hướng dẫn here cho thấy cách thức hoạt động, nó thậm chí có ví dụ xen kẽ malloc

+0

Tôi đã thử LD_PRELOAD nhưng nó vẫn gọi malloc từ libc :( – DreamLinuxer

+0

Tôi nghĩ rằng lý do nó không hoạt động là beacuse của __tls_get_addr() – DreamLinuxer

+0

@DreamLinuxer như một lưu ý phụ, bạn không nên gọi 'getpwuid () 'bạn nên sử dụng phiên bản entrant enten 'getpwuid_r()' – iabdalkader

0

Bạn có thể thay đổi trình quản lý bộ nhớ của mình để sử dụng mmap instread of brk.

Chỉ có thể có một người dùng là brk trong một quy trình. Vì vậy, nếu bạn chưa thay thế tất cả các cuộc gọi đến malloc và các chức năng liên quan (calloc, strdup và hơn thế nữa), bạn không được sử dụng brk.

mmap, tuy nhiên, không có vấn đề như vậy. Trình quản lý bộ nhớ của bạn có thể sử dụng mmapmalloc vẫn có thể hoạt động song song.

+0

Trình quản lý bộ nhớ là mã kế thừa, tôi thực sự không muốn sửa đổi nó. Tôi muốn giải quyết vấn đề này bằng cách thay thế malloc trong __tls_get_addr() – DreamLinuxer

+0

Tôi không nghĩ rằng việc thay thế các cuộc gọi 'malloc' từng là một ý tưởng hay - bạn sẽ tiếp tục tìm kiếm những cái mới. (rất nhiều gói phần mềm, chẳng hạn như Valgrind, làm điều đó) – ugoren

+0

Nó chạy tốt trong valgrind có nghĩa là cuộc gọi malloc được thay thế một cách chính xác theo valgrind @@ " – DreamLinuxer

Các vấn đề liên quan