Backend/OS★

ObjDump 사용하기

petitCoding 2012. 4. 12. 10:14

일을 하면서 정말 유용하게 쓰이는 명령어중 하나가 objdump 이다.

특히 프로그램이 core 파일을 생성하고 죽었을때, 그 core 파일에 정확한 함수명이 나타나지 않거나

찾기 힘든 경우, 이 objdump를 생성하여 해당 프로그램의 함수별 주소값을 찾아 

프로그램이 죽은 시점을 쉽게 파악할 수 있다.

 

뭐, 이외에도 objdump는 다양한 용도로 사용될 수 있겠지만 :)

 

일단 man 페이지를 보면 ..

 

> man objdump

 

OBJDUMP(1)                   GNU Development Tools                  OBJDUMP(1)

NAME
       objdump - display information from object files.

SYNOPSIS
       objdump [-a│--archive-headers]
               [-b bfdname│--target=bfdname]
               [-C│--demangle[=style] ]
               [-d│--disassemble]
               [-D│--disassemble-all]
               [-z│--disassemble-zeroes]
               [-EB│-EL│--endian={big │ little }]
               [-f│--file-headers]
               [--file-start-context]
               [-g│--debugging]
               [-e│--debugging-tags]
               [-h│--section-headers│--headers]
               [-i│--info]
               [-j section│--section=section]
               [-l│--line-numbers]
               [-S│--source]
               [-m machine│--architecture=machine]
               [-M options│--disassembler-options=options]
               [-p│--private-headers]
               [-r│--reloc]
               [-R│--dynamic-reloc]
               [-s│--full-contents]
               [-W│--dwarf]
               [-G│--stabs]
               [-t│--syms]
               [-T│--dynamic-syms]
               [-x│--all-headers]
               [-w│--wide]
               [--start-address=address]
               [--stop-address=address]
               [--prefix-addresses]
               [--[no-]show-raw-insn]
               [--adjust-vma=offset]
               [--special-syms]
               [-V│--version]
               [-H│--help]
               objfile...

DESCRIPTION
       objdump displays information about one or more object files.  The options control what particular information to display.  This information is mostly use-
       ful to programmers who are working on the compilation tools, as opposed to programmers who just want their program to compile and work.

       objfile... are the object files to be examined.  When you specify archives, objdump shows information on each of the member object files.

OPTIONS
       The   long   and   short   forms   of   options,   shown   here   as   alternatives,   are   equivalent.    At   least   one   option   from   the    list
       -a,-d,-D,-e,-f,-g,-G,-h,-H,-p,-r,-R,-s,-S,-t,-T,-V,-x must be given.

       -a
       --archive-header
           If  any  of  the objfile files are archives, display the archive header information (in a format similar to ls -l).  Besides the information you could
           list with ar tv, objdump -a shows the object file format of each archive member.

 

Description 을 보면, 한개 또는 그 이상의 object file 정보를 출력해 준다고 되어 있다. 그리고 여기서 사용되는 옵션은 어떤 방법으로 어떤 정보를 출력해 줄 것인지 결정하는 역할을 한다.

 

 

사용예를 간단히 들어 보겠다.

 

우선  다음과 같이 간단한 프로그램을 작성..

버그가 보이나용???ㅎㅎㅎ

 

#include <stdio.h>

typedef struct _info {
        char *name;
        int num;
} info;


int main(void)
{
        info *me;

        printf("name : %s\n", me->name);

        return 0;
}

 

 

그리고 컴파일 하면.. 실행파일이 생성된다.

이 프로그램을 실행하면 core dump가 나오고 프로그램이 죽을 것이다.

 

whitelka> gcc -o test test.c

whitelka> ls

test test.c

whitelka> ./test

Segmentation fault (core dumped)

whitelka> ls

core.16205 test test.c

 

 

자, 그럼 디버깅 ㄱㄱ!

 whitelka> gdb -c core.16205 ./test

GNU gdb Red Hat Linux (6.6-35.fc8rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".

warning: Can't read pathname for load map: Input/output error.

warning: Missing the matching library file: /usr/lib/debug/.build-id/82/4034107303e7a87fd2d6eaebf55d7ef31c8b0c

warning: Missing the matching library file: /usr/lib/debug/.build-id/63/26e65adb44436c51e7f7c1695614f365738303
Reading symbols from /lib/libc.so.6...
warning: Missing the separate debug info file: /usr/lib/debug/.build-id/ba/4ea1118691c826426e9410cafb798f25cefad5.debug
(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...
warning: Missing the separate debug info file: /usr/lib/debug/.build-id/ac/2eeb206486bb7315d6ac4cd64de0cb50838ff6.debug
(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2

warning: Missing the matching library file: /usr/lib/debug/.build-id/82/4034107303e7a87fd2d6eaebf55d7ef31c8b0c

warning: Missing the matching library file: /usr/lib/debug/.build-id/63/26e65adb44436c51e7f7c1695614f365738303
(no debugging symbols found)
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
#0  0xb7e1812b in strlen () from /lib/libc.so.6
(gdb) bt
#0  0xb7e1812b in strlen () from /lib/libc.so.6
#1  0xb7de81e9 in vfprintf () from /lib/libc.so.6
#2  0xb7ded9b3 in printf () from /lib/libc.so.6
#3  0x080483ea in main ()
(gdb)

 

요기 #0~#3까지 주소값이 보이는가? 바로 objdump를 떴을때 확인할 수 있는 주소값들이다.

그럼.. 이 파일을 objdump해서 어떤 위치에서 프로그램이 죽었는지, 확인해 보겠다~

 

whitelka> objdump -S test > obj

whitelka> ls

core.16205 obj test test.c

whitelka> vi obj

 

생성된 obj파일을 열면, 쭉~ 값들이 나오는데, 여기서는 위에 core 나온 부분만 캡쳐 떴다.ㅎㅎ

 

0x080483ea 이부분이 죽은 부분이다. (drag)

보면, printf호출이 이루어 지는 시점에서 죽었고, 호출한 함수는 main이라는 것이 보인다.

위의 소스코드에서 main 함수의 prinf 에서 죽었다는 것을 이렇게 확인할 수 있는 것이다!!

 

 

 

물론 objdump로 아주 확실하게 정확히 죽은 부분을 찾는것은 조금 무리가 있긴 하다.

하지만 불분명하게 주소값만 출력된 core 파일만 존재할 경우에는 적어도 어떤 함수에서 죽었는지 정도는 알 수 있기 때문에

실력있는 개발자들이라면 그 위치의 코드를 살펴 오류가 있다는 것을 알아내기 쉬울 것이다

반응형