꽃미남 프로그래머 김포프가 창립한 탑 프로그래머 양성 교육 기관 POCU 아카데미 오픈!
절찬리에 수강생 모집 중!
프로그래밍 언어 입문서가 아닌 프로그래밍 기초 개념 입문서
문과생, 비전공자를 위한 프로그래밍 입문책입니다.
jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다.
Posted by 비회원
안녕하세요. 오랫만의 테스팅 관련 글입니다. 그동안에 뭘 했냐면 구글 드라이브의 스프레드시트를 이용한 무료 Testcase 서식을 만들었습니다.


testcase_6 

 문서를 열면 Summary 페이지가 먼저 보입니다. 아래 탭을 확인하면 Summary Data, Testcase, Bug List의 4개 탭이 있습니다. 우선 Summary 페이지부터 보겠습니다. 

  testcase_1 

맨 위에는 진행중인 프로젝트 명이 들어가고 아래에는 진행된 테스트중 나온 버그들중 중요한 이슈를 담고 있는 버그 리스트를 넣습니다. 중요도 높음인 문제가 주로 들어 갈 수 있겠지요. 문서를 보는 사람에게 중요한 문제를 각인시키는데 필요한 내용입니다. 참고로 버그의 중요도는 사전에 개발자들과 어느정도 합의가 되어 있는 것이 좋습니다. 물론 문제란게 그 합의된 범위 외에서 나오는 경우도 많습니다만. 사전 상의를 통해 개발자들과의 불필요한 커뮤니케이션 시간을 줄일 수 도 있습니다.

  testcase_2 

그 아래에는 진행된 테스팅 차수에 대한 결과를 볼 수 있습니다.  예제 문서에는 버전별 결과물로 나오지만 사정에 따라 차수별로 바꾸셔도 됩니다.  문제의 중요도별 변화량과 Testcase의 차수별 성공율 변화를 확인 할 수 있습니다. 막대 그래프는 아래로 깔릴 수록 좋은 것이고 Test 성공율은 올라갈 수록 좋은 것입니다. 해당 그래프에 데이터를 반영하기 위에서는 아래의 탭중 Summary data 탭으로 이동해야 합니다.

  testcase_3 

Summary Data탭의 화면입니다. 매우 단순합니다. 그냥 셀에 맞는 내용을 적어주시면 반영됩니다. 반영이 잘 안 될 경우에는 챠트의 고급수정에서 데이터 영역을 다시 지정해 주면 됩니다. 엑셀과 거의 동일하니 엑셀을 좀 다루 실 줄 아시면 쉽게 수정 가능합니다.

  testcase_4 

다음은 Testcase 탭입니다. 프로젝트 이름은 당연히 해당 프로젝트의 이름을 적습니다. 오른쪽에는 Version을 넣는 곳이 있습니다. SVN의 Revison으로 관리하는 곳이 있기도 하니 입맛에 맞춰서 수정하면 됩니다. 아래를 보면 pass, fail, block의 수와 함께 총 Testcase 갯수, Test 성공률이 나오는 영역이 있습니다. 이쪽은 자동으로 입력이 되도록 만들어져 있습니다. 그럼 그 아래가 진짜 Testcase 입니다. 참고로 해당 Testcase는 게임 도메인에서 주로 쓰는 서식입니다. 그리고 위에 대중소분류 및 조건 결과와 같은 내용이 있는데 해당 내용은 꼭 맞춰서 쓰지 않아도 됩니다. 적당히 수정해서 사용하면 됩니다. 테스트 결과는 o,x,b만 입력가능하게 되어 있습니다. 조건부서식과 데이터 확인 옵션이 들어가 있는데 역시 환경에 맞춰 수정해서 사용하시면 됩니다. 참고로 열을 추가하거나 삭제 할 경우 테스트결과를 참조하여 위에 테스트 결과 영역이 자동으로 입력되도록 한게 어긋 날 수 있습니다. 기본 엑셀을 다룰 줄 아신다면 쉽게 고치는 법을 아실거라 생각합니다.

  testcase_5 

마지막 Bug list 탭입니다. 테스트 중 발견된 Bug를 정리하는 부분입니다. 왼쪽부터 입력되는 내용은 다음과 같습니다.
  • no. : 번호
  • Version: 문제가 발생한 Client Version 을 기록합니다. Revison을 사용하기도 합니다.
  • Tester : 해당 문제를 발견한 테스터의 이름을 적습니다.
  • 담당자 : 해당 문제를 담당한 사람의 이름을 적습니다. (ex: 프로그래머, ui, 아티스트 등등)
  • 분류 : 문제를 분류 할 수 있다면 분류를 적어 두는 것이 좋습니다. (ex: UI, 파티 시스템, 채팅 시스템, 성장 시스템 등등)
  • 중요도 : 문제의 중요도를 기록합니다. 당연하지만 심각 일 수록 바로 수정되어야 하는 문제입니다. 모든 문제를 심각으로 할 경우 개발팀과 살인 피구가 벌어 지기도 합니다.
  • 상태 : 문제의 상태를 기록합니다. BTS의 기본 시스템을 따르고 있습니다.
    • 새로운문제: 테스터가 새로운 문제를 등록 시 지정
    • 문제확인: 담당자가 해당 문제를 확인 했을 경우 지정. (담당자가 직접 변경)
    • 문제수정: 담당자가 해당 문제를 수정 했을 경우 지정 (담당자가 직접 변경)
    • 완료: 테스터가 해당 문제가 수정 된 것을 확인 했을 때 지정 (테스터가 직접 변경)
    • 재수정요청: 테스터가 해당 문제가 수정 되지 않은 것을 확인 했을 때 지정 (테스터가 직접 변경)
  • 내용 : 문제의 내용을 상세하게 기록합니다. 문제를 적는 방법은 이전 포스트 "당신의 버그 리포트에 꼭 들어가야 할 내용들"을 참고 합니다.
  • 담당자 comment는 필요할 경우 담당자가  Comment를 남길 때 사용합니다.
해당 문서의 사용 방법은 위 내용만 알면 끝입니다. 문서를 사용 하실 때는 위 링크의 문서에 바로 수정은 안되니 사본을 만들어 본인의 구글 드라이브로 복사 후 이용 하시면 됩니다. 엑셀과 관련된 내용에 대해서는 구체적인 언급을 안하고 있습니다만 위 문서에 사용된 엑셀 관련 스킬은 정말 난이도 하급으로 어렵지 않습니다. 독학으로도 어렵지 않게 배우 실 수 있을거라 생각합니다. 이제 해당 문서를 만들게 된 경위에 대해서 썰을 풀까 합니다. 혼자 썰을 푸는건 심심하니 저희 집 고양이를 불러 대담을 진행해 보도록 하겠습니다. 

  mr_hyper : 안녕하세요. 성장이 없는 8Bit Dog의 주인 하선생입니다. 

 기시감 : (사료통을 흔든다) 

  mr_hyper  : 죄송합니다. 바로 질문으로 넘어가죠. 왜 이 문서를 만들게 되었죠? 

기시감 : 이유는 여러가지가 있습니다만 현재의 목표는 2개 입니다. 편하게 공동 작업을 할 수 있도록 하는 것과 테스트에 대해 생소한 분들에게 쉽게 다가가기 위한 이유 입니다.

  mr_hyper : 공동 작업을 할 수 있다는 건 동시에 일을 할 수 있다는 것인가요? 

기시감 : 게임 테스트의 경우 게임의 장르에 따라 한 게임에 몇십명이 되는 테스터가 같이 테스트를 하는 경우가 많습니다. 아마도 대부분의 작업 환경은 테스터 모두 따로 엑셀 문서에 테스트 결과를 작성하고 그걸 lead에게 보내면 lead가 취합하는 경우 일 것입니다. 하지만 구글 드라이브 문서를 이용하면 동시에 여러명의 사용자가 하나의 문서를 열어 동시에 작업을 하는게 가능 하더군요. 거기에 작업 내용또한 수시로 백업이 됩니다. 온라인에서만 사용 할 수 있다는 제약이 있지만 효율성 높은 작업 환경을 만들어 준다고 생각합니다. 그리고 모바일 디바이스에서도 쉽게 문서를 작성 하고 수정 할 수 있다는 점도 장점입니다. 클라이언트와 엑셀을 왔다갔다하며 작업 하는 것보다 외부 디바이스에서 테스트 결과를 바로바로 처리 할 수 있다는 점은 분명한 장점입니다.

  mr_hyper : 테스트에 생소한 분들에게 쉽게 다가가기 위함이란 건 무슨 말인가요? 

 8 Bit Dog : 해당 문서를 만들던 초반에 운 좋게도 한 모바일 게임 스튜디오의 테스트 업무를 도와주게 되었습니다. 개발자 분들은 QA에 대해서 처음 경험하는 상황이었고 저는 간단하게 그분들과 커뮤니케이션과 업무를 할 수 있는 Tool 이 필요하게 되었죠. 맨티스나 레드마인과 같은 툴도 있습니다만 그런 걸 준비할 환경은 안되었기 때문에 작업중인 문서에서 해당 툴의 기능을 최소한적으로 적용 할 수 있도록 해봤습니다. 그 결과 거창한 툴보다는 오히려 최소화 되었지만 집중된 기능이 더 낫다는 생각을 가지게 되었습니다. 기본적인 테스트의 프로세스를 경험 시켜 드릴 수 있었으며 엑셀 문서와 가깝기 때문에 친숙했죠. 아마도 맨티스, 레드마인 툴을 사용하게 될 기회가 오더라고 금방 적응 하실 수 있을 거라 생각합니다.

  mr_hyper : 지금까지 주구장창 장점만 얘기 하셨는데 단점은 없는 겁니까? 

기시감 : 물론 있습니다. 온라인 상태에서만 제 역활을 할 수 있다는 점이지만 요즘 같은 시대에 이정도는 커버 되겠죠. 그리고 또 단점을 꼽자면 간략화 되어 있기 때문에 파워풀하게 사용 할 수는 없다는 것입니다.

  mr_hyper : 파워풀이요? 이건 무슨 보그병신체인가요.. 

기시감 : 죄송합니다. 파워풀하다는건 예를 들자면 이 문서의 Bug list는 맨티스와 같은 전문 BTS 툴과 비교하자면 트래킹 기능에서 매우 약합니다. 이런 부분은 전문 툴만이 가질 수 있는 강점이죠. 뭐 그런 걸 얘기하는 거였습니다.

  mr_hyper : 그렇군요. 그럼 마지막으로 하실 얘기 부탁 드리겠습니다. 

기시감 : 모바일 디바이스 시장이 활짝 열리며 작은 개발 스튜디오가 매우 많이 생겨 났습니다. 모두들 좋은 게임을 만들기 위해 노력하고 있다고 생각합니다. 테스트라는 것은 언제나 성공 이후에 따라오는 것이었습니다. 하지만 그건 이제 과거 이야기라 생각합니다. 성공하기 위해서 더욱 필요한 것이 테스트입니다. 여러분들이 만드는 좋은 게임에서 버그가 1개가 있으면 그 버그를 체험하는 유저가 1000명이라면 1000명의 실망하는 유저가 생겨나는 것입니다. 테스트는 어려운 것이 아닙니다. 제 문서가 조금이라도 도움이 되어 좋은 게임이 좋은 품질로 완성 되었으면 합니다. 감사합니다.



댓글을 달아 주세요

  1. 성호 2014.02.24 09:44  댓글주소  수정/삭제  댓글쓰기

    잘 받아갑니다.

Posted by 밥을먹는선비


들어가며...


유니티 엔진의 코루틴 강좌를 마치고 잠시 강좌를 쉬었습니다. 


이번 ndc13 에서 발표한 pig2d 엔진에 대해서 강좌를 통해서 좀더 자세히 내용을 풀어보려고합니다.

pig2d 학생들 교육을 위해서 개인적으로 만든 2D엔진이며 html5전용으로 개발하였습니다.


깃허브에 소스를 공개했으며 학교에서 하는 프로잭트와 함께 계속 진행할예정입니다.


https://github.com/gbox3d/pig2d


강연에서 다루지 못한 이야기들을 강좌를 진행하면서 상세하게 다뤄 보도록하겠습니다.

(ndc13 강연자료는 개인적으로 따로 배포할계획은 없습니다. 강좌로 대신할 예정입니다.)


이후에는 반응을 봐서 three.js 기반으로 한 하이브리드 방식의 3D 엔진개발에 대한 이야기도 풀어 보도록 하겠습니다.


강좌 순서


html5 2d 엔진(Pig2d)


1편. web 은 게임기이다.

2편. 웹킷과 css

3편. css 하이브리드엔진 개발

4편. 씬관리자 만들기 

5편. 효과적인 애니메이션 구현


6편. 캔버스를 스마트하게 활용해봅시다.

7편. kinectics.js

8편. 웹기반의 클라우드 스프라이트툴 만들어봅시다.

9편. pig2d 기반 웹게임개발 프레임웍



html5 3d 엔진(Lamb3d)


1편. three.js 의 css 랜더러 

2편. css로 모델,뷰,프로잭션 변환

3편. 조명 따라잡기

4편. SVG 를 응용한 하이브리드 모델링

5편. css 이용한 하이브리드 3d 애니메이션

6편. loud of lamb 프레임웍 분석


강좌순서나 제목은 사정에 따라 수정될수있습니다.


1. 티스토리를 게임기로?!


일단 블로그에 아래처럼 이미지를 올렸습니다.

이것을 가져다가 동적으로 사용할수있을까요?






먼저 실제로 이파일의 온라인상의 경로를 얻어보도록 하겠습니다.



위의 'getfile' 버튼을 클릭하면 바로 아래에 파일의 경로가 나오시나요?

html문서트리에 동적으로 접근하여 정보를 얻어낸것입니다. 우리가 일반적으로 생각하는 정적인 웹이 아니 동적이 웹인것입니다.

블로그에 글을쓰는것과 복잡한 프로그래밍 언어로 게임 코딩하는것이 별차이가 없는 일이 될날도 멀지않았을수도 있고 이미 벌써 그럴수도 있다는 것을 의미합니다.


2. div 를 보는 새로운 시각





위의 빨간색 사각형모양은 아래와 같이 div에 스타일을 적용해서 사각형을 출력한것입니다.


<div style="

            width: 32px;

            height:  48px;

background-color : red;


"></div>


사실 빨간색 글박스 지나지 않는다고 그냥 무시해버릴수도있을것입니다. 


과연 그럴까요?






3. 초간단 게임개발 환경


화면 하단에 보이는 div를 이용해서 만든 작은 박스를 주목해주십시오. 이 div 객체의 아이디값은 test_sprite입니다.



 

run code 버튼으로 텍스트 편집창의 자바스크립트코드를 실행을 할 수 있습니다




버튼을 눌러 실행을 하면 이미지가 박스안에 나오것을 확인 하실수있을겁니다.


그리고 간단하게 스프라이트를 움직여도 볼수있습니다.

아래코드를 편집창에 붙여넣기 하시고 run버튼을으로 실행시켜 보세요.

$('#test_sprite').css('-webkit-transform','translate(200px,0px)');


파폭에서는

$('#test_sprite').css('-moz-transform','translate(200px,0px)'); 


translate 에 인자로 들어가는것은 2D 좌표계입니다.


위의 내용은 모두 html 편집모드로 글을 쓴것입니다.(글을 쓴다는것과 코딩한다는거의 경계가 좀 애매해지죠)


티스토리 블로그는 script 태그를 사용할수있어서 자신이 만든 라이브러리 뿐만 아니라 jquery 같은 것들도 사용할 수 있습니다.







4. 결론


정말 간단하게 스크립트 코드 편집창과 미리보기 화면이 갖추어진 게임개발 프레임웍을 구성해 보았습니다.

그것도 따로 호스팅같은 번거로운 절차없이 그냥 티스토리 블로그 글안에서 말이죠.(다른 서비스 전혀 사용하지 않았음)

뿐만 아니라 이 개발 환경은 아이페드같은 스마트기기에서도 사용할수 있습니다.


지금부터 여러분들의 사고가...

웹을 단순한 인터넷어플리케이션 서비스라는 편견을 깨고 가상의 게임기로 보이기 시작하시는지 모르겠네요. ^^;

그렇게 새로운 시야가 생기셨다면 html5의 세계로 들어 오는 입구를 찾으신겁니다.


콘솔은 끝났다. 이런 말을 하시는 분들도 계셨건거 같은데...

제가 차세대 게임기는 엑박도 피에스도 아닌 web이라고 생각 한다면 .... ^^;










댓글을 달아 주세요

  1. 김용준 2013.05.08 15:49  댓글주소  수정/삭제  댓글쓰기

    저같은 웹맹에게 너무도 흥미진진한 내용입니다!

  2. Favicon of http://jhj77012.blog.me/ 아이곰탱 2013.05.10 16:50  댓글주소  수정/삭제  댓글쓰기

    저도 기대됩니다~
    소스를 보다가 getFigjterImg을 getFighterImg으로 변경해야 될것 같은 ... ^^;

    • 도플광어 2013.05.10 19:04  댓글주소  수정/삭제

      그러네요^^; 오타가 좀 많네요 수정하도록 하겠습니다
      감사합니다.

  3. 최주드 2013.05.11 01:13  댓글주소  수정/삭제  댓글쓰기

    제가 차세대 게임기는 엑박도 피에스도 아닌 web이라고 생각 한다면 .... ^^;

    아 이말에 많은생각을하네요..... web의 무궁무진함을....

  4. 북치 2013.05.13 01:14  댓글주소  수정/삭제  댓글쓰기

    배우고 갑니다
    항상 책에서도 볼 수없는
    고퀄의글을 써주셔서 감사합니다

  5. 2015.03.06 13:54  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  6. 2015.03.06 13:54  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

Posted by 친절한티스

스코프를 벗어난 객체 주시하기

디버깅을 하다 보면 스코프를 벗어난 객체를 계속 주시하고 싶을 때가 있습니다. 하지만 비쥬얼 스튜디오의 조사식 창(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 라이브러리를 사용하여 메모리 누수 찾기

댓글을 달아 주세요

  1. Favicon of http://bluekms21.blog.me 크로스 2013.04.10 10:44  댓글주소  수정/삭제  댓글쓰기

    본문은 잘 읽었습니다. 요즘 C#만 써서 그런지 디버깅이 무척 유용하더라고요.. ㄷㄷ
    그런데 VS 버전 몇 쓰고계신가요?
    꽤 마음에드는 컬러배색인데..
    저는 흑요석의 아들을 VS2010에서 쓰고있는데 디버깅창이나 출력창도 색을 바꿀 수 있는지도 궁금하네요.

  2. 코로 2013.04.10 12:59  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사합니다^^

  3. 마르스 2013.04.10 22:12  댓글주소  수정/삭제  댓글쓰기

    내공 냠냠 하겠습니다.^^

  4. 알 수 없는 사용자 2013.04.11 12:04  댓글주소  수정/삭제  댓글쓰기

    아니 어째서 태연이가 현아한테 인사를 하면 현아의 섹시가 업 되는건가요?!?!!?

  5. 강이5 2013.04.17 08:20  댓글주소  수정/삭제  댓글쓰기

    "String 변수명,s8"
    이라고 쓰면 utf8 string도 잘 출력됩니다.
    전 이걸 몰라서 불편하게 디버깅을 했었읍니다.혹시 저와 같이 필요한 분이 있을까 해서 올려요

  6. 유래너스 2013.04.18 12:28  댓글주소  수정/삭제  댓글쓰기

    아주 유용한 팁이네요~ 좋은 정보 감사합니다. ^^

  7. 알 수 없는 사용자 2013.04.29 16:22  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사합니다

  8. 트레이져 2013.05.15 16:38  댓글주소  수정/삭제  댓글쓰기

    오우 유용한팁~ 정말 감사합니다.

  9. 트레이져 2013.05.15 16:38  댓글주소  수정/삭제  댓글쓰기

    오우 유용한팁~ 정말 감사합니다.

  10. 디버깅 2013.05.29 17:03  댓글주소  수정/삭제  댓글쓰기

    프로그램이 실행될때마다 다르게 동작하는데 위의 디버깅 방법은 현실적으로 무용지물인 방법.

  11. 디버깅 2013.05.29 17:03  댓글주소  수정/삭제  댓글쓰기

    프로그램이 실행될때마다 다르게 동작하는데 위의 디버깅 방법은 현실적으로 무용지물인 방법.

    • Favicon of https://gamedevforever.com 친절한티스 2013.06.07 22:44 신고  댓글주소  수정/삭제

      어떻게 무용지물이라는건가요...?

      실무에서도 잘 사용하고 있는 방법들인데...;;

    • Favicon of https://gamedevforever.com 김포프 2013.06.09 11:20 신고  댓글주소  수정/삭제

      프로그래밍 실행할때마다 메모리 주소가 바뀐다는 말씀이신거 같아요.. 프로그래밍을 어떻게 짜느냐 따라 그런 경우가 있을수도 있지만 안그런 경우도 있죠. 특히 async 로딩을 하면 로딩 끝날때 메모리 할당 등이 일어나면 그렇구요.

      근데 그런 경우가 100프로인 프로그램은 없을텐데요. 무용지물이란 말은 너무 섯부른 일반화인듯....

    • 나그네 2015.05.22 20:58  댓글주소  수정/삭제

      런타임 디버깅시 아주아주 좋은 팁 맞습니다.

  12. t 2013.06.13 12:26  댓글주소  수정/삭제  댓글쓰기

    저는 수년간의 삽질 끝에 몇가지를 알아내서 쓰고 있었는데. 이렇게 보기 좋게 정리해주셔서 새로운 것도 알고 가네요. 고맙습니다.
    이런 노하우들을 모은 개발도구들의 사용법이나 디버깅 방법에 관한 책도 있었으면 좋겠이요. 다른 분들은 삽질 좀 덜하고 더 좋은 노하우도 만들어 낼 수 있게.

  13. 영나미 2013.06.13 16:28  댓글주소  수정/삭제  댓글쓰기

    이제서야 이런 좋은 정보를 보다니...
    좋은 정보 감사해욤 !!!

  14. 태수 2013.09.09 16:09  댓글주소  수정/삭제  댓글쓰기

    와 주소로 브레이크포인트...여태 몰랐네요.
    정말 유용하게 쓰겠네요.

    좋은 팁 감사합니다.^^

  15. jewoo 2014.05.14 10:14  댓글주소  수정/삭제  댓글쓰기

    좋은정보 감사합니다

  16. Favicon of https://2ry53.tistory.com 뿡뿡대마왕 2014.10.03 10:20 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사합니다.
    블로그에 담아갈게요^^

Posted by 비회원

게임을 배포했습니다. 그런데 무언가 잘못되어 몇몇 유저들의 클라이언트가 비정상종료가 됩니다.

게시판이 난리가 나고 전화기에 불이 나고 머리는 노래지고.. 까진 보통 아니긴 합니다..

어쨌든!! 그런데 dmp파일이 안날아옵니다! 미니덤프를 붙였는데!!! 어째서!!!


보통 정상적인 경우에는 미니덤프 파일이 잘 남습니다. 하지만 가끔 미니덤프가 안남는 경우가 있습니다.

  • 미니덤프 파일을 만들다가 에러가 난 경우
    -> 가끔 있는 경우지만 정말 가끔 덤프파일을 만드는 동안 에러가 나는 경우가 존재합니다. 이 경우 0바이트짜리 dmp파일을 만나게 되지요..
  • 안티 해킹 솔루션을 사용하는 경우
    -> 안티 해킹 솔루션의 경우 여러가지를 해주는데 그중 제 경험상으로는 프로세스목록에서 게임 프로세스를 감추거나 프로그램이 로드 되고 난 이후에 몇가지 정보를 날리거나 하는 경우에 미니덤프가 덤프파일을 생성하지 못합니다..
  • 그리고 또 다른 경우는.. 생각나지 않네요

이렇게 미니덤프를 붙였는데도 불구하고 덤프파일이 안남는 경우!! 디버깅을 포기할껀가요?!

일단 먼저 에러가 난 상황을 있는 그대로 파일로 저장해야 합니다. 
저는 이것을 에러 리포트 파일이라고 부릅니다.
그리고 덤프파일과 에러 리포트 파일을 모두 남기죠..

제가 지금부터 쓰는 글은 어셈블리어를 공부할 필요도 냄비 받침으로도 부담스러운 디버깅 어쩌고 하는 책을 공부할 필요도 없습니다. 단지 짐승같은 센스와 명탐정 코난의 빙의만 하시고 그냥 따라오시면 됩니다.

보통 미니덤프 어떻게 붙이죠??
인터넷에 "미니덤프" 검색하면 나오는 코드를 그대로 복사해서 WinMain 밑에 넣으실겁니다.
그 과정에 대해 자세히 알 필요는 없습니다.

static LONG WINAPI _UnhandledExceptionFilter( PEXCEPTION_POINTERS pExceptionInfo )
{
    // 여기에 미니덤프를 연결할테다!
    return EXCEPTION_CONTINUE_SEARCH;
}

이런 함수를 하나 만들고

int WINAPI wWinMain( HINSTANCE instance, HINSTANCE, LPWSTR commandLine, int commandShow )
{
    ::SetUnhandledExceptionFilter( _UnhandledExceptionFilter );

    ...
}

이렇게 넣으실겁니다. 여기서!! PEXCEPTION_POINTERS 이녀석이 중요합니다!
PEXCEPTION_POINTERS 이녀석이 현재 에러가 난 정보를 가지고 있기 때문이죠.
이녀석을 통해 에러가 난 상황을 텍스트로 남길 수 있습니다.

먼저 에러가 발생한 이유를 남겨보도록 하죠. 무엇 때문에 에러가 난 것인지는 알아야 할 것 아닙니까?!
PEXCEPTION_POINTERS의 멤버에는 PEXCEPTION_RECORD 라는 녀석이 존재합니다.
먼저 PEXCEPTION_RECORD가 어떤 멤버들을 가지고 있는지 살펴봅시다

typedef struct _EXCEPTION_RECORD
{
    DWORD ExceptionCode;
    DWORD ExceptionFlags;
    struct _EXCEPTION_RECORD *ExceptionRecord;
    PVOID ExceptionAddress;
    DWORD NumberParameters;
    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;

이런 데이터들을 가지고 있는 구조체인데요. 
이걸 하나하나 설명하려다가... 구글링을 해보니 굉장히 좋은 소스가 있어서!!!
걍 링크를 걸고 중요한것들만 설명하기로 했습니다!!!


사용방법은 간단합니다. _UnhandledExceptionFilter 함수 안에 

WheatyExceptionReport::WheatyUnhandledExceptionFilter( pExceptionInfo );

이것만 넣어주면 됩니다.


오늘은 이만 저장해놓고 나중에..


댓글을 달아 주세요

Posted by 비회원

std::numeric_limitsmin(), max()는 함수로 만들어져있습니다.


namespace std
{
    inline int numeric_limits<int>::min() throw()
    {
        return INT_MIN;
    }
}


그 이유는 여러가지가 있겠지만 어쨌든!! 함수로 만들어져있기에!!

클래스 내부 초기화에서 사용할 수 없습니다!!

그러니까 다시 말해서 다음과 같은 코드를 허용하지 않는다는 것입니다.


class AAA
{
    static const int xxx = std::numeric_limits<int>::max();
};


가끔 이런 코드가 필요한데 이렇게 코드를 만들고 컴파일을 해보면

error C2057: 상수 식이 필요합니다.

를 만나게 되지요..


그래서 저는 이런걸 만들어서 사용하고 있습니다.


namespace type_traits
{
    template<typename T>
    struct number_limits
    {
    };

    template<>
    struct number_limits<char>
    {
        static const char min = CHAR_MIN;
        static const char max = CHAR_MAX;
    };

    template<>
    struct number_limits<unsigned char>
    {
        static const unsigned char min = 0;
        static const unsigned char max = UCHAR_MAX;
    };

    template<>
    struct number_limits<short>
    {
        static const short min = SHRT_MIN;
        static const short max = SHRT_MAX;
    };

    ... 생략

}


TAG 끼로

댓글을 달아 주세요

  1. summerlight 2013.04.06 21:07  댓글주소  수정/삭제  댓글쓰기

    참고 : 관련 함수들은 C++11에서는 constexpr 함수로 선언되어서 상수 초기화에도 사용 가능해졌습니다. 이제 MS만 지원하면 됩니다...

    • 알 수 없는 사용자 2013.04.06 21:47  댓글주소  수정/삭제

      오오!! 민철님이다!! MS는 어서 지원하라!! 그리고 템플릿 가변인자도 어서 제대로 지원하라!!! 그전에 우리팀 비줠스튜디오 2012로 업그레이드 언제해주지..

  2. Favicon of http://bluekms21.blog.me 크로스 2013.04.07 00:13  댓글주소  수정/삭제  댓글쓰기

    아아.. 이런글을 보면 C#의 편리함을 더욱 느낄 수 있네요..
    모든 타입에 .MaxValue만 치면 알아서 척척... ㅠㅠ;;

    ...이러다 영영 C++못하게되면 안되는데;

  3. 123 2014.04.23 19:47  댓글주소  수정/삭제  댓글쓰기

    굳이 클래스를 새로 만드시지 않으셔도 필요할 때마다
    std::numeric_limits<int>().max() 라고 적으시면 됩니다. 뭐 취향차이겠지만요

Posted by 비회원

게임에서 ID 참 많이 쓰입니다. 중요한 ID도 있고 그렇지 않은 ID도 있죠..

다른 분들은 ID Type이 필요할 때 어떤식으로 쓰시나요??

저는 한때 이렇게 썼었습니다.


typedef unsigned long MyIDType;
MyIDType xxxID;


그런데 이렇게 쓰다보면 항상 필요하게 되는 것이 있습니다.

바로 할당되지 않은 ID죠


static const MyIDType MyIDType_InvalidID = type_traits::number_limits<MyIDType>::max;


이런식으로 만들어서 쓰다보니 불편함을 많이 느꼈습니다.


그래서 이런걸 생각해봤습니다.


namespace MyID
{
    typedef unsigned long Type;
    static const Type InvalidID = type_traits::number_limits<Type>::max;
}


그런데 또 생각해보니 변수를 생성하면 자동으로 InvalidID가 할당되면 좋겠다 싶더군요..

그래서 이런걸 만들어봤습니다.


template<typename T>
class TypeIDT
{
public:
    static const T InvalidID = type_traits::number_limits<T>::max;

public:
    TypeIDT()
        : m_value( InvalidID )
    {
    }

    TypeIDT( T value )
        : m_value( value )
    {
    }

    TypeIDT& operator = ( T value )
    {
        m_value = value;
        return *this;
    }

    operator T () const
    {
        return m_value;
    }

    bool operator < ( const TypeIDT<T>& other ) const
    {
        return m_value < other.m_value;
    }

    bool operator != ( const TypeIDT<T>& other ) const
    {
        return m_value != other.m_value;
    }

    bool operator == ( const TypeIDT<T>& other ) const
    {
        return m_value == other.m_value;
    }

private:
    T m_value;
};

namespace boost
{
    template<typename T>
    size_t hash_value( const TypeIDT<T>& value )
    {
        return static_cast<size_t>( value );
    }
}


ps. 글을 너무 오랜만에 쓴 관계로.. (실제로 글쓰기 버튼 찾는데 한참 걸림...) 글쓰는 법을 까먹어서..
     코드도 전부 직접 타이핑하고 색도 전부 하나하나 직접 바꿔준거라.. 어색하거나 틀린 부분이 있을 수 있습니다.

TAG 끼로

댓글을 달아 주세요