[질문]malloc을 사용자정의 malloc으로 치환하는 데 생기는 에러
글쓴이: juluv / 작성시간: 화, 2005/03/01 - 1:51오전
안녕하세요. 요 며칠째 같은문제로 계속 고민하니 마음이 하도 답답하여 고수님들의 도움을 받고자 이렇게 글을 올리게 되었습니다.
먼저 제가 하고자 하는 것은 "malloc을 사용자정의 malloc으로 치환" 하는 것입니다. 이를 위해 http://uberhip.com/godber/interception/html/slide_6.html 에 있는 LD_PRELOAD 기법을 참조하여 저만의 동적 라이브러리를 만들고, 그것을 실행하여 보았습니다. 그러면 "segement falut"만이 계속 납니다. :cry:
저만의 malloc 부분에 대한 코드는 다음과 같습니다.
#include <stdio.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include <errno.h>
#include <dlfcn.h>
void* malloc(size_t size)
{
void *handle;
void *(*orig_malloc)(size_t size);
char *error;
void *result;
handle=dlopen("/lib/libc.so.6",RTLD_LAZY);
if(!handle){
fputs(dlerror(),stderr);
exit(EXIT_FAILURE);
}
orig_malloc = dlsym(handle, "malloc");
if((error=dlerror()) != NULL){
fputs("error",stderr);
exit(EXIT_FAILURE);
}
result = (*orig_malloc)(size);
return result;
}
아낌없는 조언 부탁드립니다. 긴 글 읽어주셔서 감사합니다.
Forums:


malloc이 불릴때마다 dlopen, dlsym이 일어나는 것 보다는,
malloc이 불릴때마다 dlopen, dlsym이 일어나는 것 보다는,
orig_malloc 변수를 static으로 만들어 놓고,
NULL일 때(즉, 최초에만)만 dlopen dlsym 으로 할당하는 것이 좋을 것 같습니다.
그리고, malloc 뿐아니라, free 도 하신건가요? 그 쌍이 맞지 않으면, 두 함수간 사용하는 static 변수가 (혹시 있다면) 제대로 안될 것 같습니다만..
---
http://coolengineer.com
매번 느끼지만, pynoos님의 답변은 간결 명확하군요.[quot
매번 느끼지만, pynoos님의 답변은 간결 명확하군요.
멋지십니다.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
제가 만든거는 아니고,,,vmware 의 메뉴를 숨기기 위해서 g
제가 만든거는 아니고,,,
vmware 의 메뉴를 숨기기 위해서 gtk_widget_show 를 치환하는 프로그램인데
관련있는 듯하여 올려 봅니다.
pynoos 님이 설명한 내용 그대로 입니다.
#define _GNU_SOURCE #include <dlfcn.h> #include <stdio.h> #include <gtk/gtkwidget.h> void gtk_widget_show(GtkWidget *widget) { static void (*next_gtk_widget_show)(GtkWidget*) = NULL; if (!next_gtk_widget_show) { next_gtk_widget_show = dlsym(RTLD_NEXT, "gtk_widget_show"); if (!next_gtk_widget_show) { fprintf(stderr, "Abort: no gtk_widget_show\n"); abort(); } } if (widget && widget->name && widget->state == 0 && !strcmp(widget->name, "<main>")) { return; } next_gtk_widget_show(widget); }조언 감사합니다. 하지만 여전히 같은 에러가 나는군요..
지적 감사합니다. 일단 말씀해주신대로 저의 malloc루틴을 다음과 같이 수정하였습니다.
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <dlfcn.h> void* malloc(size_t size) { void *handle; static void *(*orig_malloc)(size_t size); char *error; void *result; if(!orig_malloc){ handle=dlopen("/lib/libc.so.6",RTLD_LAZY); if(!handle){ //fputs(dlerror(),stderr); exit(EXIT_FAILURE); } orig_malloc = dlsym(handle, "malloc"); if((error=dlerror()) != NULL){ //fputs("error",stderr); exit(EXIT_FAILURE); } } result = (*orig_malloc)(size); return result; }이것을 다음과 같이 컴파일 하여 라이브러리를 생성하고...
다음과 같은 프로그램에서 테스트하였습니다.
#include<stdio.h> #include<stdlib.h> int main() { int *a=malloc(2); return 0; }결과는...
이네요..
free를 쓰지 않았더라도 오버라이딩시키기전의 malloc일때는 에러가 나지 않았는데요..
다시한번 도움을 주시면 감사하겠습니다.
안녕히 계세요.. 꾸벅..
저의 추측...
아무리 보아도 orig_malloc이 제대로 할당이 이루어지지 않는 것 같은데요..
1. 일단 orig_malloc에 값이 할당은 되는것 같습니다. 이 값이 NULL일때 무언가를 찍어보도록 추가를 해보았는데 그렇지 않았기 때문입니다.
2. 1의 추측대로다면 그 값이 제대로 되지 않은 것이라서 에러가 나는것 같다는 생각이 드네요.. :oops:
3. 2가 맞다면 다음 두부분중에 하나가 오작동한 것일텐데요..
handle=dlopen("/lib/libc.so.6",RTLD_LAZY);orig_malloc=dlsym(handle,"malloc")4. 3에서 혹시 "/lib/libc.so.6"이 잘못된 것은 아닐까요? :shock: libc.so.6 라이브러리에서 잘못된 handle을 주었다거나... :?:이상 저의 허접한 추측이었습니다.. 어떤 지적도 감사히 받겠습니다.
일단 아래코트는 동작합니다. google에서 malloc dlsym
일단 아래코트는 동작합니다.
google에서 malloc dlsym 정도로 검색하시면 많은 도움을 얻으실 수 있을
거라 생각합니다.
원인에 대해서는 대충 짐작이 가는데, 실력이 부족하여 제대로 설명이 안되는군요....
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <dlfcn.h> void* malloc(size_t size) { void *handle; static void *(*orig_malloc)(size_t size) = NULL; char *error; void *result; if(!orig_malloc){ orig_malloc = dlsym(RTLD_NEXT, "malloc"); if((error=dlerror()) != NULL){ //fputs("error",stderr); exit(EXIT_FAILURE); } } result = (*orig_malloc)(size); return result; }The symbols RTLD_DEFAULT and RTLD_NEXT are defined by <dlfcn.h> only when _GNU_SOURCE was defined before including it.
dlopen() 함수 자체가 malloc() 를 호출합니다. 그래서 님의
dlopen() 함수 자체가 malloc() 를 호출합니다. 그래서 님의 코드는 preload 된 malloc 이 재귀적으로 계속 호출되다가 fault 가 나는 것입니다. 그래서 위의 분이 얘기하신 대로 미리 할당되어있는 RTLD_NEXT 를 이용해서 malloc 을 받아야만 합니다...
이제 졸업이다...사랑하는 SKKULUG 후배들아 안녕~
정말 감사합니다...
관심을 가져주신 분들 정말 감사드립니다.
나눔의 힘이 크다는 것을 다시한번 느끼게 되었습니다. 저도 능력이 되는 한 다른 분들께 도움이 될 수 있도록 열심히 하겠습니다.
다시한번 감사드립니다. :D
댓글 달기