gdb 관련 매우 기초적 질문 - breakpoint 설정 관련 - 자식프로세스에 breakpoint 걸기
gdb 를 써 보려고 하는데.. break 명령을 써도 breakpoint가 안 잡힙니다..
<에러 내용> 프로그램이 무한 루프에 빠졌는데.. 의심스러운 함수가 하나 있습니다.
<원하는 것> 특정 함수에 breakpoint 를 걸고 싶습니다.
==상황 설명==
<시스템 구성 요소> 세 개의 파일이 하나의 (무지 작은)시스템을 구성합니다. 대략 아래와 같습니다. (필요한 부분만 뽑아서 간략화했음)
engine.c
---------------------
main()
{
html_collector();
}
----------------------
html_collector.c
-----------------------
html_collector()
{
tag_eliminator();
}
-----------------------
tag_eliminator.c
-----------------------
tag_eliminator()
{
//뭔가 있음
}
-----------------------
즉, engine.c 의 main 이 html_collector 를 호출하고, html_collector 는 tag_eliminator 함수를 호출하는 형식입니다.
tag_eliminator 에 무한루프를 야기시키는 요소가 있는 거 같아서, gdb 를 이용해 tag_eliminator 함수에 breakpoint 를 걸고자 합니다. 그러기 위해 제가 취했던 동작들을 밑에 캡쳐해서 올립니다.
보시다시피.. 저는 tag_eliminator 함수의 시작 부분에서 breakpoint 가 걸리길 원했는데.. 프로그램은 그냥 끝까지 다 수행돼 버렸습니다.
break (파일명):(함수명)
을 수행하면 breakpoint 가 설정되야 하는 거 아닌가요?
제가 gdb 사용법을 잘 몰라서, 뭔가 기초적인 실수를 한 것 같은데.. 뭘 잘못한건지 모르겠습니다..
첨부 | 파일 크기 |
---|---|
gdb화면.JPG | 92.78 KB |
breakpoint는 제대로
breakpoint는 제대로 설정된 것 같은데 혹시 그 부분이 실행되지 않는 것이 아닐까요?
무한 루프에 빠지지
무한 루프에 빠지지 않는 것 같은데요?
run 말고 start로 해서 trace 해 보세요. 해당 함수를 타지 않고 종료 되는 것 같습니다.
-------------------------
The universe is run by the complex interweaving of three elements: matter, energy, and enlightened self-interest.
- G'kar, Babylon 5
-------------------------
The universe is run by the complex interweaving of three elements: matter, energy, and enlightened self-interest.
- G'kar, Babylon 5
gdb 포기했습니다...
일단 포기하고
printf 를 이용하여 디버그하고 있습니다..
나중에 다시 도전해 보려구요..
그런데.. 에러가 없을 경우에도 breakpoint 걸어놓을 수 있는 거죠?
무한루프가 도는 경우에두요.. 그러면서 매 순간 변수들의 값을 확인할 수 있는 거겠죠?
답변 감사합니다...^^
malloc(strlen(argv[1]))
malloc(strlen(argv[1])) <- 이 코드는 버그가 있을 가능성이 있습니다.
malloc(strlen(argv[1])+1) 로 해주세요. \0 까지 고려를 해야합니다.
--
Captue the one shot in your life!
뭘 말씀하시려는지 잘 모르겠습니다..
좀 더 구체적으로 말씀해 주시면 안 될까요?
브레이크포인트를
메인함수에서 해당 함수 호출하기전 라인에 브레이크를 거시는게 좋을듯합니다.
그리고 나서 s를 눌러서 한스텝 실행시켜보면 해당 함수가 호출되는지 않대는지 알 수 있고, 또한 브레이크를 주실때는
파일에 함수명으로 주는것도 괜찮지만 그냥 함수명으로 주는편이 좋습니다. 어차피 똑같거든요. 3개의 파일이 하나의 실행
파일이 되므로 결국 하나의 파일입니다.
브레이크포인트를 걸었는데 멈추지 않는다는 게 정말 이해가 안 됩니다
프로그램 안에 무한 루프가 있건 없건..
일단 breakpoint 를 걸면 프로그램이 멈춰야 하지 않습니까?
run www.hani.co.kr
(www.hani.co.kr 은 실행에 필요한 인자. 명령라인에서 수행시에는 ./engine www.hani.co.kr 과 같이 수행)
을 실행하면 어디에서건 일단 멈춰야 하는 거 아닌가요?
그런데 왜
program exited normally 라는 메세지가 뜨면서 프로그램이 끝까지 수행이 돼 버리는 건지 이해가 안 됩니다.
break 가 어디에 걸렸건 어디에선가 멈춰야 하는 거 아닌가요?
breakpoint를 설정하신
breakpoint를 설정하신 부분이 실행되지 않는다면 멈추지 않습니다. 그 부분이 정말로 실행되는지 확인해 보세요.
tag_eliminator 함수는 실행이 됩니다.
printf 를 이용하여 열심히 디버그한 결과..
무한루프에 빠지게 만들었던 부분을 찾아내서 수정을 했고, 현재 tag_eliminator 함수는 정상적으로 동작합니다.
정상적으로 동작하는 함수에 break 를 걸어서, 프로그램의 실행을 일시 정지시키는 일로 문제가 바뀌었는데요..
(1)일단 제가 breakpoint를 제대로 설정하긴 한 건가요?
break tag_eliminator.c:tag_elimantor
break tag_eliminator
이렇게 두개 다 해 봤는데... 멈추질 않습니다.
그리고
(2)tag_eliminator 에 breakpoint 를 걸었다는 말은 tag_eliminator() 를 호출하는 모듈이 tag_eliminator() 호출 직전에서 멈추게 된다는 말 맞는 거지요? (확인 차원에서...^^;;)
답글 감사합니다..^^
호출위치에서 브레이크를 해 보세요
tag_eliminator()함수를 호출하는 부분에서 브레이크 포인트를 걸어보시는 것은 어떨까 합니다.
처음 본문에 있는 글을 보면 html_collector()에서 tag_eliminator()를 호출하는 것으로 되어 있습니다.
호출하는 줄에 브레이크를 걸어보세요.
혹시 프로그램이
혹시 프로그램이 여러 프로세스를 만들어 내는 것인지 확인바랍니다.
GDB는 본질적으로 대상 프로세스가 child process를 만든다고 해도 child는 GDB와 상관없이 동작합니다.
만약 특정 child를 따라가고 싶다면
1) parent process가 fork/vfork하는 시점에 breakpoint를 건다
2) child process는 생성되자마자 어느 시간동안 sleep 하도록 만들어 둔다.
3) child가 만들어진 후 ps 명령 등으로 pid를 알아낸다.
4) gdb에서 attach 명령으로 현재 프로세스를 child process로 바꾼다.
를 하면 됩니다.
만약 단순하게 한 child만 만들어 쓰고 있다면, 자동으로 child process로 전환하도록 다음 명령을 쓰면 됩니다:
현재 상태를 보고 싶다면:
를 씁니다.
멀티 쓰레드를 쓰는 프로그램이라면 GDB가 알아서 해주니 걱정할 것 없습니다.
--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
프로세스 생성하는 거 맞습니다..^^
답변 감사합니다.^^
말씀하신 대로 engine에서 fork()를 이용해 child 프로세스를 임의의 수만큼 만들고 (지금은 하나만 생성해 사용중),
생성된 child 프로세스가 html_collector() 를 호출합니다.
그 html_collector() 함수가 tag_eliminator() 함수를 호출하구요..
그런데.. 수행해도 역시 안 되네요..
아래가 수행한 명령어 및 그 결과들입니다. (화면 캡쳐한 파일이 업로드가 안 되서 손으로 그냥 옮겨봤습니다..^^;;; )
#gdb engine
(gdb)break engine.c:106 (engine.c에서 fork() 를 호출하는 라인에 breakpoint 를 설정)
(gdb)show follow-fork-mode
~~~~~~~~~~~~~ is "parent"
(gdb)set follow-fork-mode child (자식 프로세스를 하나만 생성해서 사용하기 때문)
(gdb)show follow-fork-mode
~~~~~~~~~~~~~~ is "child"
(gdb)run www.hani.co.kr
Starting program~~~~
Breakpoint 1, main(~~~~~~~~) at engin.c:106
(gdb)n
~~~
(gdb)n
~~~
(gdb)n
~~~
(gdb)n =>부모 프로세스가 수행하는 코드들
~~~
(gdb)n
~~~
(gdb)n
exit(0)
(gdb)n
Program exited normally
제가 제대로 수행한 거 맞나요? ^^;;
참고하시라고 engine.c 코드 간략화시킨 거 첨부화일로 올려봅니다.. 좋은 하루 보내세요..^^
댓글 달기