Библиотечное взаимодействие
Я пытался перехватить вызовы malloc и free, следуя нашему учебнику (книга CSAPP). Я следовал их точному коду и почти тому же коду, который я нашел в Интернете, и я продолжаю получать ошибку сегментации. Я слышал, как наш профессор говорил что-то о printf, который использует malloc и освобождает память, поэтому я думаю, что это происходит потому, что я перехватываю malloc, и поскольку я использую функцию printf внутри перехватывающей функции, она будет вызывать себя рекурсивно. Однако я не могу найти решение этой проблемы? Наш профессор продемонстрировал, что перехват работает (он не показал нам код) и печатает нашу информацию каждый раз, когда происходит malloc, так что я знаю, что это возможно. Может кто подскажет рабочий метод??
Вот код, который я использовал и ничего не получил:mymalloc.c
#ifdef RUNTIME
// Run-time interposition of malloc and free based on // dynamic linker's (ld-linux.so) LD_PRELOAD mechanism #define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h> #include <dlfcn.h>
void *malloc(size_t size) {
static void *(*mallocp)(size_t size) = NULL; char *error;
void *ptr;
// get address of libc malloc
if (!mallocp) {
mallocp = dlsym(RTLD_NEXT, "malloc"); if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(EXIT_FAILURE);
}
}
ptr = mallocp(size);
printf("malloc(%d) = %p\n", (int)size, ptr); return ptr;
}
#endif
тест.с
#include <stdio.h>
#include <stdlib.h>
int main(){
printf("main\n");
int* a = malloc(sizeof(int)*5);
a[0] = 1;
printf("end\n");
}
Результат, который я получаю:
$ gcc -o test test.c
$ gcc -DRUNTIME -shared -fPIC mymalloc.c -o mymalloc.so
$ LD_PRELOAD=./mymalloc.so ./test
Segmentation Fault
Это код, который я пробовал и получил ошибку сегментации (из https://gist.github.com/iamben/4124829):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void* malloc(size_t size)
{
static void* (*rmalloc)(size_t) = NULL;
void* p = NULL;
// resolve next malloc
if(!rmalloc) rmalloc = dlsym(RTLD_NEXT, "malloc");
// do actual malloc
p = rmalloc(size);
// show statistic
fprintf(stderr, "[MEM | malloc] Allocated: %lu bytes\n", size);
return p;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STR_LEN 128
int main(int argc, const char *argv[])
{
char *c;
char *str1 = "Hello ";
char *str2 = "World";
//allocate an empty string
c = malloc(STR_LEN * sizeof(char));
c[0] = 0x0;
//and concatenate str{1,2}
strcat(c, str1);
strcat(c, str2);
printf("New str: %s\n", c);
return 0;
}
Makefile из репозитория git не работал, поэтому я вручную скомпилировал файлы и получил:
$ gcc -shared -fPIC libint.c -o libint.so
$ gcc -o str str.c
$ LD_PRELOAD=./libint.so ./str
Segmentation fault
Я делаю это часами и все равно получаю тот же неверный результат, несмотря на то, что я скопировал код из учебника. Буду очень признателен за любую помощь!!
1 ответ
Один из способов справиться с этим — отключить рекурсивное вызов функции return:
static char ACallIsInProgress = 0;
if (!ACallIsInProgress)
{
ACallIsInProgress = 1;
printf("malloc(%d) = %p\n", (int)size, ptr);
ACallIsInProgress = 0;
}
return ptr;
При этом, если вызовы, ваша подпрограмма просто вызовет фактический malloc(через
Если вам нужно поддерживать многопоточность, может потребоваться дополнительная работа.
Реализация может выделить буфер только один раз, когда он используется в первый раз. В этом случае вы можете инициализировать флаг, который отключает аналогичный приведенному выше вызов, один раз в
Другой вариант - для вашей рутины не использовать