요즘에 코딩하는 학생들 좀 보니까...

antibug의 이미지

종종 후배들한테 알바꺼릴 주는데, 요즘 일하는걸 뒤에서 물끄러미
쳐다보고 있으면... '디버깅'을 전혀 안하는거 같네요... -.-;
코딩하다가 뻑나서(세폴? 또는 GPF? 뭐, 어찌됐건간에요...) 죽으면
어디까지 진행되다 죽었는지 추측(또는 printf, TRACE)해보고
예상되는 지점에서 소스만 째려보고 있네요. -.-; 그럴때마다 한마디씩
하는데, 그것도 한두번이지 참... 깝깝합니다.

하여튼 후배녀석들만 그런줄 알았는데 모 백신회사에 있는 대리녀석도
그런 얘기를 하더군여. 애들이 디버깅은 안하고 소스만 째려본다고...

음... 개구리 올챙이적 생각 못하는건지 모르겠지만, 전 안그랬던거 같은데...
헐...

뭐, 요즘 것들은... 투의 말을 하자는게 아니라 간단히 해결할 수 있는 방법이
있는데도 (그리고 그것의 사용이 필수라고 보여지는데도) 불구하고 사용하지
않는 후배녀석들이 갑갑해서 ㅤ넋두리 한번 올려봤습니다. 떱...

File attachments: 
첨부파일 크기
Image icon uf000621.gif37.7 KB
saxboy의 이미지

사용을 않는 것이 아니라, 사용을 "못"하는 것일 수도 있겠지요. 스택을 본다는 말의 의미를 모르는 분들도 꽤 많을텐데요.

맹고이의 이미지

흠... 제가 딱 그런 스타일인데... -_-;

일단 막 코딩하다가... 컴파일해서 돌려보고

이상한 부분을 추측해서 찾거나 printf를 이용하고... ;;

하다하다 안되면 gdb같은거 돌려보구요...

그럼... 어떻게 하는게 좋은 방법인가요?

jachin의 이미지

헛. -_- 사실, 저도 오래전에 코딩할 때에는 '디버깅'이라는 말이 소스중의 오류를 검색하는 것으로 알고만 있었지 실제로 디버깅 툴을 써본적은 그리 많지 않습니다. 대부분의 C언어 또는 C++ 언어 책에서는 디버깅 툴에 대한 언급이 없었기 때문이죠. 적어도 VC++ 에 대한 책에 대해서 (API나 MFC 관련 책자가 아닌 순수 VC++의 기능들에 대한 책) 읽어보지 않는 이상 디버깅 Trace 하는 걸 모르는 경우가 많았죠.

저도 대학교 입학하고 나서야 알았던 사실입니다. -_-;
소스가 문법상 정확해도, 오류가 나는 형태(메모리 누수나, 문자열 데이터의 마지막 널 문자 삽입 공간 부족 등...)는 모르면 트레이스를 해봐도 해결 안되는 경우가 허다하죠. 가끔 가다가 목적 코드를 봐서 해결봐야 하는 경우도 생기고...

디버깅에 관련한 책자가 나온다면 그것도 나름대로 좋을 것 같습니다. ( - -)a 물론 Effective C++ 이나, 여러 패턴 관련 책자가 많이 나와서, 그런 문제는 많이 줄어들었겠지만요...

choissi의 이미지

맹고이 wrote:
흠... 제가 딱 그런 스타일인데... -_-;

일단 막 코딩하다가... 컴파일해서 돌려보고

이상한 부분을 추측해서 찾거나 printf를 이용하고... ;;

하다하다 안되면 gdb같은거 돌려보구요...

그럼... 어떻게 하는게 좋은 방법인가요?

음 간단하게 죽는 거라면 printf나 파일 로그로 찍어서 해결하지만
한 두세번 해서 안되면 gdb로 진행을 합니다.
(심볼로딩이나 기타 작업으로 구차니즘의 압박이긴 하지만
일딴 디버깅 모드로 진입하면... 안잡히는 것은 거의 없더군요..)

울랄라~ 호기심 천국~!!
http://www.ezdoum.com

cinsk의 이미지

직업/취미로 코딩을 하다 보니, 나름대로 코딩 속도가 빠르다고 생각하는 사람입니다.

제 경우에는 코드를 마구 작성하고, (물론 머릿 속으로 구조는 잘 생각을 해야 겠죠.) 중요한 함수의 경우 일일히 test하는 main()을 짜서 테스트를 하고, 전체적으로 실행 파일이 만들어 지면, 일단 gdb부터 돌립니다.

test용 main()은 GNU/Linux의 fdisk와 같은 console interface를 만들어서 검사하는 게 경험적으로 빠르더군요. 물론 이 목적으로 쓸 menu library를 만들어 놓으면 더 작업이 수월하죠.

먼저 segfault와 같은 치명적인 오류가 발생하는지 검사하고 나서, 오류가 발생하지 않는다면,

Electric Fence (efence)로 같이 링크해서 다시 한번 segfault가 있는 지 검사합니다. (링크 옵션 '-lefence'

그 다음으로 glibc의 mtrace()를 이용해서 memory leak가 발생했는지 테스트합니다.

여기까지 끝났으면, 이제 shell에서 실행해서 원하는 기능이 제대로 되었는지 테스트합니다.

프로그램이 잘 짜졌다고 상사에게 보고할 때에는, 다시 한번 아무 기능없는 normal malloc을 쓰는 glibc로 컴파일 한 다음, memusage로 그래프 만들어서 보여주면 좋아하더군요. 쉽게 정보를 얻을 수 없는 데이타로 그래프를 그릴 때는, gnuplot을 사용합니다.

라이브러리 만들 때에는 Doxygen을 써서 문서화해주는게 좋고요.

ddd나 insight를 쓴다면 모를까 gdb를 직접 쓸 때에는 emacs나 xemacs의 debuger mode가 필수라고 주장합니다! 직접 gdb를 쓴다는 것은 시간 까먹겠다는 소리에 가깝다고 생각합니다.

GUI toolkit으로 작업할 때에는 메시지를 제 3의 프로그램에 넘겨주고 그 3의 프로그램이 메시지를 받아서 출력할 수 있는 자그마한 utility를 만들면 편하더군요. 일반 debugger를 쓰는 것보다 훨씬 빠르게 작업할 수 있습니다. http://pcrc.hongik.ac.kr/~cinsk/sw/spywin.html (참고로 이건, win32용이고, gtk용은 아직 packaging을 안해서.. 그리고 남에게 보여준다기 보다는 제 개인적으로 쓰려고 만든거라, 허접.. )

물론 X app라면 당연히 sync 해주어야 할 테고요..

:-)

Viz의 이미지

디버거를 바로 사용하는 것 보다 (가능하다면) printf등을 사용하여 에러가 나타나는 곳이 어느 곳인지 범위를 좁히고 그 주변의 코드를 관찰하여 해결하는 것이 먼저 아닌가요?

저는 그런 코드 관찰을 통해 해결 되지 않는 경우에만 디버거를 동원하는데...

최근의 작업에서는 동료와 짝 프로그래밍을 많이 해서인지 코드 관찰을 통해 거의 모든 버그를 해결했습니다.
(디버깅이 무지 힘든 임베디드 환경이기도 했지만... ;) )

저의 방법이 꽤나 일반적이라고 생각하는데 그렇지 않나요?

ps. 뭐, 전문 서적 같은 것은 읽어 보지 못해서 잘 안다고 할 수는 없네요.. ;;;

My Passion for the Vision!

albamc의 이미지

경험이 쌓일수록 시행 착오를 줄여나가는 방법을 스스로 채득하지 않을까요.

그 속도가 느리다면 어쩔수 없지만 그것도 다 자기 능력이니깐요.

^^*

albamc의 이미지

으... 이거 글삭제 어떻게 하지요?

^^*

fatman의 이미지

저는 프로그램 개발시 무조건 디버거를 사용합니다. ddd가 되었던 workshop을 사용하던. Compile option에 기본적으로 -g를 주고 compile하고, 프로그램 수행은 디버거에서 수행하는 것을 원칙으로 합니다. 문제가 없다는 것을 확인한 다음 최적화 옵션으로 compile을 합니다. gdb계열이든 dbx계열이든 break(stop)와 print 사용법 정도만 알고 있어도 어지간한 벌레잡기는 다 할 수 있을텐데...

...

ihavnoid의 이미지

저는 디버거도 쓰지만, 잘은 안 씁니다. 그대신, 기본적으로 어느 정도의 assertion을 깔아놓고 코드를 짭니다.
심할 때는 수행하는 코드 반, assertion 반, 뭐 이럴 정도입니다-_-;

눈으로 노려보는 것, 저도 자주 합니다-_-; 이유는 대충 두가지쯤 되는 것 같군요.

1) 어디까지 assertion이 통과되었는지 생각하면서, 눈으로 30초만 노려보면 어디가 잘못되는지 보이는 경우가 많음. (이런 경우는 사소한 실수인 경우가 많으며, 노려봐야 할 코드의 범위가 생각보다 적기 때문에, 할만합니다...)
2) 정말로 뭘 어떻게 살펴봐야 할지 모르겠어서 (디버거로 돌리고 돌려도 데이터가 다 맞는데 모르겠는 경우, 혹은 데이터가 뭔가 잘못 들어온 게 맞는데, 그 잘못된 데이터의 근원지를 도무지 알 수 없을때)

저는 디버거를 그렇게 좋아하지는 않습니다. 오히려 대량의 assertion을 깔아놓으면, 어느 부분이 잘못되었는지 찾기가 쉬운 것 같더군요.

음... 저의 경우에는 요즘은 알고리즘 구현을 많이 합니다. 그래프 알고리즘, 뭐 이런거요...

저도 예전에 디버거를 안 쓰고 개발을 하는 것은 불가능하다고 생각했었습니다.
근데 얼마전에 놀라운 사람을 봤었습니다.... 얼마전에 학회에 갔다가, 현재 IBM에서 코드 검사를 하는 툴을 개발하는 사람을 만났습니다...
(코드를 실제로 수행시키지 않고 포인터 에러의 가능성이라던지, 버퍼 오버플로우를 검사해주는 프로그램들)

분명 컴파일러 종류의 애플리케이션이기 때문에 엄청나게 복잡한 프로그램일텐데, 이런 사람들은 어떻게 개발을 할까 궁금해서 물어봤는데, '나는 디버거를 쓸 줄 모릅니다.' 라고 자신있게 얘기하더군요.. 그럼 어떻게 개발을 하는가 물어봤더니, '자기 자신의 프로그램에 대해서 논리적으로 옳도록 한다'고 하더군요-_-;;; 뭐 정확히는 이해를 못 했지만, 자신이 짜는 프로그램에 대해서, '예외사항이 없는 경우'임을 명확히 증명을 하고 그다음에 들어간다는 식인 것 같았습니다.

뭐 저나 그 사람이나 시스템과 강하게 상호작용을 하는 프로그램을 만드는 것이 아니며, 명백한 single-thread인 경우에 코딩을 하고 있기에 가능한 일일지도 모르겠습니다. 근데 많은 경우에는 디버거 없이 자체 생산한 debug log들과 assertion으로 해결이 되는 것 같더군요.

요즘은 vc++을 쓰는데, TRACE() 매크로랑 ASSERT() 매크로를 씁니다. (매크로 맞죠?) gnu환경에서는 나름대로 dprintf() 함수를 만들고, ASSERT() 매크로를 만들어서 씁니다.

Consider the ravens: for they neither sow nor reap; which neither have storehouse nor barn; and God feedeth them: how much more are ye better than the fowls?
Luke 12:24

saxboy의 이미지

Quote:
ddd나 insight를 쓴다면 모를까 gdb를 직접 쓸 때에는 emacs나 xemacs의 debuger mode가 필수라고 주장합니다! 직접 gdb를 쓴다는 것은 시간 까먹겠다는 소리에 가깝다고 생각합니다.

글쎄요... 저는 직접쓰는데요. :-)
디버거 안에서도 tab으로 completion도 잘되고 하니 디버거 모드가 굳이 필요하다는 느낌을 받은 적은 별로 없었습니다. 취향문제이긴 하지만 VC++의 디버거는 저는 정말 불편한 인터페이스라고 생각하고 있거든요.

사실은 저도 디버거로 런타임으로 트레이스 하면서 찾아가는 경우보다는 printf를 훨씬 애용하는 편이라서 뭐라고 이야기하기는 어렵네요. 사실은 디버거로 display나 print 하는 것보다는 printf로 중간 결과를 깔끔하게 적어두고 찾아가는 편이 훨씬 쉬운 경우가 많더군요. 가끔 printf조차 적기 귀찮은 경우에는 유용하게 써먹기는 하지만...
무조건 디버거를 쓰는 경우가 하나 있기는 하군요. segfault 먹었을때 스택보기!

NeoTuring의 이미지

그 후배들이 제대로 하고 있는것 같군요.

사람의 취향마다 다르긴 하겠지만, 정석대로라면 무턱대고 디버거를 돌리는것보다는 먼저 코드리뷰를 하는것이 맞습니다.

(코드를 째려보는것도 좋은 코드리뷰의 한 예죠.)

저는 개발시 될 수 있으면 디버거는 돌리지 않는 스타일입니다. 문법오류를 제외한다면 대부분의 오류는 생각했던 프로그램의 로직이

예상밖의 행위를 할때 발생합니다. 예상밖의 행위를 예상범위 안으로 포함시키는것이 에러의 원인을 애초에 코드상에 투입시키지 않는 방법이 됩니다.

디버거로 디버깅을 하는 행위자체는 '결과'를 가지고, '원인'을 추적하는 것이지만, 코드리뷰는 '원인'자체를 찾아 그것을 방지하는 방법이기 때문에

순서상으로 봤을때 코드리뷰를 하고서 디버거를 돌리는것이 디버거만 사용했을때보다 훨씬 효과적입니다.

MasterQ의 이미지

antibug wrote:
죽으면
어디까지 진행되다 죽었는지 추측(또는 printf, TRACE)해보고
예상되는 지점에서 소스만 째려보고 있네요. -.-; 그럴때마다 한마디씩
하는데, 그것도 한두번이지 참... 깝깝합니다.

흠.. 그게 좋은 방식 아닌가요? 쉽게 해결하려고 하다가 또 다른 버그를 만들어낼수 있고요... 자기가 다 짠거라면 쉽게 쉽게 해결할 수 있겠지만 다른 사람이 짠거라면 더더욱 전체적인 그림을 이해하면서 debugging을 하는게 후에 더 골치아픈 dirty fix 를 찾아내는 수고를 덜 하게 될것 같네요. (pain in the ass)

gurugio의 이미지

cinsk 님

메모리 닉을 찾아내는 것에 대해 조금더 설명해 주실 수 있나요?

네트워크 프로그래밍을 하다보니 이게 잘 돌다가도

가끔 닉이나서 엉망이 되버리는 경우가 생긴다고 하더라구요.

규칙적으로 그런것도 아니라서 찾기도 힘들다고 하던데..

메모리 닉을 찾는 디버깅 기법을 꼭좀 알려주시면 감사하겠습니다.

gurugio의 이미지

그래도 뭐니뭐니해도 로직에 대해서 문제가 없도록 하는게 최고지요.

로직에만 문제가 없으면 자잘한 오타나 segfault 같은 것은

대강 어느 부분에서 버그가 날만한지

감을 잡을 때가 많자나요.

휴.. 로직을 잘 만드는게 참 어려운 일이지요..

antibug의 이미지

글쓴넘입니다.
듣고 보니 그렇네요. ^^; 굳이 디버깅할 필요가 없거나 없도록 해야 한다는
데는 동감입니다. 오류에 대해서 코드를 살펴보는 것도 맞는 말씀이네요.

그래도 당장 디버그 모드에서 뻑났는데 그냥 디버그 종료하고 코드 살펴보는건
이해할 수 없네요. ^^; 디버깅하는 것좀 갈켜 줘야겠습니다.

--------------------------------------
재미없는 일은 하지 말자는 인간 쓰레기.
-.-;

saxboy의 이미지

Quote:
메모리 닉을 찾아내는 것에 대해 조금더 설명해 주실 수 있나요?

네트워크 프로그래밍을 하다보니 이게 잘 돌다가도

가끔 닉이나서 엉망이 되버리는 경우가 생긴다고 하더라구요.

규칙적으로 그런것도 아니라서 찾기도 힘들다고 하던데..

메모리 닉을 찾는 디버깅 기법을 꼭좀 알려주시면 감사하겠습니다.

메모리 디버거를 몇개 작동시켜보시면 됩니다. mpatrol, valgrind, electric fence, memprof 등을 검색해보시면 관련 스레드를 여럿 찾으실 수 있을 것 같아요. 하지만 역시 자주 실행되지 않는 exec path 어딘가에 있는 릭은 여전히 찾아내기 힘들지요. 다른 사람이 만든 코드에서 릭을 찾는다면 모를까, 자신이 처음부터 작성하는 것이라면 코드를 작성하는 그 순간에 메모리에 대한 강박관념을 가지고 작성하는 방법밖에는 없어보입니다. 또는 직접 reference count를 작성해서 사용하는 것도 한가지 방법이 될 수 있겠지요.

matrix의 이미지

여기까지 읽어보니 디버거를 쓰는 사람들이 더 많은 듯합니다.
요즘은 그런 모양이죠?

printf 말고는 디버거를 사용해 본적이 없는 사람인데 ..
(개인적으로 디버거를 사용하는건 초보나 하는짓이다.. 이렇게 생각합니다만)
장점도 있는 모양이군요..

이상하긴 합니다.
자기가 짠 프로그램이 논리적으로 이상이 있는지도 모른다면 그건 누가 짠겁니까? 보조수단이어야 할 디버거가 주력이 되어야 하다니..

어쨌든 ..
조금 의외긴 합니다.

How do you define Real?

gurugio의 이미지

앗.. 저 초보 맞습니다.

프로그래밍한지 이제 3년째 접어드네요.

아직 초보라 디버거를 안쓰면 잘 안될때가 많습니다.

perky의 이미지

저도 아직 초보라서 그런지 디버거 없으면 디버깅 하기 힘들더군요..
디버거 없으면 당장 어떻게 먹고 살 지 앞이 깜깜합니다. T_T

You need Python

hey의 이미지

perky wrote:
저도 아직 초보라서 그런지 디버거 없으면 디버깅 하기 힘들더군요..
디버거 없으면 당장 어떻게 먹고 살 지 앞이 깜깜합니다. T_T

퍼키님이 그런 말씀 하시면 아무도 안 믿습니다..


----------------------------
May the F/OSS be with you..


jachin의 이미지

hey wrote:
퍼키님이 그런 말씀 하시면 아무도 안 믿습니다..

맞아요. 저같은 사람은 프로그래머축에도 못끼게 되어버려요. T-T

cjh의 이미지

분명히 대학 입학 무렵까지는 소스를 노트에 적어두고 나서 대충 짜고 나서 눈으로 확인하고 난 후에야 편집기로 입력하고 돌렸던 것 같네요(주로 ASM/BASIC/C소스...) 나중에 거의 컴퓨터 앞에 앉아있게 되면서부터 직접 짜고 말았지만...

요즘에는 소스를 손으로 적어보는 분 거의 없을 겁니다(Visual Studio계열같으면 거의 불가능이죠...). 하지만 분명히 연습해 둘 만한 습관입니다. 컴퓨터 없이도 코딩이 된답니다. :)

디버거는 보통 풀 수 없는 문제(소스만 째려보는 것이 시간 낭비라고 생각되는 경우)일 경우에만 동작시켜 봅니다. 간단한 건 gdb CLI를 그냥 쓰지만 좀 어렵게 해 보려면 아무래도 emacs gud나 ddd가... (DDD는 참 좋은 어플리케이션입니디만 아무래도 좀 무겁죠)

오래 돌 서버라면 분명히 메모리 리크를 체크하지만(웬만하면 동적할당 안하는 쪽으로...) 실행하면 곧 종료할 어플리케이션은 사실 segfault가능성 이외에 메모리 누수 크까지는 잘 안합니다. 어차피 심각한 거 이외에는 종료하면 OS가 다 거두어 가므로... 물론 그 정도까지 되면 그냥 script language로 짜고 말겠죠(작성 속도상).

--
익스펙토 페트로눔

girneter의 이미지

부끄러운 이야기지만
울 팀은 프로그래밍 실력자가 없어서리...

전에 외부에 파견나가서 프로그래밍을 할 일이 있었는데
거기 연구원들은 실력이 워낙 출중하기로 자타가
공인한 분들이었죠.

그래서 다른 건 몰라도 이 사람들 디버깅을 어떻게 하는지
어떤 툴을 사용해서 어떻게 접근하는지
확실하게 배워오리라 맘 먹었습니다.

가서 옆에서 봤더니
printf 를 마구 찍더군요. -_-;;
다만 똑같이 찍어도 뭐가 문제인지 판단하는 능력에서
차이가 난다는...

개념없는 초딩들은 좋은 말로 할때 DC나 웃대가서 놀아라. 응?

Necromancer의 이미지

저도 디버깅할때는 printf나 기타 다른 방법으로 흔적을 남기는 방법을 쓰는데

디버거 한번도 안써봤음

Written By the Black Knight of Destruction

pebiman의 이미지

초보자의 경우 혹은 경험이 부족한 개발자의 경우, 앞날을 생각해서라도, 삽질해보는 것도 괜찮은 방법이라고 생각합니다.
물론 gdb와 같은 디버거가 강력하다고는 하지만, 삽질의 노하우도 아주 그에 못지않게 중요하다고 생각합니다.

쓰레기는 쓰레기통에...

houyhn의 이미지

저는 리눅스 커널에서 주로 작업하기 때문에
디버거를 쓰고 싶어도 못 쓰거든요.
임베디드 장비여서 kdb를 넣어놓을 수도 없고...
해서 버그 한번 찾으려면 printk를 무진장 많이 넣어서
커널 모듈 올렸다 내렸다 반복합니다.
더 편한 방법이 있으면 좋겠는데, 어쩔 수 없는 환경이라서요.

그냥 이런 경우도 있다는 겁니다. ^^

cinsk의 이미지

gurugio wrote:
메모리 닉을 찾아내는 것에 대해 조금더 설명해 주실 수 있나요?

저는 주로 glibc 기능(mtrace, muntrace)을 쓰는데, portable한 방법은 아니겠죠..
더 알고 싶으시면,

$ info libc memory "memory allocation" "allocation debugging"

을 쳐 보시면, mtrace/muntrace 레퍼런스와 사용 예제가 나옵니다.

ihavnoid wrote:
기본적으로 어느 정도의 assertion을 깔아놓고 코드를 짭니다.
심할 때는 수행하는 코드 반, assertion 반, 뭐 이럴 정도입니다-_-;

동감입니다. 저도 assert(3)을 매우 애용하는 편입니다.

웬만하면 소모적인 논쟁은 하고 싶지 않습니다만:

matrix wrote:

개인적으로 디버거를 사용하는건 초보나 하는짓이다.. 이렇게 생각합니다만

전 이 말에는 동의할 수 없을 거 같습니다.

matrix wrote:
이상하긴 합니다.
자기가 짠 프로그램이 논리적으로 이상이 있는지도 모른다면 그건 누가 짠겁니까?

ihavnoid wrote:
분명 컴파일러 종류의 애플리케이션이기 때문에 엄청나게 복잡한 프로그램일텐데, 이런 사람들은 어떻게 개발을 할까 궁금해서 물어봤는데, '나는 디버거를 쓸 줄 모릅니다.' 라고 자신있게 얘기하더군요.. 그럼 어떻게 개발을 하는가 물어봤더니, '자기 자신의 프로그램에 대해서 논리적으로 옳도록 한다'고 하더군요

주로 이론에 치우치신 분들이 이런 말씀을 하시는데, 흠.. 글쎄요. logical이라는 말을 어떻게 해석해야 될 지 사실 전 막막하기만 합니다. logical을 program algorithm을 의미한다고 가정해도 될까요? 쉬운 예로 sorting을 아주 그럴듯하게 잘 설계를 하고 코딩에 들어 갔습니다. typing miss로 conditional expression (foo == 0)을 (foo = 0)으로 썼다거나, 변수 초기화를 빼먹었다거나, 등등.. 이런 에러를 logical error라고 할 수는 없겠죠? 그럼 debugger 쓰시는게 빠릅니다.

그런식으로 자신있게 (얄밉게) 말해보라면 저는 이렇게 말하고 싶군요:

저는 debugger를 애용하는 편입니다. 제가 작성한 코드는 논리적으로 하나의 결함도 없고, 단지 가끔 위에서 말한 사소한 실수만 있을 뿐이므로, 이런 것들만 debugger로 잡아주면 남보다 훨씬 빠르죠. Code review? 논리적으로 결함이 없으니 할 필요도 없고요..

아 물론 제가 진짜로 저렇게 말하고 다니거나 저렇게 생각한다는 건 아닙니다. ^^;

음.. 갑자기 이 커트(아래 첨부)가 떠오르는군요: A.J.가 DOS EDIT 프로그램을 써서 편집하는게 끔찍했다고 하니, Mike는 edlin을 썼다고 뻐김. A.J.는 다시, 자신은 COPY CON을 썼다고 뻐기고. Mike는 ECHO를 썼다고 우김. 서로 욕하고 있는데, Miranda가 와서 자신은 자석으로 inode를 직접 편집했다고 얘기함: User Friendly 만화랍니다. Best of the best of the best geek comics!

음.. 조금 과장한다면.. ihavnoid님이 인용하신 IBM programmer분, debugger를 안쓰신다는 분들 editor는 무엇을 쓰냐고 묻고 싶군요. 논리적으로 완벽하게 머릿 속에서 정리되어 있고, 결함이 없게 작성되어 있다면, ed(1)도 필요없을 거 같고, DOS/Windows라면 COPY CON으로, *nix family라면 cat >> file 로 충분할 거 같다고 말해 주고 싶습니다. 아니, compiler도 필요 없겠군요. C로 작성한다면 C 문법 패턴을 machine lanauge code로 매핑해주는 테이블을 기억에 두었다가 그냥 쓰시면 될텐데요..

그분 일이 "코드 검사를 하는 툴을 개발"하는 것이라는데,, 훗. debugger는 필요없으면서 그런 툴은 필요해서 개발하나 보군요.

욕하실 분이 있을지는 모르겠습니다만, 제 주변에서 debugger를 안 쓰는 분들은 대부분 "배우기 귀찮아서"가 현실적인 이유였던 것 같습니다.

물론! debugger를 쓸 수 없는 환경은 당연히 예외겠죠. Kernel porting하면서 printk만 쓸 수 있다거나, embedded boot loader 관련이면 더욱 심할테고요.. 그 때 쓰는 ICE, TRACE32 등등의 JTAG debugger도 debugger이긴 하네요.

댓글 첨부 파일: 
첨부파일 크기
Image icon 0바이트
lu4moon의 이미지

저는 최근에서야 디버깅을 하기 시작했답니다

예전에는 값을 파일로 찍어보거나 했었는데, 왜 그 값이 나오는지 찾기 힘들더라고요.

아직 능력이 미천하여 그런지는 모르겠으나 디버깅이 더 편하더군요 :wink:
(디버깅이 되는 환경에서는요)

You wrote 'fool self' magic on your book.

youlsa의 이미지

gurugio wrote:
cinsk 님

메모리 닉을 찾아내는 것에 대해 조금더 설명해 주실 수 있나요?

네트워크 프로그래밍을 하다보니 이게 잘 돌다가도

가끔 닉이나서 엉망이 되버리는 경우가 생긴다고 하더라구요.

규칙적으로 그런것도 아니라서 찾기도 힘들다고 하던데..

메모리 닉을 찾는 디버깅 기법을 꼭좀 알려주시면 감사하겠습니다.


리눅스에서 작업하시는거라면 valgrind하나면 웬만한 메모리 릭은 다 잡을 수 있습니다.

=-=-=-=-=-=-=-=-=
http://youlsa.com

서지훈의 이미지

음...
저같은 경우도...
아주 많은 부분을 printf() 이놈에게 의존을 하는 편입니다.
그다음으로 이것저것해서...
gdb, strace, ltrace, ...
이것들을 사용을 해서 디버깅을 하죠...
근데... 이건 그사람의 기호일 뿐이고...
꼭... 정도는 없는것 같습니다.

자기가 편한데로...

근데... 에러가 났는데...
"왜 그런지 모르겠는데요?" 이런 말 자주 하는 사람은 좀 문제가 있을듯 하네요...
에러가 나면은 대충 뭐가... 어디가 문제 일지는 알아야...

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

saxboy의 이미지

Quote:
분명 컴파일러 종류의 애플리케이션이기 때문에 엄청나게 복잡한 프로그램일텐데, 이런 사람들은 어떻게 개발을 할까 궁금해서 물어봤는데, '나는 디버거를 쓸 줄 모릅니다.' 라고 자신있게 얘기하더군요.. 그럼 어떻게 개발을 하는가 물어봤더니, '자기 자신의 프로그램에 대해서 논리적으로 옳도록 한다'고 하더군요-_-;;; 뭐 정확히는 이해를 못 했지만, 자신이 짜는 프로그램에 대해서, '예외사항이 없는 경우'임을 명확히 증명을 하고 그다음에 들어간다는 식인 것 같았습니다.

지금까지의 경험으로는 이런류 -- 수백번씩 루프가 있는 손으로 쫓아가기 힘든 프로그램들 -- 은 절대 디버거가 print를 따라갈 수 없다고 생각합니다. 전 회사에서 몇년 작업하던 프로그램이 대강 이런 종류의 프로그램인데, 디버거로 watchpoint 부터 시작해서 별짓을 다 해봤는데도 printf가 훨씬 편하더군요. 물론 로그가 수백줄 쌓인다는 문제도 있긴 합니다만... 흐흐...

하지만, 역시 저도 -- 디버거를 자주 사용하는 것은 아니지만 -- 디버거가 없이는 코딩을 못하는 종족에 속하는 것 같아요 한시간을 코딩하면 한두번쯤은 꼭 디버거와 놀게 되는군요. :-)

gurugio의 이미지

저같은 초보들은 대체로 이런 방법을 쓰는 것 같습니다.

일단 모든 함수 호출때마다 반환값이 에러인 경우는 fprintf(stderr..)을 써서

메세지를 출력하구요

루프에서 그럴 경우에는 에러 메세지를 파일로 적어서

나중에 자세히 읽어보곤 합니다.

전에 메모리 할당에 관한 시물레이션을 만들때는

수백줄되는 걸 읽느라 무지 고생도 했었지요.

그러다가 어느 지점에서 에러가 나는지 알아낸다면

그쯤에서 디버거를 돌려보면

아차~~ 또 삽질했구나.. oops 하고 생각할 때가 많지요 뭐...

근데 그래도 안잡히는 것은 대부분 로직상의 문제가 많더라구요.

또 가끔은 C의 특성을 이해못해서 잘못 코딩한 것들도 있구요

문법을 아직 정확하게 몰라서 그러지요 뭐..

으... 여하튼 초보들은 닥치는 대로 배운답니다.

좋은 디버깅 기술들을 말씀해주셔서 감사드립니다.

confide의 이미지

print나 디버거나.. 둘다 필요하겠지만, 처음에 글 쓰신분의 의도는...

선택의 여지 없이 printf를 쓰거나 그것 조차도 모르는 것 같은 후배를 말씀하시는게 아닌가 하네요.

경험이 쌓이기 위해서는 시간이 필요하겠지요 :)

------------------
나는 바보

MasterQ의 이미지

cinsk wrote:
ihavnoid wrote:
기본적으로 어느 정도의 assertion을 깔아놓고 코드를 짭니다.
심할 때는 수행하는 코드 반, assertion 반, 뭐 이럴 정도입니다-_-;
동감입니다. 저도 assert(3)을 매우 애용하는 편입니다.

저두 강츄 ^- ^

treeshad의 이미지

한 10년째 이곳 저곳 왔다 갔다하면서 여러 개발환경들을 만져봤습니다.

그런데, 디버깅의 결론은...

1. 코드를 뚫어져라 쳐다봐라. -> 논리의 오류를 찾는다.
2. 값을 찍어본다. -> 논리에 맞게 값이 변화 했는가 확인한다.

이 두가지는 어떠한 환경에서도 사용가능한 가장 막강한 디버깅 방법이더군요.
핸펀 애플 개발시 사용가능한 디버거 있으면 좀 알려주세요.
임베디드 시스템에 개발시 제대로 사용할 만한 디버거 있음 알려주세요.
마이컴 개발시 쓸만한 디버거 있음 알려주세요.

아마도 찾기 힘드실 겁니다.

과거 엠에스의 그늘아래에서 비절씨의 우산아래 있던 시절은 그나마 디버거의 덕이라도 봤지만...

임베디드 시스템에선 비절씨의 디버거가 너무나도 막강해 보이네요.

전 현재 셋탑박스 개발자로 일하고 있는데,
과외의 일로 DVR을 손대게 되서 이렇게 KLDP에 나타났습니다.

여러분들께 많은 도움을 받아야 할것 같습니다.
임베디드 리눅스는 처음이라... ^^

cwryu의 이미지

휴대폰, DVR 만져봤지만 디버거 안 쓰고 개발한 적은 없습니다.

JTAG, 리모트 등 부가적인 장비나 작업이 필요하고 하드웨어 설계단계에서 고려해야 되서 귀찮고 제약이 심할 뿐이죠.

마이컴은... 종류에 따라 안 되는 것도 있겠지만 에뮬레이터 등 장비만 있으면 가능.

treeshad의 이미지

임베디드 개발시 디버거 사용합니다.

그러나 아시겠지만 JTAG을 통해서 리모트 디버깅한다는 것이 얼마나 속터지는 일인지 잘 아실겁니다.
또한 에뮬레이터를 사용하는 방법도 있겠지만 문제는 어떤 형태의 작업이냐에 따라서 에뮬레이터가 무용지물인 경우가 많다는 거죠.

현재 ST5105/CnM의 새로운 CPU/MPEG4 기반의 DVR. 이런 작업들에 투입되고 있지만,
가장 훌륭한 디버깅 툴은 UART를 통해 출력하는 스트링들이더군요.

경험해 보셨겠지만 RTOS의 특성상 디버거로 브레이크포인트 잡아 놓고 쉽게 trace되진 않더군요.
메모리를 덤프하거나 하지 않는 한은 UART 쪽이 훨씬 좋은것 같다는 제 개인적인 생각입니다.

아~~! 전 TC로 프로그래밍 시작하여 VC로 윈도우즈 기반 개발을 주로 했었습니다.
이 경우엔 printf()나 MessageBox() 같은 넘들 사용안합니다. 무조건 디버거를 통한 trace를 합니다.

그런데 embedded로 전향하고나서는... 흑흑...
초반에 눈물께나 흘리고 가슴 꽤나 쳤습니다. 디버깅하는데 답답해서....

저의 결론 호스트 피씨에서 도는 플그램들은 디버거돌리는게 효율적이다.
임베디드는 printf()로 열심히 찍는게 장땡이다. ^^

오늘도 좋은 하루 되세요.

나는오리의 이미지

treeshad님 덕분에 다시한번 좋은 글을 읽게되네요. :)

---
관심과 간섭은 동전의 양면과 같다. - 세계정복을 꿈꾸는 오리

JuEUS-U의 이미지

솔직히 하드웨어 쪽에 손대지 않는 이상
디버거 돌릴 일이 별로 없습니다...

왠만큼 삽질을 하다보니
( 배열 1 덜잡아서 오작동 한다거나..
scanf에서 & 안붙였거나...
이런걸 또 1주일 동안 디버그 한다거나... )

코딩미스 보다는
설계 에러가 훨씬더 많더라구요...

설계 에러는 쉽게 찾을 수 있으니
역시 코딩에러를 줄여야겠지요 ^^;;;

삽질도 하나의 좋은 추억과 경험이 아닌가 싶습니다.

plustag의 이미지

생각보다 printf로 찍어보시는 분들이 많이 계시네요..

누구냐 넌?

dude7853의 이미지

저도 임베디드 쪽이라서, 주로 printf에 의존한다는 글을 올릴려고 보니,
2003년도 글이군요.

디버거를 사용하는 게 좋은 습관이라는데는 이견이 없습니다. 게다가 요새는 다들 GUI 디버거가 포함되어있는 IDE에서 프로그래밍하는게 일반적이니 더 그러하겠죠.

저도 win32 application을 만들때는 디버거에 많이 의존하곤 했습니다. printf같은건 써본적이 없었죠. 그런데 회사에 들어와서 임베디드 프로그래밍을 하다보니 printf에 의존하게 되더군요.

뭐 딱히 디버거를 무시하는게 아니라 일단 쓸만한 디버거가 없습니다. gdb를 올릴 수 있긴하지만, 올리는게 또다른 일거리를 만들어 내는 거라서 안하게 되더군요. 또한 주로 커널 작업을 하기 때문에 printk에 의존하는 경우도 많습니다.(몇몇 정보는 proc파일시스템을 이용하기도 합니다) 심지어 제가 일하는 회사는 ICE 장비도 없기 때문에 부트로더 작업할때는 보드의 LED로 printf를 대신하는 경우도 많습니다 :)

이런 식으로 디버거를 별로 안써봐서인지, (제가 주로 하는 일인) 장시간동안 동작하는 과정에서 벌어지는 버그에는 디버거가 별 소용이 없는듯합니다. 제 짧은 견해로는 디버거는 동작을 시켰을때 바로 알 수 있는 버그에만 유용한 듯 합니다. 디버깅 포인트에 언제 진입할지 모르는, 즉, 문제상황이 언제 벌어질지 모르는 경우에는 printf나 log를 이용하는게 훨씬 좋은 방법이라고 생각이 듭니다.

물론 assertion을 이용하는게 좋을 거라는 생각을 하고 있기는 한데, 습관을 고치기가 힘들군요.

나는오리의 이미지

서울까지 가는데 걸어가는 것보단 차를 타고 가는게 좋습니다.
하지만 차가 지나가기 힘든 시장길은 억지로 차를 타고 지나가기보단 걸어서 가는게 더 좋지요.

---
관심과 간섭은 동전의 양면과 같다. - 세계정복을 꿈꾸는 오리

김성진의 이미지

소프트웨어의 복잡도와도 관련이 있어보입니다.

단순한 기능의 디버거를 사용한다면, 일반 printf와 크게 차이가 없어 보입니다만,

진짜로 디버거를 사용하면 편리한 곳이 많습니다.

저는 solaris의 dbx가 가진 기능중 stop access 라는 기능이 있습니다.

특정 메모리에 대한 접근시 event를 발생하는 것인데,

다수의 쓰레드가 복잡하게 돌아가는 환경에서 corruption 비슷한 동작을 하는

놈을 잡는데는 이이상 편리한 기능은 없다고 생각합니다.

실제로 디버거가 가진 편리한 기능을 알고 나면, printf와는 비교할 수 없을 것이라

생각합니다.

디버거의 유/무용론을 말하기 전에 실제 그 디버거가 가진 모든 기능을 review 하신 후에

하시는 것이 이치에 맞을 것 같습니다.

디버거가 printf의 super set이 아니던가요?

마치 purify와 같은 전문툴을 한번도 사용하지 않고, 메모리 관련 에러는 그런 것 없어도

잘 잡을 수 있다 라고 단정짓는 것과 비슷한 것 같아 드리는 말씀입니다.

물론, case에 따라 다른 것을 사실입니다.

그러나, 무조건 printf가 디버거보다 낫다는 주장은 조금 설득력이 떨어져 보입니다.

김성진

고도의 추상화, 극도의 구체화, 에디슨을 그리워하다.

이한길의 이미지

2003년도 글이었군요.. 저도 오늘 첨 보고..진지하게 읽고 있었습니다.
대학교 1학년 들어가기 전에 code complete의 저자이기도 한 steve maguire의 저서
writing solid code를 읽어본적이 있습니다.

그 책이 94년에 나온것이긴 하지만... (그때도 디버거있었겠죠?)

지금은 오래되서 잘 기억이 나지 않지만
그 책에서는 주로 ASSERT를 강조했던것 같습니다.
----
먼저 알게 된 것을 알려주는 것은 즐거운 일이다!
http://hangulee.xo.st
http://hangulee.egloos.com/

----
먼저 알게 된 것을 알려주는 것은 즐거운 일이다!
http://hangulee.springnote.com
http://hangulee.egloos.com

ktship의 이미지

뭐 저도 시스템 구상하고 직접 구현하는 경우는..
디버거는 생각하기 힘든 에러 잡을때 빼고는 잘 안쓰는 편인데요..

이건 그때뿐..

남의 소스 고칠때는 디버거 없이 힘들겠죠?
학교에서 배우는 수준이면 괜찮을까 싶지만.. 여기 계신분들 대부분은 거의 현업이시니..
일단.. 시스템 구조 문서나 api문서가 없는 상태에서
그냥 눈으로 하겠다는건.. 뭐라해야되나.. 자네가 천잰가? 라고 질문하고 싶어진다고 해야되나?

trace나 assert도 결국 자기가 의심스러우니깐 쓰는 것이때문에
남이 짜논 것에 에러가 뜨는 경우는 별 도움이 안될까 싶은데..뭐 아닐수도 있습니다.
프로젝트의 크기라던가.. 어떤 환경이라든가.. 차이가 있겠죵~

하여간 전 지금 하고 있는 일은 디버거가 없으면 쫒겨날지도 모르는 판~ 있어도 힘들구만~

lawch의 이미지

어떻게 끝이 날지 끝까지 와봤는데,
예상대로 그때그때 달라요군요.

저도 gdb랑 ddd광팬이었는데,
이거 단순히 디버깅용외에도
복잡한 남의 코드 분석할때 유용했던 기억이 있네요.

그런데, 요즘은 ML류의 함수형언어를 공부하는데
이건 아예 debugger가 없다는군요.
(몇몇 함수형언어는 있기도 하다는데...)
제가 그러면 어떻게 디버깅하냐고 물으니
"그냥 코드를 뚫어지라 쳐다보거나,
화이트보드를 이용한다"
고 하더군요...대략 낭패.
저같은 초짜는
어디 tracer라도 있는지 찾아보는 중입니다.

superwtk의 이미지

저는 주로 Java 를 쓰기 때문에 stack trace 만 잘 들여다봐도 대부분의 문제는 금방 해결됩니다. (이클립스나 넷빈즈에 있는) 디버거는 binary tree 를 직접 구현한다거나 할때 말고는 써본 기억이 별로 없네요.

개인적으로는 JUnit Test 가 디버거보다 더 유용하다고 생각됩니다. (제가 만나는 대부분의 문제들에 대해서)

http://blog.superwtk.com/

사랑천사의 이미지

그래도 우선은 코드 분석을 거치고 그래도 안 되면 GDB같은 디버거를 쓰는 것이 좋아 보입니다... 대부분은 그냥 코드를 보다 보면 잡히던데요... 또는 컴파일러 경고 뜨는것만 봐돠 대충 뭐가 버그와 관련이 있느지 프로그램이 왜 죽는지 대강은 알 수가 있긴 하더군요... 프로그램이 커지면 모르겠지만... 디버깅의 기초는 소스를 분석 하고 함수 실행 중간 중간에 디버그 출력문을 넣어 두는 거라고 생각 합니다. 물론 그렇게 배운 탓도 있겠지만요.
----
일어나라! 싸워라! 그리고 이겨라!
다만!!! 의미 있는 것에 그 힘을!!!
그 능력과 노력을!!!

사람천사

지리즈의 이미지

저같은 경우에는 C는 1차적으로 컴파일러 에러,워닝 잡고 나면,
이하 발생하는 모든 오류는 디버거 없이는 도저히 못잡겠더군요.

물론 printf 및 assert 다 쓰지만, 그래도 마지막에는 디버거.

결국 디버거갈 거라, 그냥 디버거 씁니다.

printf는 큼직큼직한 로직 추적용으로만. 그래야 디버거 쓸때도 편하니...

There is no spoon. Neo from the Matrix 1999.

There is no spoon. Neo from the Matrix 1999.

사랑천사의 이미지

실력이 별로 좋은 편은 아니지만... 왼만한 버그는 그냥 소스랑 컴파일러 메세지만 봐도 아는데.. 때로 세그먼트 어긋나 버리는 무지막지한.. 그리고 치명적인 에러가 나는 프로그램들이 있는데 그럴 때는 정말 디버거를.. 크흠... 무엇보다 프로그래머 십계명을 어느정도 따른다면 큰 문제는 없는거 같네요... 논리의 구멍, 상황 변수... 흐흠... 잘 난 놈도 아니면서 떠들어 죄송합니다...
----
일어나라! 싸워라! 그리고 이겨라!
다만!!! 의미 있는 것에 그 힘을!!!
그 능력과 노력을!!!

사람천사

daybreaker의 이미지

디버그 모드에서는 잘 되는데 일반 컴파일 모드에서는 안 되고.. fprintf를 찍으면 잘 되는데 그걸 안 찍으면 안 되고.. 똑같은 옵션으로 컴파일했는데 gdb 돌리면 잘 되는데 그냥 실행하면 안 되고.... (뭐 세그폴이나 그런 것도 아니고 그냥 block되어버리는...) 뭐 한 10번 실행하면 그 중 한 두번은 잘 되고...

이런 건 어찌해야 할까요? ㅠㅠ

ps. 근데 assert에 대해서 찾아보니 이게 제가 나름대로 만들어서 쓰던 매크로랑 비슷한 기능을 하는 거였군요. manpage 보니까 "디버깅모드에서 사라지는 Heisenbugs(불확정성버그)를 만들 수 있다"라는데.. 바로 이 문제 때문에....-_-;

조경민의 이미지

저같은 경우는 printf() 넣는게 귀찮아서 디버거 돌립니다.
디버거를 돌릴 수 없는 상항에서만 printf()로 로그를 남기죠...
printf()넣는것 자체가 엄청난 노가다 같다는 느낌이 드네요.

올해목표 10kg 살 붙이기

nomoreid의 이미지

디버거를 사용해서 편한 경우에는 gdb를 직접 써서 디버깅을 합니다.
물론 printf , file log 등등을 병행해서 처리하구요.
printf등의 log에서 이상한 부분의 범위를 좁히고 디버거에서 확신하는 작업을 하게 되죠.

메모리 버그는 뜬금없이 엉뚱한 부분의 메모리를 깨는 경우가 많으니 자주 깨지는 주소에 브레이크 포인트를
걸어서 잡을 수 있습니다.

gdb에서는 메모리주소에 조건을 걸고 해당 메모리 값이 특정 범위가 아닐때 브레이크 포인트를 걸 수 있습니다.
( VC++에선 6.0에선 안되고 .NET에 와서야 구현된 기능이죠.)

디버거를 쓰냐 printf를 쓰냐는 취향의 문제 겠지만. 못쓰는 프로그래머는 문제가 있습니다.
못쓰는 이유는 call 스택이라든지 메모리 구조 등등에 대한 사전 지식이 없는 경우기 때문이죠.

디버거에 익숙해 지는건 상당히 중요 합니다.
__
Never Ending 삽질.

Never Ending 삽질.

antibug의 이미지

다만 실행속도가 엄청나게 느려지는 단점이 있지만 하여튼 IDE에서 지원해줍니다.
--------------------------------------
재미없는 일은 하지 말자는 인간 쓰레기.
-.-;

--------------------------------------
재미없는 일은 하지 말자는 인간 쓰레기.
-.-;

사랑천사의 이미지

printf를 넣었을 때는 잘 되고 안 그럴 때는 안 되고 디버거로 돌리면 잘 되고 그냥 하면 안 되거나 죽고... 10번 정도 돌리고 한두번 되고... 이거... 콘솔 디스크립터나 그런 쪽 문제일지도 모르겠군요... 아니면 프로세스 fork 할 때 문제가 생기나요? 아무튼 흐흠...
----
일어나라! 싸워라! 그리고 이겨라!
다만!!! 의미 있는 것에 그 힘을!!!
그 능력과 노력을!!!

사람천사

poibe의 이미지

^^..
저는 gdb에서 찍어보는 편인데요.. 이것도.. 그냥.. 찍어보는 거죠? ㅜㅜ

얼마전.. 한참돌다가 segmentation fault나 glibc어쩌고 하면서 스택주루룩 보여주던 에러때문에 한 1주일을 삽질했을때를 생각하면..
gdb도 별로 잘 아는편은 아니라.. 결국 메모리와 관련해서.. 늘고 줄고 하는거를 찍는거를 만들어서.. 찍어보다가...
어떤넘이.. 문제를 일으키는지 찾아서 해결한적이 있었는데..

저에겐 여기있는 모든 글이 정말 값진 글인거 같습니다.

메모리 릭이나. 디버깅에 관한 좋은 책이 있으면 추천을 바랍니다. ^^;
아니면 직접 포스팅 하시면 정말 좋으실듯..

물론 여기 써져있는 몇마디 고귀한 말씀만으로도 앞으로 계속할 공부에서.. 추가해서 한번 파보겠지만.. 너무 떠돌면.. 지칠까봐.. 가이드라도. ㅋ

Fly to the SKY~~~~~~

"According to your faith, be it unto you!!"

오호라의 이미지

모든 분들에게 Steve Maguire씨의 Writing Solid Code를 추천합니다.

디버깅의 과정, 비용(노력,시간), 결과. 이 3가지 측면때문이 아닐까요?

디버깅은 디버거!!

디버깅이 printf()로 편하게 해결이 가능했다면 수많은 디버거가 출현할 이유가 없겠죠.

반면, 디버거도 printf()만큼 쉽게 사용하고, 빠르게 확인가능 했다면 printf()를 쓰지 않았겠죠.

교수님(유닉스세대)들은 디버거도 못쓰면서 어떻게 디버깅을 하냐라고 말씀합니다.

반면 학생들은 그나마 GUI 디버거에서 text 디버거를 쓰라고하면 죽을려고 합니다.

의외로 많은 분들이 이책을 안보신것 같네요. ^^;

Hello World.

chadr의 이미지

저도 디버거를 아주 자주 애용합니다..
편하기 때문이지요..

오히려 printf쳐서 일일이 변수 찍는것보다 브레이크 포인트 걸고 멈추면 디버거에 변수 내용
확인하는게 더 편하더군요..

아.. VS에서 말입니다..

그렇지만 디버거로도 찾기 힘든게 있지요..
특히 멀티스레드 프로그램의 데드락...

이건 디버거를 보는것 보다는 곳곳에 printf를 찍고 직접 돌려보는것이 더 빠르더군요..
한번 쫙 깔아놓고 실행 해주면 어디서 멈추는지 바로 나타나니까요..

또는 실시간으로 마구 도는 프로그램의 디버깅이라든가.. 그런건 디버거를 이용해서
디버깅을 하면 아무런 문제가 없는데 디버거 안걸고 돌리면 문제가 생기기도 하죠..
대부분 그런건 타이밍 문제이긴 합니다.. 그런 프로그램의 경우에는 printf를 써서
곳곳에 심어놓습니다..

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

peccavi의 이미지

어찌된 영문인지, 직장생활 시작해서 지금까지
단일스레드로 돌아가는 프로그램을 짜본적이 없는것 같네요.

멀티스레드에서의 디버깅은 너무 힘들기 때문에, 물론 내공부족이겠지만..
printf에 70%정도 의존하고 있습니다.
valgrind+gdb조합으로 부족한 30%를 채웁니다.. ;-)

좋은글 잘읽고 갑니다~

---
jai guru deva om...

----
jai guru deva om...

쓴귤의 이미지

ML이나 Haskell 같은 함수형 언어에서는 컴파일러만 통과하면 segment fault를 일으키거나 하는 경우가 없습니다. 그리고 변수가 없기 때문에 C에서처럼 printf를 쓸 필요도 별로 없습니다. 위에서 언급된 IBM 프로그래머는 아마 함수형 언어를 사용하나 봅니다. 그 '코드 검사 하는 툴'이 정적 분석기 (static analyzer)를 말하는 것 같은 데, 정적 분석은 함수형 언어가 가장 잘 적용될 수 있는 분야 중에 하나거든요. 디버거를 사용하느냐 마느냐는 어떤 환경에서 어떤 도구로 어떤 프로그램을 짜느냐에 따라 다를 수 있습니다.

http://mentalese.net
http://functional.or.kr

yyww의 이미지

treeshad 씀 (화, 2006/07/04 - 2:48am)

저의 결론 호스트 피씨에서 도는 플그램들은 디버거돌리는게 효율적이다.
임베디드는 printf()로 열심히 찍는게 장땡이다.
----
이 의견에는 반대의견을 가지고 있는데, 임베디드 일수록 디버거가
필요하다고 생각합니다. debugger도 s/w 방식과 h/w 방식이 각각의 특징이 있고
동일한 h/w 방식을 이용해도 다양한 장비들이 있습니다. 다만 그 장비가
얼마나 정확하고 안정적인지가 문제일 것 같습니다.

스패너로도 자동차를 분해할 수 있겠지만 전동 장비가 있으면 훨씬 더 빨리 마칠 수
있다고 생각합니다.

=======
dude7853 씀 (화, 2006/05/30 - 1:34pm)

이런 식으로 디버거를 별로 안써봐서인지, (제가 주로 하는 일인)
장시간동안 동작하는 과정에서 벌어지는 버그에는 디버거가 별 소용이 없는듯합니다.
제 짧은 견해로는 디버거는 동작을 시켰을때 바로 알 수 있는 버그에만 유용한 듯 합니다.
디버깅 포인트에 언제 진입할지 모르는, 즉, 문제상황이 언제 벌어질지 모르는 경우에는
printf나 log를 이용하는게 훨씬 좋은 방법이라고 생각이 듭니다.
----

장시간 장비를 에이징을 걸다가 우연한 기회에 발생하는 경우가 있을 때, 그 문제 원인도
모른다면 아주 심각한 문제를 가지고 있다고 생각해요. 다만 문제 재현이 어렵다면
그 문제가 발생하는 시점에서 타겟을 멈추거나 해서 적절하게 살펴볼 수 있다면 printf로
무모하게 출력하는 것보다 효율적이지 않을까요? printf 등이 임베디드 시스템에 미치는
영향을 고민해봐야 할 것 같아요.

=========
제 생각에 디버깅의 가장 기본은 "돌다리도 두드려보고 건너라"는 원칙인 것 같습니다.
반드시 두 눈으로 결과를 확인해가며 넘어가는 습관을 들여야 할 것 같습니다.

dude7853의 이미지

yyww wrote:

장시간 장비를 에이징을 걸다가 우연한 기회에 발생하는 경우가 있을 때, 그 문제 원인도
모른다면 아주 심각한 문제를 가지고 있다고 생각해요. 다만 문제 재현이 어렵다면
그 문제가 발생하는 시점에서 타겟을 멈추거나 해서 적절하게 살펴볼 수 있다면 printf로
무모하게 출력하는 것보다 효율적이지 않을까요? printf 등이 임베디드 시스템에 미치는
영향을 고민해봐야 할 것 같아요.

저는 printf등이 임베디드 시스템에 미치는 영향보다 디버거가 끼치는 영향이 크다고 생각합니다. 디버깅 모드로 작동하는 프로그램이 과연 일반적인 상황과 동일하다고 할 수 있을까요?

프로그램을 디버거로 몇일 이상 작동시켜보신 적이 있습니까? 그리고 그 동작이 순수하게 프로그램을 동작시키는 것과 같다고 보장하시다면 저도 디버거를 사용하겠습니다. 혹시 웹서버같은 것을 디버거로 몇일씩 돌려보았는데 문제 없었다는 사례를 알려주신다면 더욱 좋습니다.
(h/w 방식의 디버거도 마찬가지라고 생각합니다. 역시 h/w 디버거를 사용할때와 안할때가 같다고 생각하신다면, 간략한 설명 부탁드리겠습니다.)

개인적으로 디버거보다는 문제 시점이라고 생각되는 곳에 printf나 log를 넣어두는 것을 선호하는 이유는 일단 위에서 얘기한 것처럼 장시간 디버거를 돌리는 것에 대한 거부감이 첫번째이고, 또 다른 이유는 디버거를 쓰면 미묘하게 타이밍이 흐트러져서 문제가 발생하지 않는 경우가 생기기 때문입니다.

그건 printf도 마찬가지지 않느냐고 반문하시겠지만, printf를 문제가 발생한 후에 사용한다면 적어도 그 전 과정에서 printf의 영향은 없었다는 것을 보장할 수가 있다는 점이 다릅니다.

저는 디버거도 디버깅의 한 도구라고 생각합니다. 좋은 도구를 안쓰는 것도 문제이지만 꼭 그것만 써야할 필요는 없다고 생각합니다.

moohooramaTcode의 이미지

방법이 무엇이든 정확하게 효율적으로 수정되는게 가장 좋겠지요.

제 개인적인 경험 상으로는 printf건 디버거건, 그냥 설계 단계부터 제대로 짜놓 것만큼 좋은게 없더군요. 위에서 허구헌날 requirement spec을 변경해서 문제지-_-

후배들에게 디버거 쓰게 하는 방법은 간단합니다.
보통 대학 과정은 C를 먼저 배우는걸로 알고 있고, 툴도 visual studio 6.0을 쓰는걸로 알고 있습니다.

그때 버그 못고치겠다고 물어보면 f9 f10 f11 눌러주면서 stack trace 하는거 직접 보여줍니다.
그러면 신기해 하면서 알아서 쫓아 하더군요.

컴퓨터 구조 모르면서 저런거 먼저 보여주면 되려 햇갈려 하지 않을까, 했는데, 애들은 되려 눈으로 직접 보면서 조작하다보니 function call이나 포인터, 메모리 구조 같은걸 제대로 배우더라구요.

골빈해커의 이미지

php 나 javascript 같은건 끼워주지 않으시나요(...)

nthroot의 이미지

coredump와 assert 는 축복과 같아요 'ㅇ')/

------식은이 처------
길이 끝나는 저기엔 아무 것도 없어요. 희망이고 나발이고 아무 것도 없어.

서지훈의 이미지

디버깅시... printf() 추천 1순위...ㅡㅡㅋ
전 좋은데...
아주아주...
그래도 안되면 gdb를 쓰긴 하지만.

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <beer.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

익명사용자의 이미지

으음... 에러 뱉어내고 프로그램이 죽어버리는 경우라면 디버거가 유용할 지도 모르겠습니다.
하지만, 당장 프로그램이 죽어버릴 정도의 버그가 버그 축에 낄 수 있느냐에 대해선 개인적으로 동의하지 않습니다.
오탈자를 버그로 취급하지 않는 것과 같은 이유입니다.
이런 것을 버그라 부르며 디버깅을 한다고 디버거를 들이댄다는 것은 말 그대로 삽질이죠.
디버거는 코더의 필수품일진 몰라도, 프로그래머에겐 치욕스런 물건입니다.
디버거와의 친밀도를 자랑하시는 모습이 ...

"(처음부터) 바르게 동작되도록 만든다" 가 비아냥의 대상이 되는 세상에서 사는 어느 분은 얼른 눈 좀 뜨셨음싶습니다.

부끄럽지만, 고백하자면, 저도 디버거를 사용할 줄 압니다. 숨어서 몰래 사용하곤 합니다.
더불어 지x 같은 코드에 디버거 깔짝거리고 있는 놈들 보면 그게 선배건 후배건 상관없이 *걸어다니는 전화기* 정도로 취급합니다.
다행히, 제 주변엔 나봐란 듯이 내놓고 디버거를 깔짝대는 분들은 안계십니다.

임베디드 환경... JTAG, T32 등 장비를 언급하시며 디버깅을 하신다는 분이 계신데,
제 입장에선 저런 세상에서 사는 분도 계신다 싶을 뿐입니다.
램의 내용을 임의로 다룰 수 있다는 점을 빼면, 어디 써먹을 데가 없네요.
디버깅... 아시겠지만 이런 장비를 사용해서 디버깅할 수 있는 것은 버그라고 부를 수도 없는 수준의 것들입니다.
이런 디버깅을 자주 하신다면, 디버깅 장비에 친숙해지기 위해 노력하는 것 보다 본인의 능력을 의심하는 쪽에 관심을 가져야죠.
정말로 절망스러운 것은, 에이징 십만다섯번째 테스트에서 뭔가 이상해지거나 일주일째 되던날 뭔가 이상해지는데 그것도 시료 10대 중 한두대에서만 간혹 발생하는 경우입니다.
흔치 않을 것 같습니까 ? 제 경우엔 디버깅이 필요한 거의 대부분의 상황이 이런 상황입니다.
printf() 류는 말이죠... 디버거를 들이대기 전에 간단히 뭔가 해보는 그런 것이 아니라... 궁극적이고 유일무이한 절대적인 디버깅 수단입니다.

서지훈의 이미지

경험 많은 프로그래머 = 디버깅 잘 하는 프로그래머
좋은 프로그래머 = 좋은 알고리즘을 만드는 프로그래머

어떤 좋은 코드에도 버그는 숨어 있습니다.
실로 간단한 "hello! world!" 에도 버그가 숨어 있습니다.
이럴지인데, 디버그 툴을 잘 다루는 사람이 실력이 모자르다고 하시면...
아직도 경험이 부족하신분 같군요.

버그는 어떤 좋은 프로그래머가 코딩을 해도 꼭 생기게 되어 있습니다.

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <beer.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

sDH8988L의 이미지

글 전반적인 부분을 동의하지는 않지만, 그 절망적인 상황이라는 것이 이해가 가네요... 저도 여러 번 겪어본 일이라서요...

TEST 같은 걸 수십 번 해도 발생하지 않는 문제가 실제 돌아가기 시작해서 한 두 달 만에 문제를 내 뱉는 건 정말...

머리가 하얗게 돼 버립니다...

상상하는 것만으로도 짜증이 나는군요...

익명사용자의 이미지

디버거 없이 코딩할 수 있는 환경을 가지시다니.
정말 좋은여건에서 작업하고 계시는군요.

나 혼자만 작성하고, 나만이 소스를 봐야하는 상황이라면, 그리고 자신의 실력에 자신이 있다면, 분명히 디버거 필요 없습니다.
하지만, 10명이 넘어가는 다른사람과 공동작업을 하는, 몇만-몇십만 라인이 넘어가는 소스에 대해서는...
소스가 버전업을 함에 따라서, 내가 다른사람의 코드 부분을 건드려야 하고,
다른사람이 내가 작업한 코드를 건드러야 하는 상황이라면...

그래도 디버거의 도움없이 말끔히 눈으로만 해결하실 수 있는 분이 있다면..
코딩의 신으로 모십니다..

antibug의 이미지

제가 쓴 글이군요. 뜬금없이 3년전 글이 다시 올라오니... 거참...
3년전 글을 보면서 '그래도 디버거는 사용해야 한다' 라는 생각을 하고
있는 것을 보면(변한게 없는 걸 보면) 그동안 공부를 덜 한 모양입니다.

저 글을 썼던 당시 상황을 말하자면,
코딩하던 후배가 ASSERTION이 발생했는데 그걸 무시하고 프로그램 실행을
종료한 다음 '코드 째려보기' 놀이를 하고 있어서 답답해서 쓴 글이었습니다.
물론 어떤 경우에는 저도 assertion은 그냥 무시하지만 그건 당연히 일어날
꺼라고 생각했던 assertion, 또는 assertion 메시지를 보고 어디인지,
왜 일어났는지 파악이 되는 경우 얘기고 '코드 째려보기' 놀이를 해야 할
지경이라면 그 assertion으로 실행을 중단 시킨 상태에서 디버거를 사용해
확인해야 하지 않을까 생각합니다.

많은 분들의 답글을 주욱 읽어봤습니다.
좀 놀랍습니다. 의외로 많은 분들이 디버깅(디버거가 아니라)이 필요없다...라고
주장하셔서. 제가 프로그래밍 언어로 말하는게 좀 짧아서 그런지 모르겠지만
디버깅이 왜 필요하냐는 질문에는... 좀 어이가 없네요. 말했듯이 놀랍기도 하구요.
필요한 시점에서 디버거를 사용하는지 printf()를 사용하는지는 개인적인 취향이거나
개발 환경, 태양풍이나 지하수맥 때문에 생기는 어쩔수없는 선택일 수 있습니다.
하지만 그런 시점이 반드시 (그것도 매우 빈번하게) 생긴다는 것은 자신하고
있었는데, 그런 시점을 만드는 어리석인 짓이나 하고 있었다니 좀 부끄럽군요. -.-;

다만, 제가 보통 사람이라 copy con으로 컴파일러를 써내려가는 guru같은 분들의
생각을 따라갈 수는 없네요. 솔직히 말하면 그럴 수 있는 사람이 있다고도 생각하기
어렵군요. 미숙하고 어린 대중들한테는 기적을 보여주는 것이 가장 효과적입니다.
수많은 종교 창시자/지도자들도 그러셨듯 말이죠. 그런 수퍼 울트라급 개발자들의
코드를 구경을 좀 해봤으면 좋겠습니다 (보고서 믿을 수 있는데도 어느 정도
레벨이 필요할텐데 그게 될런지는 모르겠습니다...)

요즘들어 머리를 걸어다닐 때 균형잡는 용도로 사용하는 통에 점점 바보가 되고
있는 것 같군요. 정신적 쇼크를 주실 분이 필요해요...

-------------------------------------
재미없는 일은 하지 말자는 인간 쓰레기.
-.-;

--------------------------------------
재미없는 일은 하지 말자는 인간 쓰레기.
-.-;

5peaker의 이미지

고수님들 하시는 말씀 들어보니
전 하나도 모르겠습니다.

평생 도망만 다니다 늦게 시작하게 되었는데,
열정만 한가득이네요.

제입장에서는 이렇게 이야기 하시는 모습이 너무 부럽습니다.

magingax의 이미지

몇일 동안 잘돌다가 퍽~ 죽습니다..아무 메시지 없이..
원인은 둘중하나 입니다.

1. thread 간에 충돌
2. thread 가 돌고 있다가 IO interrup 가 발생해 충돌..

문제는 포인트를 도져히 못찻겠내요..
좋은 툴있으면 추천좀..

LISP 사용자모임
http://cafe.naver.com/lisper
방송기술 개발업체
http://playhouseinc.co.kr

young의 이미지

본문의 내용과는 상관이 없는 내용이지만, 글의 생명이 언제까지
이어질지 참 기대되는군요...
나중에는 과연 무슨답이 달릴까라는 생각이 흐뭇하게 납니다.

# ./Go_Go_GO!!!!

# ./Go_Go_GO!!!!

익명사용자의 이미지

문제는 디버깅 툴이 만능이 아니라는 데에 있습니다.

Quote:

많은 분들의 답글을 주욱 읽어봤습니다.
좀 놀랍습니다. 의외로 많은 분들이 디버깅(디버거가 아니라)이 필요없다...라고
주장하셔서. 제가 프로그래밍 언어로 말하는게 좀 짧아서 그런지 모르겠지만
디버깅이 왜 필요하냐는 질문에는... 좀 어이가 없네요.

모든 글들을 다 읽어보진 않았지만, 대부분의 글에서 디버거가 필요하다는 말을 하는 것 같은데 님께서는 어떻게 이런 말씀을 하시는지 ? ^^;;