스코프를 벗어난 객체 주시하기
디버깅을 하다 보면 스코프를 벗어난 객체를 계속 주시하고 싶을 때가 있습니다. 하지만 비쥬얼 스튜디오의 조사식 창(Watch Window)에서는 입력한 객체가 스코프를 벗어나면 비활성화가 되어 더이상 값을 확인 할수 없게 되어버리죠. 이 때, 조사식에 주시 하고픈 객체의 포인터를 입력하면, 해당 객체가 스코프를 벗어났더라도 (해당 객체가 살아 있다면) 지속적으로 값을 확인할 수 있습니다.
위 코드를 보면 mHyuna 객체는 이미 스코프를 벗어나 조사식 창에서 비활성화가 되었지만, (CHyuna*)0x0031fe2c 식으로 직접 객체의 주소를 참조하여 스코프를 벗어난 객체의 값을 확인할 수 있습니다.
배열값 확인
간혹 매우 큰 크기의 배열을 사용할때가 있습니다. 대략 1만개라고 해보죠. 이 배열 내부의 값을 확인하려면 어떨까요? 1만개의 배열을 일일히 확인하려면 엄청나게 스크롤링을 해야 할 것 입니다.
이럴때 범위식을 사용하여 특정 구간의 값만을 확인하는 방법이 있습니다. 배열명, 범위 식으로 조사식 창에 입력하여주면 그 범위 만큼의 배열만 보여주는 것이죠. 또한 포인터 연산을 통해서 특정 범위 부터의 값도 확인할 수 있습니다.
CRT 라이브러리를 활용한 메모리 누수 탐지
메모리 누수는 항상 골치 거리입니다. 수많은 코드들 중에서 어디서 메모리가 새는지 원인을 찾기도 힘들죠. CRT 라이브러리를 활용하여 메모리 누수 지점을 찾기 위한 방법이 있습니다. 먼저 아래와 같이 CRT 라이브러리를 사용하기 위한 헤더를 선언 해줍니다. 그리고 메모리 누수 체크를 위한 플래그를 선언 해줍니다( _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); ).
위 코드를 보시면 일부러 char[8] 만큼의 메모리를 할당 해주고, 해제를 안하고 있습니다. 이 코드를 실행시키면 아래와 같이 출력 창에서 메모리 누수가 탐지 되었다는 메시지가 나타납니다.
출력창 메시지에서 빨간 네모 박스의 숫자를 잘 기억해두세요. 이 것이 메모리가 누수되는 위치를 가리키고 있는 값입니다. 이제 이 값을 이용해 메모리 누수 위치를 찾아보도록 하겠습니다.
우선 프로그램 아무 곳에나 중단점을 걸고 디버깅 모드로 들어갑니다. 되도록 이면 프로그램의 시작 점에 거는 것이 좋습니다. 디버깅 모드에 들어갔으면 아래와 같이 조사식 창에 {,,msvcrXXXd.dll}_crtBreakAlloc 을 입력해줍니다. 여기서 XXX는 비쥬얼 스튜디오 버전을 적어줍니다. 2008일 경우 msvcr90d.dll, 2010일 경우 msvcr100d.dll, 2012 일 경우 msvcr110d.dll 입니다.
조사식 창에 위의 구문을 입력하면 처음에는 값이 -1로 나올 것입니다. 여기에 출력창에 나왔던 메모리 누수 위치값을 입력해줍니다. 위의 예제에서는 108 이죠. 그 다음 F5를 눌러 프로그램 실행을 재개합니다.
그러면 어디선가 중단점이 걸립니다. 이제 콜스택을 확인해봅니다.
중단점이 걸린 곳은 msvcr110d.dll 모듈입니다. 이 부분은 디버깅을 위한 곳이니 신경 쓰지 마시고, 밑으로 따라 내려가 보시면 실제 작업 영역 호출 부분이 있습니다. 이 곳으로 따라 가보면...
짜잔~ 메모리를 할당하고 해제 하지 않은 부분을 찾아냈습니다. 이렇게 CRT 라이브러리를 이용하여 메모리 누수 원인을 찾아 낼수 있습니다.
값이 변경 되는 위치 찾기
디버깅을 하다보면 특정 변수가 어디서 값이 변경 되는 지를 알고 싶을 때가 있습니다. 변수를 사용하는 곳을 전부 검색하여 중단점을 걸어서 볼수도 있지만 데이터 중단점 기능을 이용하면 값을 변경 하는 곳을 손쉽게 찾을 수 있습니다.
먼저 추적 하고 싶은 데이터의 주소를 파악합니다.
그 다음 비쥬얼 스튜디오의 디버그 -> 새 중단점 -> 새 데이터 중단점을 선택합니다. 여기에 위의 데이터 주소 값을 입력 해줍니다. 타입의 크기 값에 주의 합니다.
중단점을 추가 한 후, F5를 눌러 실행을 재개합니다. 그러면 어디선가 해당 데이터가 값이 변경 되면 아래와 같이 중단점이 작동하게 됩니다.
위의 예제에서는 SexyUp 함수에서 해당 데이터를 변경하는 것을 알아냈습니다.
출처 및 참고
Code Project Article - 10 Even More Visual Studio Debugging Tips for Native Development
Code Project Article - 10 More Visual Studio Debugging Tips for Native Development
MSDN - CRT 라이브러리를 사용하여 메모리 누수 찾기
'프로그래밍' 카테고리의 다른 글
맘에 안드는 PIMPL 패턴 (C++) (5) | 2013.06.03 |
---|---|
도플광어의 html5 게임엔진 만들기 1편. 웹은 게임기이다. (9) | 2013.05.05 |
비쥬얼 스튜디오 디버깅 팁 ( Visual Studio Debugging Tips ) (31) | 2013.04.10 |
미니덤프 파일이 안남는다고 디버깅을 포기할텐가?!?!!?!! (0) | 2013.04.06 |
std::numeric_limits 의 min, max는 왜 클래스 내부 초기화를 할 수 없는가?! (4) | 2013.04.06 |
C++에서 ID Type이 필요할때 어떻게 쓰시나요?? (0) | 2013.04.05 |
댓글을 달아 주세요
본문은 잘 읽었습니다. 요즘 C#만 써서 그런지 디버깅이 무척 유용하더라고요.. ㄷㄷ
그런데 VS 버전 몇 쓰고계신가요?
꽤 마음에드는 컬러배색인데..
저는 흑요석의 아들을 VS2010에서 쓰고있는데 디버깅창이나 출력창도 색을 바꿀 수 있는지도 궁금하네요.
VS2012 다크 테마 + Son of Obsidian 컬러링( http://studiostyl.es/ ) 쓰고 있어요.
좋은 정보 감사합니다^^
좋게 봐주셔서 감사합니다.
내공 냠냠 하겠습니다.^^
저두 냠냠~
아니 어째서 태연이가 현아한테 인사를 하면 현아의 섹시가 업 되는건가요?!?!!?
패왕이시니까 가능합니다.
"String 변수명,s8"
이라고 쓰면 utf8 string도 잘 출력됩니다.
전 이걸 몰라서 불편하게 디버깅을 했었읍니다.혹시 저와 같이 필요한 분이 있을까 해서 올려요
좋은 정보 감사합니다
아주 유용한 팁이네요~ 좋은 정보 감사합니다. ^^
좋은말씀 감사합니다
좋은 정보 감사합니다
좋은 댓글 감사합니다.
오우 유용한팁~ 정말 감사합니다.
오우 유용한팁~ 정말 감사합니다.
좋은 댓글 감사합니다
프로그램이 실행될때마다 다르게 동작하는데 위의 디버깅 방법은 현실적으로 무용지물인 방법.
프로그램이 실행될때마다 다르게 동작하는데 위의 디버깅 방법은 현실적으로 무용지물인 방법.
어떻게 무용지물이라는건가요...?
실무에서도 잘 사용하고 있는 방법들인데...;;
프로그래밍 실행할때마다 메모리 주소가 바뀐다는 말씀이신거 같아요.. 프로그래밍을 어떻게 짜느냐 따라 그런 경우가 있을수도 있지만 안그런 경우도 있죠. 특히 async 로딩을 하면 로딩 끝날때 메모리 할당 등이 일어나면 그렇구요.
근데 그런 경우가 100프로인 프로그램은 없을텐데요. 무용지물이란 말은 너무 섯부른 일반화인듯....
런타임 디버깅시 아주아주 좋은 팁 맞습니다.
저는 수년간의 삽질 끝에 몇가지를 알아내서 쓰고 있었는데. 이렇게 보기 좋게 정리해주셔서 새로운 것도 알고 가네요. 고맙습니다.
이런 노하우들을 모은 개발도구들의 사용법이나 디버깅 방법에 관한 책도 있었으면 좋겠이요. 다른 분들은 삽질 좀 덜하고 더 좋은 노하우도 만들어 낼 수 있게.
옳으신 말씀입니다~
이제서야 이런 좋은 정보를 보다니...
좋은 정보 감사해욤 !!!
좋은 댓글 감사합니다
와 주소로 브레이크포인트...여태 몰랐네요.
정말 유용하게 쓰겠네요.
좋은 팁 감사합니다.^^
좋은정보 감사합니다
블로그에 담아가고싶네요..
담아갈게요~~
좋은 정보 감사합니다.
블로그에 담아갈게요^^