[C, C++] LDD, List Dynamic Dependencies

개발 노트 2009. 1. 13. 15:13 posted by 무병장수권력자


작성자 : 김문규
최초 작성일 : 2009. 1.13

라이브러리 작업을 하다보면 동적으로 참조되는 것들이 무엇이 있는지 알아야 할 때가 많습니다.
특히 혼자만 쓰는 게 아니라 배포되어야 한다면 더욱더 그러하겠지요.

Windows는 툴이 많다고 하더군요.
하지만 개인적으로는 dependency walker가 좋아요~

Unix....
언제나 어렵습니다. 그래서 잠시 구글링을 했습니다. 근데 LDD라는 것이 있더군요. 우왓 짱!

아래 소스를 빌드하시고 첫번째 변수로 해당 파일 넣으시면 되네요.

ldd [파일명]

작업시 유용하게 사용하세요~ AIX에서 테스트 하였습니다. 다른 UNIX에서는?

/*
 * %W% revision of %E%  %U%
 * This is an unpublished work copyright (c) 1993 HELIOS Software GmbH
 * 30827 Garbsen, Germany
 */
/*
 * ldd.c - List dynamic dependencies. Performs a similar function as the
 *    SunOS or System V.4 ldd command. This one works by loading the
 *    target program through load() and then printing all loaded
 *    modules as returned by loadquery().
 *
 * To compile:
 *  xlc -D_ALL_SOURCE -o ldd -O ldd.c -bnoso -bI:/usr/lib/syscalls.exp
 */
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ldr.h>
void errxit(char *);
int main(int argc, char **argv)
{
 struct ld_info *lp;
 char *buf;
 int size = 4*1024;
 int i;
 
 if (argc != 2) {
  fprintf(stderr, "Usage: %s program\n", argv[0]);
  exit(1);
 }
 if (load(argv[1], 0, NULL) == NULL) {
  char *buffer[1024];
  if (errno != ENOEXEC)
   errxit(argv[1]);
  buffer[0] = "execerror";
  buffer[1] = argv[1];
  loadquery(L_GETMESSAGES, &buffer[2], sizeof(buffer)-8);
  execvp("/usr/sbin/execerror", buffer);
  errxit("execerror");
 }
 if ((buf = malloc(size)) == NULL)
  errxit("malloc");
 while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
  free(buf);
  size += 4*1024;
  if ((buf = malloc(size)) == NULL)
   errxit("malloc");
 }
 if (i == -1)
  errxit("loadquery");
 lp = (struct ld_info *)buf;
 while (lp) {
  /*
   * Skip over ourselves. The main part is always the first
   * in the list of loaded modules.
   */
  if (lp != (struct ld_info *)buf) {
   char *fileName = lp->ldinfo_filename;
   char *memberName = fileName + strlen(fileName) + 1;
   printf("%s", fileName);
   if (*memberName)
    printf("(%s)", memberName);
   printf("\n");
  }
  if (lp->ldinfo_next == 0)
   lp = NULL;
  else
   lp = (struct ld_info *)((char *)lp + lp->ldinfo_next);
 }
 free(buf);
 return 0;
}
void errxit(char *s)
{
 perror(s);
 exit(1);
}