2011-10-18 31 views
5

Tôi đang cố gắng can thiệp vào malloc/free/calloc/realloc v.v. với một số interposers qua LD_PRELOAD. Trong thử nghiệm nhỏ của tôi, chỉ có malloc dường như bị xen kẽ, mặc dù phát hiện free (xem đầu ra).LD_PRELOAD chỉ hoạt động đối với malloc, không miễn phí

Tôi mong đợi đầu ra chứa dòng "NANO: free (x)" - nhưng dòng này bị thiếu.

Với

// compile with: gcc test.cc 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char* argv[]) { 

    void* p = malloc(123); 
    printf("HOST p=%p\n", p); 
    free(p); 
} 

// compile with: g++ -O2 -Wall -fPIC -ldl -o libnano.so -shared main.cc 
#include <stdio.h> 
#include <dlfcn.h> 

typedef void *(*MallocFunc)(size_t size); 
typedef void (*FreeFunc)(void*); 

// Original functions 
static MallocFunc real_malloc = NULL; 
static FreeFunc real_free = NULL; 

static void __nano_init(void) { 
    // Override original functions 
    real_malloc = (MallocFunc)dlsym(RTLD_NEXT, "malloc"); 
    if (NULL == real_malloc) { 
     fprintf(stderr, "Error in `dlsym`: %s\n", dlerror()); 
    } else { 
     fprintf(stderr, "NANO: malloc() replaced @%p\n", real_malloc); 
    } 

    real_free = (FreeFunc)dlsym(RTLD_NEXT, "free"); 
    if (NULL == real_free) { 
     fprintf(stderr, "Error in `dlsym`: %s\n", dlerror()); 
    } else { 
     fprintf(stderr, "NANO: free() replaced @%p\n", real_free); 
    } 
} 

// replacement functions 
void *malloc(size_t size) { 
    if(real_malloc==NULL) __nano_init(); 

    void *p = NULL; 
    fprintf(stderr, "NANO: malloc(%lu) = ", size); 
    p = real_malloc(size); 
    fprintf(stderr, "%p\n", p); 

    return p; 
} 

void free(void* ptr) { 
    if(real_free==NULL) __nano_init(); 

    fprintf(stderr, "NANO: free(%p)\n", ptr); 
    real_free(ptr); 

    return; 
} 

Sản lượng thực tế là:

% ./a.out 
NANO: malloc() replaced @0x3b36274dc0 
NANO: free() replaced @0x3b36272870 
NANO: malloc(123) = 0x601010 
HOST p=0x601010 

Trả lời

9

Bạn đang soạn thảo một C++; điều này có nghĩa rằng (theo mặc định) chức năng được đặt tên-mangled để phù hợp với C + + ABI. Thật không may, các hàm bạn đang cố gắng móc là không phải là bị xé tên, vì vậy bạn sẽ kết thúc việc nhập sai hàm (không tồn tại).

Khắc phục là hoặc a) xác định trình bao bọc của bạn trong khối extern "C" { } hoặc a) đảm bảo bạn bao gồm tiêu đề cho hàm - như trong #include <cstdlib>. Thao tác này sẽ lấy các khai báo cho mallocfree bằng một trình bao bọc extern "C", yêu cầu trình biên dịch không được đặt tên mangle.

Lý do malloc công trình có lẽ là bởi vì <stdio.h> hay <dlfcn.h> kéo trong một tuyên bố cho mallocnhưng khôngfree. Do đó, malloc không bị giật, nhưng free bị xáo trộn.

Cũng lưu ý: Nếu bạn đang sử dụng glibc, bạn nên sử dụng malloc hooks để treo chức năng cấp phát bộ nhớ. glibc làm một số công cụ khá kỳ lạ với phiên bản biểu tượng có thể can thiệp với móc của bạn nếu không. Một ví dụ về cách sử dụng nó trong tài liệu được liên kết - đừng quên extern "C" nếu bạn đang sử dụng C++!

+0

Mang tên mang xoài. Tại chỗ trên. Nó chỉ ra rằng tất cả các ví dụ tôi đã sử dụng trong đó C/gcc. Tôi nên nhận ra khi tôi đi đến g ++. Cảm ơn mẹo - bây giờ tôi muốn đánh giá kỹ thuật LD_PRELOAD thẳng. Tôi không chắc chắn về bất kỳ lợi thế của móc malloc. – Justicle

+0

@bdonian nếu bạn là trò chơi tôi có câu hỏi tiếp theo tại đây: http://stackoverflow.com/questions/7910666/problems-with-ld-preload-and-calloc-interposition-for-certain-executables – Justicle

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