강좌 & 팁
글 수 2,412
2012.03.30 12:47:28 (*.52.177.29)
45308
ltrace를 이용하여 바이너리 실행시, 라이브러리 들이 어떻게 호출 되고 있는지 알 수 있는 명령어 이다.
간단한 프로그램인 /bin/true, /bin/false를 ltrace를 이용하여 살펴보자.
# ltrace /bin/true
__libc_start_main(0x8048dd0, 1, 0xbf9ccb94, 0x804ac50, 0x804acb0 <unfinished ...>
exit(0 <unfinished ...>
+++ exited (status 0) +++
# ltrace /bin/false
__libc_start_main(0x8048dd0, 1, 0xbf81b234, 0x804ac50, 0x804acb0 <unfinished ...>
exit(1 <unfinished ...>
+++ exited (status 1) +++
/bin/true 과 /bin/false 프로그램은 main 함수에 0과 1을 exit로 종료하는 함수로 구성 되어 있는 것을 알 수 있다.
주로 사용하고 있는 ls의 경우 lstrace를 이용하여 살펴보면 상당히 많은 함수를 호출 하는 것을 알 수 있다.
-------------------------
# ltrace ls
__libc_start_main(0x804f990, 1, 0xbff38e44, 0x805a140, 0x805a1a0 <unfinished ...>
strrchr("ls", '/') = NULL
setlocale(6, "") = "ko_KR.UTF-8"
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
textdomain("coreutils") = "coreutils"
__cxa_atexit(0x8053490, 0, 0, 0xbff38e44, 0xbff38d98) = 0
isatty(1) = 1
getenv("QUOTING_STYLE") = NULL
getenv("LS_BLOCK_SIZE") = NULL
getenv("BLOCK_SIZE") = NULL
getenv("BLOCKSIZE") = NULL
getenv("POSIXLY_CORRECT") = NULL
getenv("BLOCK_SIZE") = NULL
getenv("COLUMNS") = NULL
ioctl(1, 21523, 0xbff38ad8) = 0
getenv("TABSIZE") = NULL
getopt_long(1, 0xbff38e44, "abcdfghiklmnopqrstuvw:xABCDFGHI:"..., 0x0805af00, -1) = -1
__errno_location() = 0xb77d1694
malloc(48) = 0x09e46880
memcpy(0x09e46880, "", 48) = 0x09e46880
__errno_location() = 0xb77d1694
malloc(48) = 0x09e468b8
memcpy(0x09e468b8, "", 48) = 0x09e468b8
malloc(12800) = 0x09e468f0
malloc(16) = 0x09e49af8
strlen(".") = 1
malloc(2) = 0x09e49b10
memcpy(0x09e49b10, ".", 2) = 0x09e49b10
__errno_location() = 0xb77d1694
opendir(".") = 0x09e49b20
readdir64(0x09e49b20) = 0x09e49b38
readdir64(0x09e49b20) = 0x09e49b50
readdir64(0x09e49b20) = NULL
closedir(0x09e49b20) = 0
_setjmp(0x8060ce0, 0xbff38968, 0x2eb8e8, 0x9e49b20, 0) = 0
free(0x09e49b10) = <void>
free(NULL) = <void>
free(0x09e49af8) = <void>
exit(0 <unfinished ...>
__fpending(0x3b44e0, 0x8048b02, 0xb77d32b8, 2, 0) = 0
fclose(0x3b44e0) = 0
__fpending(0x3b4580, 0x8048b02, 0xb77d32b8, 2, 0) = 0
fclose(0x3b4580) = 0
+++ exited (status 0) +++
root@jhpark-desktop:~/t# ltrace /bin/sleep 0
__libc_start_main(0x8048f00, 2, 0xbfdff944, 0x804b2e0, 0x804b340 <unfinished ...>
strrchr("/bin/sleep", '/') = "/sleep"
setlocale(6, "") = "ko_KR.UTF-8"
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
textdomain("coreutils") = "coreutils"
__cxa_atexit(0x80493f0, 0, 0, 0x55fff4, 0xbfdff898) = 0
getopt_long(2, 0xbfdff944, "+", 0x0804b840, NULL) = -1
getopt_long(2, 0xbfdff944, "", NULL, NULL) = -1
__errno_location() = 0xb78de898
newlocale(8127, 0x804b800, 0, 0x41a420, 0xbfdff87c) = 0x55f040
strtod_l(0xbfe0093c, 0xbfdff80c, 0x55f040, 0x41a420, 0xbfdff87c) = 0
__errno_location() = 0xb78de898
nanosleep(0xbfdff808, 0, 0xbfdff828, 0x804ab2f, 0xbfe0093c) = 0
exit(0 <unfinished ...>
__fpending(0x5604e0, 0x804855e, 0xb78f9858, 1, 0xbfdff7c0) = 0
fclose(0x5604e0) = 0
__fpending(0x560580, 0x804855e, 0xb78f9858, 1, 0xbfdff7c0) = 0
fclose(0x560580) = 0
+++ exited (status 0) +++
-------------------------
항상 시작은
__libc_start_main(0x804f990, 1, 0xbff38e44, 0x805a140, 0x805a1a0 <unfinished ...>
로 시작해서
+++ exited (status 0) +++
로 종료 된다는 것을 확인 할 수 있다.
테스트 삼아 ifconfig를 ltrace를 수행해 보면 ls 보다 훨씬 다양하고 많은 함수 들을 호출 한다는 것을 확인 할 수 있다.
strace와 ltrace를 이용하면 print 문 외에 좀더 다양항 방식으로도 디버깅이 가능 하다는 것을 알 수 있게 된다.