디버깅 이야기: strace, truss, tusc
디버깅의 시작은 과감히 툴을 먼저 배우는 것이라고 해도 과언이 아닐정도로 툴에
익숙해야합니다. 디버깅 툴은 어떻게 보면, 크게 구분이 되어 있는 것은 아니지만
사뭇 심도있는 분석을 위해서는 해킹에 사용되는 것과 크게 다르지 않습니다.
디버깅과 해킹은 같은 맥락에 있는 것이지요.
먼저 쉽고 재밌게 접근할 수 있는 것이 system call tracer입니다.
linux: strace
solaris: truss
hpux: trace(10.x), tusc(11.x)
로 알려져 있는 것들이지요. 위 프로그램들의 option 들이 대개 비슷합니다.
strace ls
만 해도 나오는 내용이 어떻다는 것을 보실 수 있을텐데요.
이들은 모두 kernel level의 함수들입니다. 즉 system call이라는 것이지요.
직관적으로 이용할 수 있는 방법은 다음과 같은 것들입니다.
1. 어떤 shared library가 사용되는지 알수 있음.
2. 1번과 비슷하지만 어떤 파일을 열다가 실패하는지,
대개 configuration file을 global, home.. 순으로 찾지요.
3. process가 잠시 멈출때, 어떤것을 대기하고 있는지.
4. 전송되고 들어오는 내용은 무엇인지 (-s 1024 option)
5. 어떤 signal을 받는지.
6. ipc 객체들은 어떤것들이 이용되는지.
등등...
system call은 기본적으로 OS를 다루는 방법에 대한 것이므로, 많은 hint를 얻을 수
있습니다.
option 들중에 중요한 것 몇가지만 소개하자면, system call의 가장 대표적인 것중의
하나는 실행되고 있는 daemon의 현재 작업내용을 살펴볼수 있는 것이 있습니다.
strace -p <pid>
형태로 실행중인 process를 살펴보는 것이지요. 더불어 daemon의 경우 fork가
일어나는 경우가 많은데,
strace -f -p <pid>
-f option을 주어 fork되어 나오는 process까지 trace 하라는 것입니다. fork외에
vfork도 추적할 수 있어야하므로 대개 f를 쓸때는 다음과 같이 사용합니다.
strace -fF -p <pid>
더 줄여서
strace -fFp <pid>
로 사용하지요.
이것들을 종합하여 다음과 같은 용도로 사용할 수 있습니다.
1. daemon 이 갑자기 멈추었는데, debug 용 printf를 집어 넣지 않았을 때, 알고싶은
경우.
2. socket server가 과연 process가 connection을 접수한 뒤 제대로 fork 되는지.
3. telnet 서버에 접속하였는데, prompt가 떨어지지 않는 경우 inetd가 무슨일을
하는지. (대개 tcp_wrapper에 의해 DNS IP resolve 하는 경우가 많죠.)
지금까지 한 것은 일부분에 지나지 않습니다. 남의 program을 추적할때 system call
trace를 하는 것만으로 process가 하는 일을 상상할 수 있다면, 프로그램을
만든사람은 어느 code를 지나가고 있는지 알 수 있을 것입니다.
디버깅은 printf 로만 하는-_-줄아는 저에게정말 많은 도움이 되
디버깅은 printf 로만 하는-_-줄아는 저에게
정말 많은 도움이 되네요ㅎㅎ
앞으로도 계속 올려주세요~ :lol:
좋은 글 감사합니다.
:roll: 좋은 팁이군요 ^^
Don't be confused to contact me ^^
thankudd@shinbiro.com - TIM systems.
음 궁금한게 있는데염....미리 선언해논 변수 무언가에.. 에러가 나
음 궁금한게 있는데염....
미리 선언해논 변수 무언가에.. 에러가 나면 에러난 라인이라든가...
몇가지 정보가 저장되는 변수가 있단 말을 들은 적이 있는데... 어떤것인지.. 어떤식으로 사용하는지 알고 싶네요.
앞마당 먹고 시작한 저그의 8할은 뮤탈 테크를 먼저 탄다. 하지만 나머지 2할때문에 항상 스켄이 모자란다. - _-;
에러난 라인은 모르겠습니만....error code는 errno
에러난 라인은 모르겠습니만....
error code는 errno 라는 전역 변수에 저장이 됩니다.
#include <errno.h>
perror( "check" );
printf("Error message: %s\n", strerror(errno) );
위 두 함수 중 하나로 그 메시지를 확인합니다.
용도는 다르겠지요.
---
http://coolengineer.com
음... __XXX 어쩌구 하는 변수라던데 -_-; errno는 아니고염
음... __XXX 어쩌구 하는 변수라던데 -_-; errno는 아니고염
앞마당 먹고 시작한 저그의 8할은 뮤탈 테크를 먼저 탄다. 하지만 나머지 2할때문에 항상 스켄이 모자란다. - _-;
error line은 모든 함수의 return 값을 제대로 확인하는 수
error line은 모든 함수의 return 값을 제대로 확인하는 수 외에는
제가 알기로는 없습니다.
누구 답변해주실분~~? ^^
시혹..........
__errno_location()
함수를 말하시는 것인지 모르겠습니다만, 이것은 errno의 thread safty를 위해 만들어진 것으로 알고 있구요.
이것이 error가 난 장소를 의미하는 것은 아니지요..
---
http://coolengineer.com
아.. 제가 헤더 파일을 뒤져봤는데여.. assert()라는 매크로를 쓰
아.. 제가 헤더 파일을 뒤져봤는데여.. assert()라는 매크로를 쓰면 되고,
__FILE__, __LINE__ 를 그냥 써도 되는군여 -_-;
앞마당 먹고 시작한 저그의 8할은 뮤탈 테크를 먼저 탄다. 하지만 나머지 2할때문에 항상 스켄이 모자란다. - _-;
^^__FILE__, __LINE__ 을 쓰신다면, 다른 팁이 또
^^
__FILE__, __LINE__ 을 쓰신다면, 다른 팁이 또 있습니다.
__PRETTY_FUNCTION__
이 있지요.. 현재 compile 진행중인 함수를 의미합니다. gcc에서만 되며, 상용 vendor의 compiler에서는 지원하지 않습니다.
---
http://coolengineer.com
오, 이런 것이...
한 수 배웠습니다...(_ _)
gdb랑 assert, printf만 썼었는데 또 실력이 조금 진보할 수 있겠네요.
저희 모임 게시판에 퍼다 올려도 될까요? ^^;;
노루가 사냥꾼의 손에서 벗어나는 것 같이, 새가 그물치는 자의 손에서 벗어나는 것 같이 스스로 구원하라 -잠언 6:5
네.. 마음대로 퍼가셔도 좋습니다.
네.. 마음대로 퍼가셔도 좋습니다.
---
http://coolengineer.com
글 재밌게 보고 있습니다. 꾸벅.
ltrace - A library call tracer 도 strace 만큼이나..유용한... :)
보고 하나둘씩 얻어가고 있습니다. 감사합니다.
발 담갔다. 이제 익숙해 지는길만이..
ltrace도 소개해야지 하면서.. 못하고 있네요.. ^^
ltrace도 소개해야지 하면서.. 못하고 있네요.. ^^
---
http://coolengineer.com
ltrace는 어떤건가요?
라이브러리의 루틴들이 call되는 것을 보여주는 건가요?
truss 에 옵션을 주니까 라이브러리 함수 수준에서도 트레이스가 되던데
이거랑 비슷한 건가 보네요?
근데 AIX 쪽에서도 시스템콜 성공적으로 트레이스 해 보신 분 있나요?
syscalls 라는 것이 있다고 메뉴얼에는 나오는데,
안 깔려있어서 테스트를 못 해봤는데 경험 있으신 분 좀 올려주시면 고맙겠습니다.
ltrace는 library call 을 보여줍니다.truss 무
ltrace는 library call 을 보여줍니다.
truss 무슨 option이었죠? 제가 확인 안해봐서리.. ^^
AIX 버전 4.x 에는 시스템콜 크레이스 비슷한 기능이 있는 것이 상용이 있다는 것만 알고 있습니다.
AIX 5 에는 truss 라는 이름이 있는 걸로 알고 있는데, 써보진 못해봤구요.
AIX 4.3.x 용 library trace 에는..
http://www.pgibbs.demon.co.uk/useful_code.htm
에 가보시면, 훌륭한 library trace를 구하실 수 있습니다.
---
http://coolengineer.com
전보통 이렇게 사용합니다
전보통 이렇게^^... 다들 좋은 팁올리시네여~
[/code]
초심으로
이야~~ 디버깅 이야기 정말 재미있네요.전 디버깅 툴이라면 [co
이야~~ 디버깅 이야기 정말 재미있네요.
전 디버깅 툴이라면 GDB가 최고인줄 알았습니다.
그 이상은 아무것도 없다고 생각했는데..제 생각이 좁았네요.
앞으로 디버깅 이야기 계속 올려주세요.
저의 무지함을 깨우쳐 주세요. ^^
문근영 너무 귀여워~~
말씀해주신데로 strace -p 프로세스id를 수행했더니usage
말씀해주신데로 strace -p 프로세스id를 수행했더니
usage : [mod_ID sub_ID pri_level] 와 같은 메시지만 뜨고 아무일도
안일어 나던데요.
위와 같은 옵션이 무엇을 뜻하고 어떻게 사용해야 되는지요?
strace는 linux에서만 사용됩니다. 혹 다른 OS의 strace를
strace는 linux에서만 사용됩니다. 혹 다른 OS의 strace를 사용한다면, 그것은 원하는 디버깅 툴이 아닐것입니다.
---
http://coolengineer.com
혁신적 입니다!저같은 초보한텐 한줄기의 .. 뭐엿지..새벽
혁신적 입니다!
저같은 초보한텐 한줄기의 .. 뭐엿지..
새벽 5시라.. 뭐가뭔지..
아아, 앞으로도 많은거 부탁드려요 ==3
좋은 내용이네요..
많은 도움 되었습니다.
그런데 strace -fFp pid
하닌까..
[pid 27984] open("/oracle/app/oracle/product/8.0.5/rdbms/mesg/oraus.msb", O_RDONLY) = 7
[pid 27984] fcntl(7, F_SETFD, FD_CLOEXEC) = 0
[pid 27984] lseek(7, 0, SEEK_SET) = 0
[pid 27984] read(7, "\25\23\"\1\23\3\t\t\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 256) = 256
[pid 27984] lseek(7, 512, SEEK_SET) = 512
[pid 27984] read(7, "\303\35op\32t\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 512) = 512
[pid 27984] lseek(7, 1536, SEEK_SET) = 1536
[pid 27984] read(7, "\323\35\337\35\0\36\31\36%\36I\36\215\36\251\36F\37\10"..., 512) = 512
[pid 27984] lseek(7, 179712, SEEK_SET) = 179712
[pid 27984] read(7, "\v\0\245/\0\0J\0\246/\0\0l\0\250/\0\0\222\0\251/\0\0\257"..., 512) = 512
[pid 27984] close(7) = 0
[pid 27984] --- SIGSEGV (세그멘테이션 오류) ---
<... accept resumed> 0xbffff7b0, [16]) = ? ERESTARTSYS (To be restarted)
--- SIGCHLD (자식이 종료됨) ---
이런식으로 세그멘테이션 오류가 나오면서..
프로그램이 정상동작을 하지 않네요..
strace를 사용하지 않으면
정상적으로 동작을 하는데..
source 문제인가요?
-f 옵션 없이
별도의 프로세스별로 체크를 하면 문제가 되지는 않는군요.
댓글 달기