디버깅의 테크닉

geekforum의 이미지

훌륭하게 디버깅을 하고 싶습니다. 프로그래밍을 하면서 거의 printf 문으로 디버깅을 할 때가 많습니다. 그럴 때마다 한계(?)를 느끼고 있습니다. 이를 해결할 수 있는 방법이 없을까요?

가령, 디버깅에 관련(리눅스) 책 없을까요? 아님, 관련 웹사이트라도.. gdb 는 너무 어렵더군요. 뭐 gdb로 다 할 수 있는데라고 말씀하시면 할 말 없이 무조건 마스터링(?)을 해야 겠지만요.

디버깅을 훌륭하게 할 수 있게 하는 방법, 책, 웹사이트좀 알려주세요. 다른 툴이라도 있으면 더욱 좋구요.

댓글

익명 사용자의 이미지

머 이건 리눅스에선 해당되지는 않지만..

다른 몇몇 상용 O/S의 경우에는 디버깅 툴이 좀 있습니다.
물론 상용이긴 하지만 Trial 버전을 받으면 일주일은 디버깅 가능하죠..

프로그램은 Rational에서 나온 Purify 라는 프로그램이 있습니다.
이것을 사용하면 왠만한 Memory Leak 이라든가 메모리 관련된 오류는 쉽게 찾아낼수 있습니다.
당근 printf 문 넣을 필요 없구요..
지금은 이거 없으면 디버깅이 너무 불편해서 잘 못하겠더군요... -,.-;;;
UNIX 개발자는 이 프로그램 하나정도는 있으면 정말 든든합니다.
장담하는데.. Segment core 나는경우 이걸 이용하면 하루걸려서 알아낼것도 1분 아니면 10분 이내로 해결이 됩니다.
더 말하면 너 이거 장사하지? 할까봐.. 더 말못하겠구요..

그리고 Mccabe 라는 것도 있는데 이거는 저도 이런게 있다고 만 들어봤을 뿐이구요.. 잘은 모르겠습니다.

또 다른거는 Solaris의 경우에는 Workshop 이 좋은 디버거 입니다.
물론 MS Visual Studio 수준은 아니지만 Unix 개발자라면 이정도만 되어도 수준급이죠..

그외에는 저도 알고 있는건 없지만..
앞에서도 어느분이 말씀하셨지만..
꽁자 치고는 DDD 가 참 좋은거 같습니다.

그럼 이만..

익명 사용자의 이미지

저도 gdb를 쓰지만.. 간단하게는

printf와 strace를 씁니다.

그리고 실행시나 컴파일시 메세지를 파일로 남겨 살펴보구요..

./test 2>&1 | tee > test.log

익명 사용자의 이미지

> ./test 2>&1 | tee > test.log

tee 명령을 쓰신다면 tee > test.log 는 필요없는 부분일 듯 하네요. ^^

화면으로 보실 필요가 없다면 그냥

./test > test.log 2>&1

라고 하심 될 듯 하고요.

입출력을 파일로 대치하는 것은

숙제할 때 편하게 썼던 것 같습니다. -_-;;

sharefeel의 이미지

간단한 프로그램은 gdb돌리기도 귀찮고..
특히 linked list쓴 것들은 더더욱 귀찮은 거 같아요..
그럴때 흔히 쓰는 게 printf인데..
이거 fflush(xxx)를 꼭 써줘야하더라구요..
다들 알고 계시는 거겠지만..

모르면 디게 고생하죠..
segmentation fault가 난 곳 한참 이전까지의 printf만 실행되고 죽으면..
참 황당하죠.. 에러가 날만한 곳은 아직 한참 멀었는데 중간에 죽었다고 생각하게 되니까요.
윈도에서 살다가 리눅스로 와서 고생한 대표적인 예인거 같습니다..ㅅ.ㅅ;;

===============
Vas Rel Por

익명 사용자의 이미지

setlinebuf(stdout);으로도 효과가 있죠....
:)

익명 사용자의 이미지

fprintf(stderr,...

sharefeel의 이미지

stderr 편하지만.. 단점이 하나있습니다.
$ ./a.out > error.log
이렇게 에러가 캡쳐가 안되더라구요..
그래서 귀찮아도 어쩔수 없이 printf, fflush를 씁니다..

===============
Vas Rel Por

익명 사용자의 이미지

$ ./a.out 2> error.log

익명 사용자의 이미지

헉...
감사합니다.

clhitter의 이미지

AIX 같은 곳에서 gdb로 디버깅을 하다 보면요 소스 파일 위치를 자동으로 찾지 못하고 directory 명령으로 수동으로 지정을 해줘야 하는 경우가 종종 있는데요.
혹시 해결 방법을 아시는 분 있으신가요?

p.s. 본문과 크게 관련 없는 글인줄은 알지만, 인터넷에서 아무리 찾아봐도 해결 방법을 찾을 수가 없어서요 ^^

익명 사용자의 이미지

cgi를 디버깅 할때는 어떻게들 하시는지요?

예전에 잠깐 cgi 프로그램 짤때 디버깅 때문에 무지 고생했던 기억이 나서요

cgi의 특성상 프로그램이 끝나야 브라우저에 출력이 가능하고
웹서버에서 환경변수나 값을 넘겨받아야 했기에...
중간에 세그먼트 폴트가 나면 브라우저로 확인이 불가능합니다.
인터널 무시기 에러만...

초짜였던 저로서는 엄청난 삽질을 했었습니다..
다시 cgi를 할일이야 없겠지만.. 그래도 궁금하네요..

익명 사용자의 이미지

QUERY_STRING, HTTP_COOKIES의 환경변수를 경우에 맞게 값을 주고,
(이 값은 아파치 웹서버 패키지에 있는 printenv 또는 test-cgi를 돌리면 구할 수 있습니다)
커맨드라인에서 cgi를 돌리면 HTML 페이지 출력이 나옵니다.

이 때 SegFault 같은 에러가 있는 경우 gdb을 사용하면
에러를 잡을 수 있지요...

익명 사용자의 이미지

원민호의 이미지

제 기억으로는 STDIN 입력으로 & 로 delimit 된 스트링을 주고

php 같은 건 php 명령으로 실행시키거나 C 로 된 건 stdin 에 저렇게 주고..

실행시키면 stdout 에 찍히는 명령이 브라우저의 소스보기에 나타나는 거 같았습니다.

몇가지 encoding rule 을 지켜줘야 되는데.. ms explorer 부터는 encoding 같은 건 안하는 거 같더군여..

jsp 는 제가 사용했던게 resin 하고 tomcat 이었던 거 같은데.. server 쪽에서.

system.out.println 으로 디버깅 메시지를 확인할 수 있었습니다.( 이 상황이 제일 디버깅하기에 좋았던 거 같군여.. )

asp 는 안해봐서 모르겠습니다..

조기태의 이미지

JSP의 경우 다양한 IDE에서 원격 디버깅을 지원합니다. 특히 로직을 별도의 클래스로 분리한 경우 중단점을 활용해서 편리하게 디버깅할 수 있습니다.

로그를 찍는 경우 System.out에 찍는건 절대 비추천입니다. 가능하면 Log4j나 1.4의 로깅관련 클래스를 활용하시는게 좋습니다.

이유는 log4j홈페이지를 참조하세요 :)

그럼~

익명 사용자의 이미지

이제까지 log4j를 서버관리용으로만 사용하고 있었는데...
디버깅은 콘솔에서 바로 확인할 수 있는 System.out에 손이 가는 건 왜 일까요.
그런데 asp는 서버상태를 확인할 수 있는 콘솔은 없는 것일까요...
asp는 왠지 손이 안가서...

익명 사용자의 이미지

디버깅은 디버깅 함수를 쓰는 것 뿐만이
아니라 처음부터 코드를 잘 짜는 것도 중요합니다.
(1) IF (조건) {처리1} ELSE {처리2 리턴}

(2-1) IF (! 조건) {처리2 리턴}
(2-2) 처리1
로 표현을 바꾸어 코딩할 수 있습니다.
디버깅 뿐만 아니라 코드 읽기도 쉬워지죠.

(물론 반론이 있을 수도 있겠죠. 하지만 디버깅이 어려운
임베디드 기기에서는 생각외로 쓸만한 방법입니다.)

익명 사용자의 이미지

글쓴이께서는 음 예를 잘못든 것 같습니다. ^_^*

그러나 말씀하신 것처럼 코드를 잘짜는 것은 아주 중요하다는데 한표던집니다.

깔끔한 알고리즘은 확실히 디버깅하는데 수월합니다.

게다가 소스를 보기 쉽게 잘정리하는 것 또한 중요하다고 생각합니다.

소스를 잘정리한다면 파악하기도 쉽겠지요.

게다가 주석은 아주 중요한 습관이라고 생각합니다. 심하다 싶을 정도로 상세하게 주석처리를 하는 것이 프로그래밍하는 당사자도 훨씬 더 정리된 자세로 프로그래밍을 할 수 있을 것이고 나중에 다른 프로그래머도 쉽게 이해할 수 있겠지요.

익명 사용자의 이미지

심하다 싶을 정도로 상세하게 주석처리를 하는 것
은.. 정말 안 좋은 코딩 습관이죠.. --;

중요 부분 빼고는 주석없이 이해할 수 있는 소스를 만들어야 되겠죠..

익명 사용자의 이미지

응 맞는디? 전 이렇게 쓰거든요.

입구와 출구를 단일화 시키는 것에 원칙적으로
찬성하지만 에러 대응 코드가 많이 붙을 경우
차라리 단일 입구에 단일 출구 원칙 외에
에러에 대해서는 즉시 리턴을 원칙으로 코딩을
합니다.

저도 극악의 임베디드 환경에 오기전까지는
원론적 원칙을 지키고 살았습니다. ^^a

sharefeel의 이미지

어떤 책에서 읽은 내용입니다.. (code complete였던거 같네요..)

가능하면 함수의 시작지점과 끝나는지점을 하나씩만 두어라..
라고 되어 있었던 거 같습니다..

요즘 저렇게 해보려고 하는데..
if (error) return error;
블라블라..;
return result;

if (error) ret = error;
else{
블라블라;ret = result;
return ret;

이렇게 짜고 있는데.. 오히려 더 산만한거 같다는 느낌도 드네요..
그리고 저렇게 짜면 에러체크가 많아지면 else의 nest된 깊이가 커져서..
어떻해서는 80칼럼 안쪽으로 맞추려는 제 의지를 꺾게 되더라구요..

그리고 쓸데없는 얘기지만.. code complete라는 책은 MS Press에서 나온책이져..--;;

===============
Vas Rel Por

익명 사용자의 이미지

> 그리고 저렇게 짜면 에러체크가 많아지면 else의 nest된 깊이가 커져서..

goto문을 쓰세요. goto를 금기시하는것이 프로그램의 법칙이지만
이런때 아래와 같이 사용하면 아주 좋습니다.

if (error) {
ret = error;
goto func_exit;
}
else if {
블라블라;
}
else{
블라블라;
ret = result;
goto func_exit;
}
블라블라;

func_exit:
return ret;

goto를 남발하면 문제겠지만 코드가 아주 길고 if문이 많은 경우
쓰는게 오히려 논리적으로 명확해지죠.

ihavnoid의 이미지

음...
저 같은 경우에는 error시 그냥 튕겨나가는 걸 선호합니다....
비정상적인 상황에서는 중간에 튕겨나가는 게 차라리 나을 듯 합니다....

어차피 더이상 실행하는 게 의미가 없는 상황이라면, 그냥 나가도록 하는 게 흐름 따라가기 편하더군요. 오히려 다중 if문 같은 건 정말 싫습니다. 이 if문의 else가 어디서 시작하나 눈에 잘 안 들어오더군요..

음... 예외적인 경우가 있다면... error시 뒷처리가 복잡한 경우(가령 file이나 자료구조를 cleanup해 줘야 한다던가)에는.. 좀 다른 방법을 모색하는 것도 좋을 듯 합니다.

저같은 경우에는 가끔씩 매크로도 쓴답니다-_-;;

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

익명 사용자의 이미지

그런 경우가 종종 있죠?

함수 안에서 메모리를 할당받는다거나,
함수 안에서 파일을 열었는데 함수가 나가기 전에 닫아줘야 하는 경우,
Pro*C나 ESQL 같은 경우에 커서를 열었거나 하는 경우,
어떤 형태로 락을 걸었을 경우 등등
에 중간에 에러가 나면 나가기 전에 cleanup을 해줘야 하는 경우
이거 에러난 곳마다 중간에 나가려면 매번 비슷한 종류의 cleanup 코드가 중복되고, 코드가 변경될 때마다 그거 쫓아가서 추가해주고 수정해 주려면 상당히 귀찮더라고요. 매크로를 써서 긴 문장을 하나로 줄일 수는 있겠지만 장애 포인트 있는 곳마다 계속 중복된 코드가 보이는 것 상당히 신경쓰입니다.

그래서 저는 다른 분이 goto 문 쓰는 것 보고 저도 goto 문을 도입했습니다.
file열거나, lock걸거나, 메모리 할당 받을 때마다 flag변수를 설정하고,
중간에 에러가 나면 goto cleanup; 으로 가게 하는 겁니다.
cleanup 에서는 flag 변수들을 보고 닫아주거나 정리해 주어야 할 것이 있으면 닫아주는 것이죠. 리턴은 goto 로 cleanup쪽으로 오기전에 변수에 할당해 주고요, cleanup 루틴 마지막에 해당 변수를 리턴해줍니다.
정상처리될 경우도 cleanup을 해줘야 하니까 cleanup 쪽 루틴은 정상루틴도 그대로 타고요, 메모리 할당 같은경우에는 정상처리된 경우에는 caller에게 전달해야 하는 경우도 있으니까 cleanup 코드 중 어떤 것은 flag변수점검과 함께 정상처리여부도 점검하는 경우도 있습니다.
물론, 함수 앞쪽에서 장애가 발생하는 경우에는 필요없는 cleanup 검사도 있겠고, goto가 pipelining이나 instruction cache쪽에 안 좋을 수도 있겠지만, 그런 건 1초에 수백만번 이상 할 수 있는 일이라 마음 여유롭게 가지기로 했습니다.

musiphil의 이미지

assert를 많이 쓰세요.

'여기서는 x 값이 음수는 아니겠군.'
'여기까지 왔으면 p가 NULL이 아니라고 할 수 있겠다.'

이렇게 가정을 하는 것마다 assert로 표현할 수 있습니다. 그럼 그 가정이 어긋날 때 바로 알 수 있습니다.

또한 에러 처리 같은 것을, 나중에 하긴 해야 하지만 지금 당장은 귀찮고 재빨리 결과만 보고 싶을 때도 assert를 사용할 수 있습니다.

FILE *fp = fopen(filename, "r");
assert(fp);
...

이 때 에러 처리를 아예 생략해버리면 나중에 잊어버리기 쉬운데, assert를 써 두면 잊어버리지 않을 수 있습니다.

익명 사용자의 이미지

디버깅도 중요하지만 버그가 없는 프로그램을
작성하는 것이 더 좋은 방법인 것 같네염.
아래 두 책은 모두 그러한 프로그램을 작성하는
방법에 관해 설명하고 있습니다.

Writing Solid Code.
Code Complete.

디버깅에 대한 직접적인 툴을 사용하는
설명이나 기타 방법에 대한 설명이 나와
있는 책은 아니지만 한번쯤 읽어보면 두고두고
도움이 될 것 같네염^^

익명 사용자의 이미지

감동적인 책들이었슴돠.
한글판도 나와있슴돠.

익명 사용자의 이미지

혹시 한글판 보셨나요?
번역 상태가 어떤지 궁금합니다.

익명 사용자의 이미지

Code Complete는 책이 두꺼운므로
소설책 읽듯이 가볍게 읽어 내려가시기 바랍니다.
방법론을 알고만 있어도 언제라도 유용하게 다시
살펴보면 되니까요.

무겁게 읽고 싶다면 Refactoring가 있고요.
좀 철학적으로 써 놓아서 부담스럽더군요.
그만큼 미국쪽도 코드가 엉망이 되어 간다는 얘기일 수도
있고요 (미국쪽에서 팔거나 공개하는 소스 코드는 매우
깔끔하다는 것이 제 경험입니다)

naisr00t_의 이미지

글을 올린 학생입니다.

가장 이해하기가 힘든 부분(디버깅 할 때) 전처리기를 이용하시는 분들인데요.
어떻게 하는지 솔직하게 이해하기 힘듭니다.
공부를 할 때도, 전처리기가 이런 것이다 정도만 공부를 했고, 그렇게 몇년을 알고 프로그래밍을 해왔는데.
너무나 의아스럽습니다.

그렇다면, 전처리기를 이용해서 디버깅하는 책이나 웹사이트가 있나요?
아님, 숱한 경험을 통해서 프로그래밍의 테크닉에 진리가 되버린것인지 궁금하네요.

추신 : 카일릭스를 당나귀에서 얼마전에 다운로드를 했습니다. 거기에 볼랜드 C++이 있다는데,
거기 디버깅 툴을 이용해도 괜찮을 책 하나 부탁드립니다.
다른 얘기지만, 임베디드환경에 프로그래밍할 때 디버깅도 마찬가지 인가요??

물론, 프로그래밍의 테크닉을 책과 웹에만 의존 할 순 없지만, 저로서는 현재 어쩔 수가 없어서 그렇습니다.

그리고 아래, DDD를 추천하시는 분께 고마움을 전하구요...

익명 사용자의 이미지

저도 회사가서 전처리기를 알았습니다.
한 이틀 지긋지긋하게 많은 컴파일 옵션 쳐다보니까
알겠더군요.
회사가서 공동작업하고, 디버깅하다보면 코드는 좀
엉망이 되도 디버깅 하기 좋은 형태를 익힐 수 있습니다.
너무 부담갖지 마세요.

익명 사용자의 이미지

전처리기를 이용한 디버깅은 특별할게 없습니다.
아래 어떤 분처럼 debug 출력 code를 macro로 만들어서 debug 시에만 define하고 release 때는 undef 해버리는 방법도 있고 특정 code block을 ifdef나 if문을 사용해서 전처리하는 방법도 많이들 쓰지요.

제 경험으로는 가능하다면 macro로 쓰기보다는 debug 메시지 출력함수를 만들어서 쓰고 release 때는 막아버리는게 더 유용한 것 같습니다. 물론 메모리 문제가 있거나 time-critical한 임베디드나 리얼타임 시스템에서는 저도 macro를 씁니다만 일반적으로 볼때 macro는 bug prone 하고, 특히 공동작업을 하거나 규모가 큰 작업을 하게 되면 좀 귀찮습니다.

디버깅에 대해서는 아니지만 전처리기에 대한 설명은 프렌티스 홀에서 나온 C ARM(a refrence manual)에 보시면 잘 정리돼 있습니다. 이 책은 두루두루 c 프로그래머면 한번 봐둘만 합니다.

임베디드에서 디버깅은 경우의 수가 많지만 serial이나 이더넷 류의 통신이 가능하다면 gdb나 전용 모니터링 프로그램을 이용해서 디버깅을 할 수 있고. 최악의 경우에는 오실로스코프나 로직아날라이저를 이용해서 디버깅 해야합니다. 임베디드에 대해서는 오렐리에서 나온 임베디드프로그래밍 in c(?)를 권해드립니다. 정말 잘 썼더군요. 한빛에서 번역판도 나와있고 다 살펴본 건 아니지만 깔끔하게 잘 옮긴 것 같더군요.

라키시스의 이미지

쿠..쿨럭...
로직 애널라이져 ㅡㅠㅡ
있으면 너무너무 편한 장비이겠지만, 흑... 너무나 비싼 장비입니다.....
꿈도 못꾸어보고 스코프로 찍고, 포트로 날리고 하면서 디버깅하고 있습니다 ㅡㅜ

익명 사용자의 이미지

저도 딱 한 프로젝트에서 써봤습니다.
쓸 필요 없었는데 너무너무 써보고 싶어서 다른 팀꺼 슬쩍해와서 썼지요:)
사실 우리나라 실정에서 로직아날라이저가 필요하면 오실로 스코프 여러개 불여서 쓰는일이 더 흔 하겠죠. 저도 오실로 스코프 2 프르부짜리 두개 4프르브 짜리 하나 해서 써본 일이 있지요. 어마어마한 닭짓.

익명 사용자의 이미지

푸하하핳
2 probe 두개랑 4 probe 하나랑 하면...
그거 다 손으로 잡고 있을수도 없구...
걸어둘라면 tp 뽑아야 할텐데,
납땜하기 귀찬흐셨겠습니다 ㅋㅋㅋㅋ
게다가...
타이밍은 또... .. ㅋㅋㅋㅋ
수고하셨습니다 :)

------------
라키

익명 사용자의 이미지

컥 오실로 스코프라 ...

오실로 스코프가 필요한 디버깅이 있다니 놀랍군요.

dawnsea의 이미지

오실로를 써야 하는 디버깅은 얼마든지 있지요.

음..KLDP 야 워낙 고수분들이 많습니다만. 하드웨어쪽 프로그래밍에 익숙치 않은 분들을 위해서 좀 자세하게 쓰자면...

가장 흔한 것이 SoC (System on Chip : 칩안에 몽창 들어간 것.. 요즘 가장 흔한 것이 스트롱암) 류에서 특정 모듈(이를테면 LCD 컨트롤러)을 드라이빙 못 하고 있을 때.

제일 먼저 점검하는 것이. 리셋 시그널의 타이밍을 보고.
그 다음에 CS (칩 셀렉트) 를 보고.
그 다음에 RE, WE (읽기 쓰기 시작 신호)를 보고.
마지막으로 데이터/어드레스를 보지용.
아. 클럭이야 수시로 봐야죠 ^^;;

예를 들어 데이터 버스에서 데이터가 잘 안 나오는 것 같이 의심되는 상황이라 칩시다.

그럼 단순하기 포인터에다가 주소 지정해서 아무데나 억세스하게 해 놓구

while 로 무한루프를 돌린다음에 데이터버스 핀을 찍어보면. 파르르 떨겠죠?

어~ 그럼 신호는 일단 나오는 군! (정확한지는 몰라도) 기초적으로는 여기서부터시작됩니다.

이 뿐만 아니라.

인터럽트 핸들러나 타임 슬랏이 민감한 디버깅을 요할때는, 요즘은 jtag 장비가 좋다고는 하지만. (전 이런 고급디버깅에 약해서..)

GPIO 같은 걸로 하이/로우를 띄우는 것이 가장 쉬운 디버깅이지요.

GPIO 4비트면 2^4 = 16가지의 디버깅 코드를 찍을 수 있군요 ㅠ.ㅠ
근데 이것도 로직어날이 있으면 편하지만서도. 스코프로 볼라면 TP (스코프로 찍기 편하게 뽑아놓은 뽀인트) 가 잘뽑힌 레퍼런스 보드가 아니면 성가시죵.
특히 음주전후에는 ㅡ.ㅡ; 수전증환자라든지..ㅡ.ㅡ;;

OS 쪽과 관계되서도 디버깅 툴이 있는 것으로 알고 있습니다만.

쉽게 생각할때는. 요즘은 장비가 좋아서 컴팔도 빠르니까 ㅡ.ㅡ;

printk 처럼 GPIO 를 쓸 수도 있다는 것이지용.

익명 사용자의 이미지

그렇죠...
많은 하드웨어 콘트롤에서는 특히나 요즘처럼 빠른 클럭과 많은 32비트의 연속적인 데이타 통신에서는 스코프로 찍는 것이 한계가 있기 마련이죠.

타이밍을 이해한후에 적절할 레치를 잡아 원하는 타이밍을 잡아내려면 스코프로 찍는 것은 거의 불가능합니다.
그럴때 유용하게 쓰는 것이 로직 아날라이저죠.
얼마전 PCI버스를 통째로 잡아서 볼일이 있었는데... 그럴때 스코프로 잡는 것은 불가능하지 않습니까?

프로그램상에서 실수로 남긴 코드들이 있을때도 타이밍에서는 다 보이기 때문에 바로 바로 걸립니다.(사실 소프트웨어에서는 아날라이저로 찍어서 타이밍을 확인한다는 것은 완전히 속을 다 까 뒤집는 일이기 때문에 그리 반기지 않기도 합니다. 왜 혼자만 보고 싶죠??? ^^;;)

ihavnoid의 이미지

그럼 있죠.. ^^

어떤 하드웨어에서 serial을 작동시켜야 하는데... 이상하게 클럭스피드에 맞는 divisor을 넣어도 제대로 작동을 안 해서.. 결국 공급되는 클럭을 의심하다가... 오실로를 이용해 봤는데요.. ^^

끙... 잘 모르는 다른데에 이유가 있는 듯.. -_-;
음... 프로그래밍하는데 오실로 써보기는 처음이었답니다-_-;;

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

익명 사용자의 이미지

간혹 저사양(?) 프로세서에서는 57600이상의 고속(-_-) 통신을 할때 uart 쪽과는 전혀 상관 없는 레지스터에서 세팅을 해야하는 경우가 있습니다. 아예 divisor는 28800에 맞춰놓고 그 짓을 해야 한 적도 있는 듯하고...
8051이었나..
어떻게 된게 한번 하고나면 다 까먹는지...:(

그리고 임베디드 개발하면 오실로 스코프로 디버깅하는 일 비일비재 하지 않나요?
uart는 기능구현하느라 써버리고 led와 timer, 빈포트 몇개 가지고 디버깅할려면 오실로스코프 옆에 끼고 살아야죠.

익명 사용자의 이미지

UART 로 기능구현 하실 때
HDLC 비스무리한 프로토콜을 사용하도록 약간 상위 레벨에서
조정해서, 통신용 채널과
디버그용 채널을 나눠서 사용하도록 하시면
편하게 사용하실 수 있죠 ^^;;

디버그 메세지는 디버깅 채널로 보내고,
다른 모듈과 통신하는 것은 해당되는 채널로 하구요 ^^;;

코드 스페이스가 안된다면 할 수 없구요 -_-;;;

-----------------
라키

익명 사용자의 이미지

uart를 범용으로 쓰는 경우라면 말씀하신 방법이 매우 좋은 방법이라고 생각합니다.
하지만 uart를 범용으로 쓰는게 아니라 특정 모듈을 제어하기 위한 통신용으로 쓰고 있을 경우엔 말씀하신 방법은 좀 어렵지 않을까요.
신호야 점퍼를 날려서 받아본다 해도. 걔 나름의 프로토콜로 통신해야하는데 내가 임의로 정한 프로토콜을 써버리면 어찌 돌아갈지는 알 수 없으니까요.

라키시스의 이미지

아.. 하하 ^^;;
네, 제어하고자 하는 특정 모듈의 펌웨어를 건드릴 수 있는 경우엔 채널(?)을 나누는 것도 괜찮지만,
말씀하신것 처럼 그 모듈을 건드릴 수 없는 경우라면, 그렇죠 ^^;;;.. 당연히 말입니다.
^^;;

익명 사용자의 이미지

ARM은 Annotated Reference Manual의 준말 아닌가요.

익명 사용자의 이미지

아뇨. A Refrence Manual 맞습니다.
물론 원작자에 따라서는 advanced나 annotated를 쓰기도 하지만 이 책은 제목이 A Refrence Manual 입니다.

익명 사용자의 이미지

혹시 ARM을 Advanced Risc Machine로 읽는 분들도 계실듯 -_-;;

bookworm_의 이미지

저요...... ㅡㅡ;
--
Bookworm

Bookworm

bookworm_의 이미지

coredump나 exit가 필요할 때에는 stdout 또는 stderr로 뽑습니다만, 계속 실행 중에 trace에 필요하면 화면에 나오는 내용하게 헷갈리더군요.

그래서 저는 syslog 쪽으로 뽑습니다. local0이나 local1으로 해놓고, 레벨을 잘 분류해 놓으면 좋더군요.
--
Bookworm

Bookworm

익명 사용자의 이미지

ddd 같은 툴을 사용하는 것이 가장 좋은 방법이라고 생각되지만, 경우에 따라서는 툴을 사용할 수 없는 여건도 있지요. 그럴땐 역시 많은 디버깅 메시지를 출력하도록 하는 것이.
아래는 제가 사용하는 메시지 출력 매크로입니다.

#define DMSG(n, msgs...) \
do { if( (n) & debug_mask ) \
sprintf( debug_message_buffer, msgs ), \
fprintf(debug_messageg_file, "[%04x] %s:%4d: %s: %s\n", \
n, __FILE__, __LINE__, __FUNCTION__, \
debug_message_buffer ); } while(0)

lovehis의 이미지

음... 제 개인적인 생각은...
툴은 언제라도 배울수 있습니다.

툴로 디버깅 하는 것은 좀 나중에 하시고....

지금은 머리로 하십시요.
잘만 활용하면 가장 좋은 디버깅 툴임니다.

툴에 익숙해지면... 정작 중요한 것을 놓칠수 있습니다...

JBuilder에 익숙해져 Java를 까먹은 바보가...^^*
--
늘...

익명 사용자의 이미지

디버깅을 잘하는 방법이라..

C 프로그램을 짤때..

(A B C)

(A-1, A-2, A-3, A-4 )

(B-1, B-2, B-3 )

(C-1, C-2 )

(A-1-1, A-1-2, A-1-3 )

......

하여간 이렇게 모듈화를 하는 쪽이 debug를 하기 좋으며

debug시에 편하도록 하기 위하여 모든 데이터는 될 수 있는데로 묶어서 사용 (이를테면 2개이상만 되면 무조건 structure안에, 그리고 많을 경우에 structure안의 structure로)

그리고 변수는 전역변수를 쓰지 말것..

그러면 체크하기가 아주 쉬워집니다.

그리고 모든 함수들은 에러와 성공으로 나누어서 리턴값을 받고.. 그 결과값에 대한 처리를 다 해주면.. 모든 함수들이 연결이 되죠.. 에러일 경우에..

디버그를 할때 제일 중요한 것은 따라다닌다는 것인데.. 이렇게 모듈을 계층형으로 만들어놓고 성공실패를 따라가다보면.. 자연스럽게 나오죠..

그리고 에러시에는 로그를 남기고요..

제 로그찍는 방법은
:프로세서번호:시간:에러모듈이름:에러코드 및 에러 메시지:

그리고 debug를 할때.. 코드를 다 짜놓고 하는 사람인 경우, 소스가 클 때... 아예 debug option을 만들어 쓰는 것입니다.

$program debugmode

이렇게 debugmode라는 형태로 구동이 될때..
debugmode 값을 셋팅하고, 그럴 경우에 따라가면서 출력하는 루틴을 넣어두면 그쪽은 다 프린터가 되죠..

이런 경우에는 debugmode를 안쓰면 아무것도 표시가 안되죠..

그리고 또 한가지 방법은 소스안에 define으로 정의를 하는 방법..

#define DEBUGMODE

#ifdef DEBUGMODE
printf("A");
#endif

이렇게 쓰는 경우도 있습니다.
위에 DEBUGMODE를 셋팅 안하면 거기에 해당하는 것들은 무시가 되는..

하여간 여러가지 방법이 있습니다만.. 제일 좋은 방법은.. 모듈화에 계층화를 성공하는 방법이라 생각합니다. 머 시간이 없다면 어쩔 수 없지만..
이 계통에서 계속 살아 남으려면 그래도 라이브러리루 쓸 수 있는 것을 편집하면서 살아야 하지 않을까요?

gdb는 제약사항이 많기 때문에 embeded쪽이나 단순 프로세서를 디버깅 할 경우에는 괜찮기는 하지만.. 정확하지 않습니다. 특히 메모리에 관한 버그는..

airdh의 이미지

툴이란건 사용하면 사용할 수록 늘게 되어있습니다.
주위에서 권하는 툴 몇개를 사용해본다음 자신과 궁합이 잘 맞는 툴을 장시간 계속해서 사용하면 툴 다루는 방법은 자연히 늘게 될것입니다.
(사실 툴은 환경에 종속적이므로 애써서 많이 공부해야할 수준이라면, 공부를 보류하는 것도 나쁘진 않습니다... ^^ 단발성 프로젝트나 작업을 위해 거대한(?) 툴을 익히는건 낭비도 될 수 있죠.)

일반적으로 통용되는 툴을 적용할 수 없는 경우도 생기기 때문에 (임베디드쪽에 이런 경우가 많죠), 평소에 올바른 프로그래밍 습관을 길러야하고, 잘된 프로그램을 많이 분석해보아야하고, 튼튼한 설계에 관해서 고민을 많이 해야합니다.

설계단에서 부터 원죄적인(?) 오류가 있다면, 그것은 어떤 툴이나 후처리(?)를 적용하더라도 작업이 진행된 만큼의 고통을 안겨줄 것입니다.

학부때 교수님 말씀이었는지 어디 책에서 읽었는지 잘 생각은 나지 않고, 원문도 생각나지 않지만 대충 다음과 같이 해석되었던 문장들이 생각나네요.

"벌레는 언저리(바운더리)에 많이 살고 있다."

"깨끗한 코드는 더러운 손에서 나온다."

多路

익명 사용자의 이미지

Debugging Application 이라는 책자를 권하고 싶습니다.

그리고 문제가 발생되었을때 처치하는것도 좋지만, 문제가 발생되지 않게 만드는것이 더 좋다고 생각합니다.

익명 사용자의 이미지

MY IP?

익명 사용자의 이미지

아이피 보이게하면 뭘하나

익명 사용자의 이미지

허허

ihavnoid의 이미지

저는 디버그 시에는 주로 insight을 쓰고요...
소스분석은 linux cross reference (http://lxr.sourceforge.net/ 씁니다..)

뭐 언어에 따라 쓰는 디버거가 다르긴 하지만....
디버거한테 의존하는 경우는 별로 없습니다...
대다수의 경우에는 코드를 짜면서부터 대량의 debug message를 출력하도록 하면, 메세지를 좀 읽어보고 분석이 가능합니다...
그래도 분석이 안되면 디버거를 돌리죠...
(물론 완성 후에는 이를 출력하지 않도록 하죠...)

이런 메세지의 유용한 점 중 하나는, 잘 작성을 해 놓으면 단순히 debug output이 아니라, 하나의 주석으로 작용을 하기도 한다는 것입니다...

오히려 디버거를 소스분석할 때 쓰는 경우가 많죠...
optimize되지 않은 version의 소스를 돌려서, local variable이 어떻게 바뀌나 유심히 관찰하면서, 소스코드의 흐름을 따라갈 때는 좋더군요.. ^^

음.. 갑자기 든 생각인데요....
컴파일러를 개조해서... 옵션을 붙여놓으면, 함수 내의 주석을 출력하도록 하는 것도 좋을 것 같아요.. ^^

가령....

int a_function(int val){
/* entering a_function : val=$val */
int i,j;
/* begin of the outer loop */
for(i=0;i<100;i++)
/* begin of the inner loop (i=$i) */
for(j=0;j<100;j++)
some_function(i,j);
}

이런 식으로 코드를 짜 놓으면....
컴파일 시 --print-comments 뭐 이런 옵션을 붙여놓으면.. 함수 안에 만들어 놓은 comment가 하나하나 debug message로 변환되는...

음... 이런 기능이 생기면 디버그할때 주석 참 많이 달아놓을텐데.. ^^

(음... whitespace가 몽땅 무시되는군요-_-;;)

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

musiphil의 이미지

이미 매크로로 충분히 할 수 있는 일 아닌가요?

가장 원초적이고 간단하게는 이렇게 해볼 수 있겠네요.

#ifdef DEBUG
#define dprintf printf
#else
#define dprintf (void)
#endif

dprintf("entering a_function : val=%d\n", val);

ihavnoid의 이미지

물론 가능하기도 하고, 이미 저 역시 그렇게 하고 있기는 하지만요...
그냥 '언어 자체에서 간편하게 지원하는 방법이 없을까' 싶어서 그런 것이었습니다.. ^^

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

musiphil의 이미지

오히려 제가 소개한 매크로를 사용하는 방법이 '언어 자체에서 지원되는' 방법 아닙니까? 컴파일할 때 --print-comments 등 특정한 옵션을 붙이면 프로그램의 동작이 달라지도록 하는 것이 오히려 특정 컴파일러에 의존할 수밖에 없게 하는 것이지요.

--print-comments 옵션을 쓸 수 있다면 -DDEBUG 옵션을 못 쓸 이유가 없지 않습니까? 오히려 매크로를 사용하는 것이 이식성 면에서도 더 좋습니다.

그리고 뭐가 출력될지는 프로그래머가 정할 수 있어야 합니다. 옵션으로 아무 주석이나 다 출력해 버리면 주석 마음 놓고 못 답니다. :-) 주석은 주석일 뿐이지요. 또한 디버깅 정보가 어디로 출력될지도 프로그래머가 정할 수 있어야 하며, 모든 디버깅 출력이 stdout으로 가는 것 또한 늘 바람직하다고 볼 수는 없고 오히려 stderr나 로그 파일이 더 유용할 때가 많습니다. (제가 들었던 예에서는 최대한 간단하게 하기 위해 그냥 printf를 사용했습니다만..)

결국 --print-comments가 -DDEBUG에 비해 나은 점이 없어 보입니다.
간편함을 말씀하셨지만 저로서는 최소한의 간편함도 찾을 수가 없습니다.
이미 쓰고 계시는 방법 잘 쓰시길 바랍니다. :-)

서지원_의 이미지

글쎄요.. macro등으로 충분히 할 수 있는 일을 language에서 해 주는것이 필요할지는 의문이네요.. :)

정말로 그런 feature - 함수의 설명을 함수의 attribute로 지정할 수 있는 것 - 가 필요하다면, python이나, lisp등을 사용하면됩니다.

If you want X, you know where to find it. :)

익명 사용자의 이미지

good idea!

진짜로 저런 기능이 있으면 편하겠네요..^^;

dyaus의 이미지

일정규모 이상의 프로그램을 작성할때는 log level 설정을 하고,
log function 들을 정의해서 사용하면 도움이 됩니다.
디버깅을 할때는 가능한 많은 정보를 확인하고 서비스단계에서는
심각한 에러 수준만 출력되게 하는 방법이죠.

그럼, 코딩할때, 어떤 부분에서 어떤 값이 어떻게 변하는지 확인하고 싶으면.
적당한 수준의 log function을 설정해서 디버깅을 진행하고.
디버깅이 끝났다 생각되면 그 부분들을 모두 무시하도록 해버리는 방법도 있겠구요.

익명 사용자의 이미지

간단한 디버깅인 경우는
linux 에서 strace, solaris 에서 truss..
뭔가 문제가 있을 경우에는
gdb 를 주로 사용합니다..
gdb gui 는 익숙치 않아서 사용하지 않구요..
디버깅 기술 역시.. 개인이 만들어 내는
skill 이 아닐런지...? :)

익명 사용자의 이미지

ddd는 gdb의 gui툴인데요.. (디폴트로 대충 다 깔려있습미다.)
gdb조금 손댈줄 알면.. 대충 손댈수 있습미다..
정말 훌륭한 툴입미다.. 이런걸 일찍 발견하지
못한게 후회될 지경입미다.. 그리고 gdb때문에..
이맥스 쓰시는 분들도 있는데.. 저도 이맥스 써볼까
했는데.. 배우기 귀찮쵸.. -_- 어쨌든..
개인적으론 디버깅에 ddd만한게 있을까 하는게 제생각입미다.. 사실 너무 훌륭하잖아여.. (__ __) ...
덤으로 한가지더 알려 드리면..
소스 분석하기 위한 툴로
source-navigator가 있습미다.. 역시 훌륭하죠..
이거 없이 소스 분석하라면.. 대책이 안설껄요...

익명 사용자의 이미지

감사해요..
저 바로 DDD깔았어요...꾸벅

cedar_의 이미지

GDB가 어려우시다면,
GDB의 GUI 프런트엔드인
DDD(Data Display Debugger)를 써보세요.
http://www.gnu.org/software/ddd/
감히 최고의 GUI Debugger라고 말할수 있습니다!

그 외에도 다른 리눅스용 IDE에 있는 디버거도 쓸 만합니다.
대표적으로 Kdevelop(GCC 용)이나 Kylix(리눅스용 BC++)도 정말 편리하지요.

익명 사용자의 이미지

님께도 감사..꾸벅

오늘부터 DDD써야지..하하.

knight2000_의 이미지

Kylix는 리눅스용 Delphi 라고 알고 있습니다.
아니면 리눅스용 Object Pascal 이라고 해야 하나요?

cedar_의 이미지

카일릭스는 3버전부터 델파이(오브젝티브 파스칼)뿐만 아니라,
C++을 포함하고 있습니다.
즉, 리눅스용 C++Builder라고 할 수 있죠.

익명 사용자의 이미지

온리 gdb는 아니지만 지존 gdb..흐흐흐

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.