CnUnix

[알림판목록 I] [알림판목록 II] [글목록][이 전][다 음]
[ CnUnix ] in KIDS
글 쓴 이(By): akira (Park_S_J_)
날 짜 (Date): 2002년 8월 18일 일요일 오후 05시 55분 15초
제 목(Title): [Q] linux에서 libc profiling과 dlopen


어떤 프로그램을 libc까지 profiling하고 싶은데
그냥 -lc_p를 붙여서 compile하면 이상한 warning이 뜨고
(/usr/bin/ld: BFD 2.11.93.0.2 20020207 assertion fail elf-strtab.c:262)
-static까지 붙여서 하면 잘 되는데 dlopen에서 segfault 또는 illegal instruction이 뜨네요.

linux에서 -static으로 생성된 binary내에서 dlopen을 호출하면 segfault가 뜨는것 같은데요.
이런 저런 방법으로 SEGV는 피해가기는 했는데 여전히 dlopen과 libc profiling이 동시에 안되네요.
대상 library가 plugin 형식이고 소스나 .a가 없어서 꼭 dlopen해야 하는데
방법이 없을까요?

google에서 찾아보니까 FreeBSD에서는

 $(LD) -e start -dc -dp /usr/lib/gcrt0.o -L/usr/libdata/gcc \
   myprog.o  /usr/lib/libgcc.a -lc_p -lc /usr/lib/libgcc.a -o myprog

하면 된다는데 Linux에서는 잘 안되는듯...

cc.c:
extern int global_var;
int my_sym;
int my_printf(char *fmt, int op)
{
  return global_var;
}
% libtool gcc  -pg -c cc.c
% libtool gcc -avoid-version -o libcc.la -rpath /usr/lib cc.lo


p.c:
int global_var;
main()
{
  char libname[] = ".libs/libcc.so";
  void *ptr;
  int (*func)(char *fmt, int opt);
  ptr = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL);
  global_var = 999;
  printf("dl_handle: %x\n", ptr);
  if (!ptr)
  {
    printf("dlopen: %s\n", dlerror());
    exit(-1);
  }
  func = dlsym(ptr, "my_printf");
  printf("func: %x\n", func); 
  if (func)
  {
    printf("global-var:%d\n", func("test", 1));
  }
}   


다음 정도까지는 성공했는데

% gcc -pg -Wl,-export-dynamic -o p p.c -ldl_p -lc_p -static
% p
dl_handle: 0
dlopen: .libs/libcc.so: undefined symbol: global_var

dlopen이 되려고 하다가 symbol을 못찾고 dynamic linking에 실패하네요.
(libc profiling은 전부 잘 됩니다.)
물론 다음과 같이 하면 

% gcc -pg -Wl,-export-dynamic --o p p.c -ldl
% p
dl_handle: 804a2b0
func: 40014764
global-var:999

dlopen은 잘 됩니다. 하지만 libc profiling이 안됩니다.


[알림판목록 I] [알림판목록 II] [글 목록][이 전][다 음]
키 즈 는 열 린 사 람 들 의 모 임 입 니 다.