블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2801)
Unity3D (857)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (234)
협업 (61)
3DS Max (3)
Game (12)
Utility (140)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (16)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

2003 프로젝트를 2008에서 컴파일 할때 발생..


Wp64 옵션을 주지 말라는 것

프로젝트 -> 속성 -> C/C++ -> 일반 -> 64비트 이식성 문제점 검색 : 아니요



출처 : http://blog.naver.com/ghostcbr954/110086888865

2차 출처 : http://boyfox009.egloos.com/2579554

반응형
Posted by blueasa
, |
Visual Studio 2008에서 C++ 프로그램을 컴파일 하면은 기본적으로 두가지 모드가 있습니다.

Release /Debug 두 버전의 차이점은 다른 소소한 성능 향상을 위한 컴파일 옵션도 있지만

가장 중요한건 디버깅이 가능하느냐 가능하지 않냐의 차이점 이라고 생각입니다.

그런데 기존에 구축되어 있는 프로그램을 유지 보수 하다보면은 디버깅 할일이 발생합니다.

기존의 선임이 Release / Debug  별로 프로젝트를 잘 관리했으면 좋겠지만

세상 사는 일이 다 내맘데로 안되듯이 너무 오랜기간 유지 보수를 하다보니 Debug 정보가 유실되는 경우가 있습니다.

프로젝트가 하나의 exe이면 다시 Debug 컴파일 하면되지만 exe와 dll이 약 40~50개 연결된 프로그램이라면

헉 소리 납니다.

이럴때 기본적으로 되어 있는 Release에서 디버깅 정보를 삽입해서 컴파일 할 수 있습니다.

프로젝트 속성 (ALT + F7) 으로 들어가서 아래 그림과 같이 3개의 설명을 그림에 맞게 해주시면 Release 에서도 

디버깅 가능합니다.

* Property Page -> Configuration Properties -> C++ -> General -> Debug Information Format

* Property Page -> Configuration Properties -> C++ -> Optimization -> Optimization 

* Property Page -> Configuration Properties -> Linker -> Debugging -> Generate Debug Info

반응형
Posted by blueasa
, |

짜증나는 워닝과 에러 중에헤더파일 순서에 따라 발생하는 워닝/에러가 있습니다특히 링크타임에 나는 에러는 네이밍 모양새가 재밌게 생겨먹지 않은 스타일로 생기는 데다가 링커가 별로 힌트를 주지 않아서 짜증이 나기도 합니다예를 들면 아래와 같은 겁니다.

 

1>Generating Code...

1>Compiling resources...

1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1

1>Copyright (C) Microsoft Corporation.  All rights reserved.

1>Compiling manifest to resources...

1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1

1>Copyright (C) Microsoft Corporation.  All rights reserved.

1>Linking...

1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)

1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)

 

위 예는 MFC프로젝트에서 모든 파일에서 MFC 헤더를 다른 헤더 보다 먼저 선언해야 하는데(대부분 stdafx.h를 가장 상위에 선언합니다.),  MFC 프로젝트에서 사용하던 파일을 Import 하고 컴파일 하는 순간 발생했습니다.

 

이런 에러의 경우 대처법은 의외로 간단 합니다일단 똑똑고 기억력 좋으신 분들은 자기가 했던 행위들의 콜스택을 하나하나 거슬러 올라가시면서 대처 하는법이 있고이게 가장 비용대비 시간단축 효가가 가장 좋습니다.

 

순간 욱해서 콜스택 거슬러 올라가기 힘드신 (저 같은;;)분들은 아래처럼 대처 하시면 됩니다먼저 링커 옵션에 아래 옵션을 추가 합니다.

 

/verbose:lib

 

 

 

그리고 다시 빌드 하면 링킹타임에 library를 스캔하는 리스트가 아래와 같이 output창에 나오게 됩니다.

 

1>Generating Code...

1>Compiling resources...

1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1

1>Copyright (C) Microsoft Corporation.  All rights reserved.

1>Compiling manifest to resources...

1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1

1>Copyright (C) Microsoft Corporation.  All rights reserved.

1>Linking...

1>Searching libraries

1>    Searching C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\DelayImp.lib:

1>    Searching C:\Program Files\Microsoft SDKs\Windows\v6.0A\\lib\uuid.lib:

1>    Searching C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\LIBCMTD.lib:

1>    Searching C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\OLDNAMES.lib:

1>    Searching C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\lib\uafxcwd.lib:

1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)

1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)

1>    Searching C:\Program Files\Microsoft SDKs\Windows\v6.0A\\lib\kernel32.lib:

1>    Searching C:\Program Files\Microsoft SDKs\Windows\v6.0A\\lib\user32.lib:

1>    Searching C:\Program Files\Microsoft SDKs\Windows\v6.0A\\lib\gdi32.lib:

1>    Searching C:\Program Files\Microsoft SDKs\Windows\v6.0A\\lib\uuid.lib:

 

윗 예에서 uafxcwd.lib를 링크 할 때링크에러가 났고에러를 유발한 유력한 용의자는 uuid.lib입니다왜냐면계속 다른 애들은 디폴트 경로에서 링크되는데 uuid.lib만 sdk 에서 링크 되었고, MFC에서 new를 재정의 하기 때문에이전에 new가 정의되어 있는 파일이 링크되면 안됩니다여기서 “stdafx.h”파일을 추가 하는 것을 잊었구나 하는 생각이 듭니다.

 

/verbose 옵션을 써보지 않으신 분들은 한번 넣고 컴파일을 해보시면 쓰잘떼기 없는 정보까지 주르륵 나와서 놀라실 껍니다. 여러가지 링킹 타임에 하는 작업 정보를 자세히 알려주는 것을 알 수 있습니다. 윗예의 :lib처럼 뒷부분에 세부 옵션을 붙여 보기 좋게 정보를 추출하는 작업이 익숙해 지면 일반적인 컴파일시 정보를 잘 제공해주지 않는 링킹 타임시 발생하는 에러에 정보를 얻어 디버깅 작업 시간을 단축 시킬 수 있습니다.


출처 : http://blog.naver.com/drvoss/20064150564

반응형
Posted by blueasa
, |

/VERBOSE:LIB

 

이 옵션을 걸어주면 어떤 lib에서 라이브러리 충돌이 생기는지 알 수 있다

 

라이브러리 충돌은 라이브러리를 만들때 crt lib를 포함해서 (mtd,mt) 컴파일 하였다면

라이브러리를 사용하는 응용프로그램 또한 crt lib를 포함해서 컴파일 해야한다.

 

반대로 lib를 만들때 (mdd,md) 공유 라이브러리를 이용해 컴파일 했다면 응용프로그램에서도

그렇게 해야한다.



출처 : http://blog.naver.com/herok3/100047421303

반응형
Posted by blueasa
, |

1. API에서 참조하는 library의 순서를 확일 할수 있는 명령

 

.net -> 속성 -> linker -> 명령줄 -> 추가 옵션

/verbose:lib


반응형
Posted by blueasa
, |

예외 처리 ~~ tip

Tip & Tech / 2011. 2. 8. 17:11

예외 처리라 하면.. try{} catch(...){} 등을 사용하여 코딩을 하는게

보통이다.

 

하지만.. release 컴파일시 error로 프로그램이 죽어버리게 되면 catch등을 통하지 않고

종료되어. 버그 리포팅을 하기가 힘든데

 

이럴때를 지원해주기 위한 window API 함수를 알아본다.

 

step1 : 프로그램이 죽어버를 경우 무조건 호출될 callback함수를 하나 만든다.

LONG WINAPI  ExceptionCallStack (struct _EXCEPTION_POINTERS *exceptionInfo);

 

step 2 : 예외 처리 핸들러 생성

LPTOP_LEVEL_EXCEPTION_FILTER PrevExceptionFilter = NULL;

 

 

int APIENTRY _tWinMain(..... )

{

 

 // 콜스택 기록용 예외 콜백 함수 등록
 PrevExceptionFilter = SetUnhandledExceptionFilter(ExceptionCallStack);

Run();

 

// 콜스택 기록용 예외 콜백 함수 등록 해제
 SetUnhandledExceptionFilter(PrevExceptionFilter);

 

}

 

=> Thingking

........... ExceptionCallStack 함수에 miniDump나 콜스택 과련 debug코드를 내포하여 release를 배포하면

차후 생각지 못한 버그가 발생했을경우 리포팅이 가능해진다.

[출처] 예외 처리 ~~ tip|작성자 모냐

반응형
Posted by blueasa
, |

define DEBUG_OUTPUT
//------------------------------------------------------------------------
// 2010/01/22 [19:56:32]
// jedikim72
// - 디버깅출력함수
//------------------------------------------------------------------------
#ifdef DEBUG_OUTPUT
 #define debugLog(...) { char acTemp[2048]; \
                                      char acTemp2[2048]; \
                                      NiSprintf(acTemp, 2048, __VA_ARGS__); \
                                      NiSprintf(acTemp2, 2048, "[L%d]:%s - %s", __LINE__, __FUNCTION__, acTemp ); \
                                      OutputDebugString( acTemp2 ); \
                                    }
#else
 #define debugLog(...) ((void)0)
#endif
//------------------------------------------------------------------------

 

빌딩모드와 상관없이 디버깅 메세지를 출력하는 메써드가 필요해서 부랴부랴 만든 매크로.

(기존 매크로는 사용하기 불편해서... - -a)

 

매크로 가변인자를 사용하여 가변인수를 받아 출력할 수 있다.

사용예) debugLog("%.2f, %.2f, %.2f\n", pos.x, pos.y, pos.z);

또한 VS IDE 출력창 뿐만 아니라, 실행파일만 독립적으로 실행해도 DebugView 유틸을 통해 디버깅 출력 메세지를 볼 수 있다는 장점이 있다.

 

 

이제까진 TraceWindow를 써서 출력했는데, 프로젝트에 매번 관련 모듈 삽입하는 것도 귀찮고 해서 아예 매크로로 빼버려 간단한 구문 삽입만으로 간편하게 작업을 완료할 수 있게 했다.

 

 

 

DebugView와 함께 구동시킨 작업중인 데모 스크린샷

그나저나,

DebugView 유틸은 첨부파일로~!



출처  : http://jedikim72.blog.me/10079110907

반응형
Posted by blueasa
, |
반응형
Posted by blueasa
, |

C++ 을 배운지 꽤 오래 되었지만, 아직도 코드 리뷰를 통해 다른 개발자들의 코드를 볼 때면 한숨이 나오는 경우가 많습니다.

이런 경우가 반복되다 보니, 예전에 몇 가지 코딩 규칙 비슷하게 만들어놓은 자료가 있어 포스팅해 봅니다.  자료가 만들다 말아 내용이 중구난방이네요..  앞으로도 계속 내용 보강해 나가겠습니다.

 

    포인트 핸들 및 윈도우 핸들 체크

-       함수로 전달된 포인터 인자나, new 로 생성한 포인터 등 모든 포인터는 사용하기 직전 포인터 검사를 수행

-       가급적 STL 컨테이너를 사용해서 아예 포인터를 사용하지 않는 것이 정신건강에 이롭다. (STL 자체적으로 메모리 생성 및 소멸)

-       메모리 LEAK 을 막기 위해 SMART POINT 와 같은 Wrapper 클래스를 만든다.

-       (윈도우 프로그램의 경우)윈도우 API 호출 직전 항상 윈도우 핸들이 정상인지 IsWindow 와 같은 함수로 검사한다.

 

    DRY(Don't Repeat Your Code)원칙

-       같은 코드를 여기 저기 중복해서 사용하지 말아야 한다. (☞ 실용주의 프로그래머 참고). 중복해서 사용할 경우 코드 량이 늘어날 뿐만 아니라 유지보수 cost 가 같이 늘어 나고, 추후 추가/개선/변경 등의 요구사항으로 인한 모듈 수정 시 여러 소스를 함께 수정해야 한다.

-       동일한 코드를 공용 루틴(함수)으로 개발 – 2~3줄 짜리 복잡한 if 문도 bool 를 리턴 하는 함수로 개발(Refactoring 참고)

 

    클래스간 종속성 최소화

-       대규모 프로젝트에서는 공통모듈이 변경되어도 이를 사용하는 모듈이 문제가 없도록 반드시 공통모듈은 인터페이스 기반(데이터가 없는, virtual 가상함수로만 구성된)으로 구현한다. (The C++ Programming Language 참고)

-       A 클래스 → B 클래스 → C 클래스를 사용할 경우 각 클래스는 자기가 직접 다루는 클래스(A B, B C) 만 알아야 한다. A 클래스는 C 클래스를 직/간접적으로 include 해서는 안되며 C 클래스의 변경으로 인해 A 클래스가 컴파일 되어서는 안 된다. A 클래스가 C 를 직접 접근할 경우가 있다면 B 클래스에 위임함수를 만들어 해결한다. (☞ 실용주의 프로그래머 참고)

-       B 클래스가 A 클래스로 어떤 데이터를 전달할 경우가 있다면(주로 이벤트 발생시 값을 전달하기 위해) A 클래스의 최소 인터페이스만을 B 클래스에 전달하여(COM 의 이벤트 소스 방식) 종속성을 최소화 한다. (Developer’s Workshop To COM and  ATL 3.0 참고)

 

    함수 인자 전달

-       함수의 인자는 최대 7개를 넘지 않아야 한다(Code Complete 2 참고)

-       클래스 인스턴스를 함수 인자로 넘겨서는 안 된다(특히 함수 인자로 CString 을 넘기는 경우가 많음. CString → const CString& CString*, const char* 등으로 수정한다. )

 

    오류조건을 먼저 검사하여 오류 체크로 인해 코드 가독성이 떨어지지 않도록 하자.

-       특정 오류조건이 발생하면 더 이상 함수 수행에 의미 없을 경우, 이러한 오류 조건들은 함수초입단계부터 먼저 확인해서 바로 리턴 한다

-       위와 같이 오류조건이 먼저 확인되면 프로그램 코드에서 if depth 가 줄어 들고 코드 읽기가 수월해 지는 장점이 있다.

Before

After

void CClass::OnTest()

{

 ...

 ...

 if (m_pWndMain)

 { 

  DoSomething1();

 }

 ...

 if (m_pWndMain)

 { 

  DoSomething2();

 }

 

}

void CClass::OnTest()

{

 if (m_pWndMain == NULL)

  return;

 ...

 ...

 DoSomething1();

 ...

 DoSomething2();

 

}

 

    긴 함수 쪼개기 (Refactoring 참고)

-       긴 함수는 작은 여러 개의 함수로 쪼갠다(Refactoring 책에 의하면 2-3줄 짜리 함수로까지 쪼개어서 코드 가독성을 높이도록 하고 있음)

-       작은 함수로 쪼개다 보면, 작은 함수를 재활용하게 될 수 있고

-       긴 함수보다 코드 읽기가 수월해 지며

-       결국 유지보수가 쉬워진다

 

    enum 값 선언 시 _START, _END 를 활용하자( CODE COMPLETE2 참고)

-       enum 으로 선언된 값들을 변수나 for loop 를 이용하여 반복 계산할 경우가 종종 있는데 이 경우 enum 시작과, 끝을 나타내는 값을 enum 선언에 포함하면 유용하게 사용할 수 있다.

-       추후 enum 에 값을 추가해야 할 경우 _END 값을 사용한 배열은 코드 변경없이 크기가 늘어남

-       For 루프 등에 _START, _END 을 사용할 수 있어 유지 보수에 유리

Before

After

enum WEEK_NAME

{

           SUNDAY                     = 0,

           MONDAY                    = 1,

           TUESDAY                    = 2,

           WEDNESDAY     = 3,

           THURSDAY       = 4,

           FRIDAY            = 5,

           SATERDAY        = 6,

};

 

int nWeeks[SATERDAY + 1];

}

enum WEEK_NAME

{

           WEEK_STAR       = 0,

           SUNDAY                     = 0,

           MONDAY                    = 1,

           TUESDAY                    = 2,

           WEDNESDAY     = 3,

           THURSDAY       = 4,

           FRIDAY            = 5,

           SATERDAY        = 6,

           WEEK_END        = 6,

};

 

int nWeeks[WEEK_END + 1];

 

 

    복잡한 제어문을 가진 루틴을 피하자  

-       If 문은 2 depth 이상 들어 갈 경우 refactoring 하라 (CODE COMPLETE2)

     대부분 코드를 제대로 이해하지 못해 복잡한 코드를 작성하고 있다.

     개발자 90% 2 depth 이상 들어가는 if 문장을 이해하지 못한다

-       IF~ELSE IF ~ELSE IF ~ …. ELSE 가 길게 이어질 경우 SWITCH 문으로 바꾼다

-       IF 문이 길게 늘어 질 경우 함수로 분리한다

-       C++ factory 개념으로 상속을 이용한 클래스를 만드는 방법도 활용


반응형
Posted by blueasa
, |

Visual C++ (.NET 기준)에서 디버깅 시 유용하게 사용할 수 있는 컴파일옵션들을 정리해 보았습니다.  하나하나 다 외우질 못해 프린트해서 그때그때 사용하고 있습니다. ^^

도움이 될 지 모르겠네요.

 

/EP /P C/C++ Preprocessor Generate Preprocessed File
(파일전처리)
전처리 코드에 대한 내용을 소스파일.i 파일로 볼 수 있다. 
/C C/C++ Preprocessor Keep Comments
(주석유지)
위를 설정하고 이것도 설정하면 선택하면 전처리코드 위의 주석도 유지하면서 보여 줄 것이다.
/X C/C++ Preprocessor Ignore Standard Include Path
(표준 포함경로무시)
표준 인클루드 경로 무시
/Zp C/C++ Code Generation Struct Member Alignment
(구조체 맴버 맞춤)
#pragma pack 지시자를 사용하는 것이 더 좋을 것 같다.
/Wp64 C/C++ General Detect 64-bit Portability Issues
(64비트 이식성 문제 검색)
나중 64비트 호완성을 돕기위해 설정을 해 두는 것이 좋다.
/RTC C/C++ Code Generation Smaller Type Check
(작은 형식 검사)
/RTCc : 값을 작은 데이터 형식으로 변환할 때 데이터손실이 없는 지 검사한다.
Basic Runtime Checks
(기본 런타임 검사)
/RTCu : 초기화되지 않은 변수참조를 추적한다.
/RTCs : 모든 지역변수들을 0xCC로 초기화 하여 훌륭한 스택 프레임 검사가 로컬변수 언더런과 오버런을 감지하고 스택 충돌에 대해서 스택 포인터를 검증하도록 한다.
/RTCsu : 위의 두개 모두 포함
/GS C/C++ Code Generation Buffer Security Check
(버퍼 보안 검사)
바이러스 작성자들의 가장 일반적인 공격인 리턴주소를 악성코드로 리다이렉트 할 수 있도록 하는 버퍼오버런공격을 막아주는 것이다.
/O(num) C/C++ Optimization Optimization
(최적화)
/O1(크기최소화), /O2(속도최대화:디폴트)
마이크로소프트 제품은 모두 /O1으로 컴파일..이것으로 컴파일 할 때 같이 SWS(Smooth Working Set)유틸리티를 사용해서 공통적으로 사용하는 함수들을 앞으로 배치되도록 해야 한다.(속도도 높이기 위해)
/GL Main General Whole Program Optimization
(전체프로그램최적화)
설정하면 링커스위치에 /LTCG(밑에 참조 바람)를 설정
/showincludes C/C++ Advanced Show Includes
(포함 파일 나열)
컴파일 할 때 포함되는 include 파일들이 어떤 위치의 것인지를 Output 화면으로 모두 보여준다.
/MAP Linker Debugging Generate Map File
(맵파일 생성)
맵파일을 생성하는 스위치로 유용한 정보를 얻기위해서는 모두 사용해야 한다.
/MAP:LINES Linker Debugging Map Lines
(맵파일에 줄 번호 정보 포함
/MAP:EXPORTS Linker Debugging Map Exports
(맴파일에 익스포트 함수정보 포함)
/NODEFAULTLIB Linker Input Ignore All Default Libraries
(라이브러리 무시)
많은 시스템 헤더파일들이 어떤 파일이 링크되는지 지정하기 위해 #pragma comment (lib#,립이름)을 포함하는데 이를 모두 무시하도록 지시한다.
/OPT:NOWIN98 Linker Optimization Optimize for Windows98
(Windows98에 맞게 최적화)
98,ME를 지원하지 않는 다면 설정하는 것이 좋다. 응용프로그램의 크기를 줄일 수 있다.
/ORDER Linker Optimization Function Order
(함수에 순서 지정)
SWS(Smooth Working Set) 을 실행한 후 함수의 순서를 포함하고 있는 파일을 지정할 수 있다.
/VERBOSE Linker General Show Process
(진행 메시지 표시)
링크되는 라이브러리의 모든 진행 메세지를 표시
/VERBOSE:LIB Linker General Show Process
(진행 메시지 표시)
검색된 라이브러리만 나타내는 진행 메세지를 표시
/LTCG Main General Whole Program Optimization
(전체프로그램최적화)
/GL스위치와 짝을 이룬다. 링크시간코드를 생성.
/RELEASE Linker Advanced Set Checksum
(체크섬 설정)
별로 사용되지 않지만 WinDBG를 사용할 때 책섬을 조사할 때 필요하기 때문에 미리 넣어 두는 게 좋다.
/PDBSTRIPPED Linker Debugging Strip Private Symbols
(전용 기호 제거된 심볼)
스택을 탐색하고 해독하기 위해서 필요한 특별한 Frame Pointer Omission(FPO) 데이터를 PDB파일에 포함시키기 위해 설정한다. 각종 변수나 소스 줄정보는 빼고 필요한 FPO데이터와 공용함수들만 남겨놓는다(stripped PDB파일). 이것과 함께 일반 PDB 파일을 같이 생성할 수 있다. 나중에 Dr.Watson 등에서 PDB파일을 로드할 수 있기 위해서는 파일명을 어플리케이션 명과 같게 해줄 필요가 있다.

반응형
Posted by blueasa
, |