MFC를 사용하여 프로그램을 개발하여 배포한 후 현장에서 문제가 발생하는 경우가 있다이때개발자는 프로그램을 디버깅을 해볼 수 있는 상황이 못된다이럴 때를 대비한 한가지 팁을 소개드립니다.
  xCrash Report
를 사용하면 개발프로그램이 Runtime중 사망시 사망직전 호출 스택과 시스템의 상태정보를 Log로 기록하여 분석할 수 있게 해줍니다.참 좋군요~

 

사용법은 아래와 같습니다.

1)       Lib를 선
#pragma comment(lib, "dXCrashRpt.lib")              

2)       App InitInstance에서 소스추가

BOOL CMyApp::InitInstance()

        {

                  // gdiplsu start

                  Gdiplus::GdiplusStartupInput gdiplusStartupInput;

                  if(Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) != Gdiplus::Ok)

                  {

                                   AfxMessageBox(_T("Error : Failed to initialize GDI+ library!"));

                                   return FALSE;

                  }

 

                  // 응용 프로그램 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을

                  // 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControlsEx() 필요합니다.

                  // InitCommonControlsEx() 사용하지 않으면 창을 만들  없습니다.

                  INITCOMMONCONTROLSEX InitCtrls;

                  InitCtrls.dwSize = sizeof(InitCtrls);

                  // 응용 프로그램에서 사용할 모든 공용 컨트롤 클래스를 포함하도록

                  //  항목을 설정하십시오.

                  InitCtrls.dwICC = ICC_WIN95_CLASSES;

                  InitCommonControlsEx(&InitCtrls);

 

                  CWinApp::InitInstance();

 

                  if (!AfxSocketInit())

                  {

                                   AfxMessageBox(IDP_SOCKETS_INIT_FAILED);

                                   return FALSE;

                  }

 

                  // OLE 라이브러리를 초기화합니다.

                  if (!AfxOleInit())

                  {

                                   AfxMessageBox(IDP_OLE_INIT_FAILED);

                                   return FALSE;

                  }

 

                  AfxEnableControlContainer();

 

                  // Use Crash Report

                  ::InstallXCrash();  // ß 요기에 사용을 선언합니다.

 

                  EnableTaskbarInteraction(FALSE);

 

                  // RichEdit 컨트롤을 사용하려면  AfxInitRichEdit2() 있어야 합니다.     

                  // AfxInitRichEdit2();

 

                  // 표준 초기화

                  // 이들 기능을 사용하지 않고 최종 실행 파일의 크기를 줄이려면

                  // 아래에서 필요 없는 특정 초기화

                  // 루틴을 제거해야 합니다.

                  // 해당 설정이 저장된 레지스트리 키를 변경하십시오.

                  // TODO:  문자열을 회사 또는 조직의 이름과 같은

                  // 적절한 내용으로 수정해야 합니다.

                  SetRegistryKey(_T("로컬 응용 프로그램 마법사에서 생성된 응용 프로그램"));

                  LoadStdProfileSettings(0);  // MRU 포함하여 표준 INI 파일 옵션을 로드합니다.

 

 

                  // 응용 프로그램의 문서 템플릿을 등록합니다문서 템플릿은

                  //  문서프레임    사이의 연결 역할을 합니다.

                  CSingleDocTemplate* pDocTemplate;

                  pDocTemplate = new CSingleDocTemplate(

                                   IDR_MAINFRAME,

                                   RUNTIME_CLASS(CMyDoc),

                                   RUNTIME_CLASS(CMainFrame),       //  SDI 프레임 창입니다.

                                   RUNTIME_CLASS(CMyView));

                  if (!pDocTemplate)

                                   return FALSE;

                  AddDocTemplate(pDocTemplate);

 

 

                  // 표준  명령, DDE, 파일 열기에 대한 명령줄을 구문 분석합니다.

                  CCommandLineInfo cmdInfo;

                  ParseCommandLine(cmdInfo);

 

 

 

                  // 명령줄에 지정된 명령을 디스패치합니다.

                  // 응용 프로그램이 /RegServer, /Register, /Unregserver 또는 /Unregister 시작된 경우 FALSE 반환합니다.

                  if (!ProcessShellCommand(cmdInfo))

                                   return FALSE;

 

                  //  하나만 초기화되었으므로 이를 표시하고 업데이트합니다.

                  m_pMainWnd->ShowWindow(SW_SHOW);

                  m_pMainWnd->UpdateWindow();

                  // 접미사가 있을 경우에만 DragAcceptFiles 호출합니다.

                  //  SDI 응용 프로그램에서는 ProcessShellCommand 후에 이러한 호출이 발생해야 합니다.

 

                  // Init all manager

                  CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd();

                  CMyDoc* pDoc = (CMyDoc*)pMainFrame->GetActiveDocument();

                  CMyView* pView = (CMyView*)pMainFrame->GetActiveView();

                  return TRUE;

        }


3)     실행파일 폴더에 dll복사
dXCrashRpt.dll
를 프로그램 실행 폴더에 복사


4)     ExceptionHandler.h 헤더를 App 헤더에 선언(솔직히 이건 필요한지는 모르겠음)
#include "ExceptionHandler.h"


5)     XCrashRpt.exe 실행프로그램 위치에 복사한다. 

 

 

 

이렇게 작업을 완료하였다면 프로그램 배포  문제가 발생했을 경우에 해당 프로그램이 있는 폴더에 ERRORLOG.txt가 생성되게 됩니다. 그럼 이 파일을 분석하시면 되겠죠~~
ERRORLOG
 내부에는 프로그램에 문제가 발생한 시점의 Callstack정보가 기록되어있습니다

아래처럼요~~



XCrashRpt.zip



출처 : 반사마의 낙서장

'Programing > Visual C++/MFC' 카테고리의 다른 글

자료형의 크기 및 범위  (0) 2016.03.23
DebugView 사용법  (0) 2016.03.11
OnCtlColor(Dialog Control 에 색깔 입히기)  (0) 2014.05.08

퍼온글 : Beom's Blog [C++ 정리] 자료형의 크기 및 범위

[C++ 정리] 자료형의 크기 및 범위


32비트를 기준으로 한 자료형의 크기 및 범위이다. 다른 OS(16비트, 64비트)나 컴파일러에서 자료형의 크기가 조금씩 다르다는점 기억해 두자.

구분자료형크기범위
기본형void
문자형(signed) char1 byte-128 ~ 127
unsigned char1 byte0 ~ 255
wchar_t2 byte0 ~ 65,535
정수형bool1 byte0 ~ 1
(signed) short (int)2 byte-32,768 ~ 32,767
unsigned short (int)4 byte0 ~ 65,535
(signed) int4 byte-2,147,483,648 ~ 2,147,483,647
unsigned int4 byte0 ~ 4,294,967,295
(signed) long (int)4 byte-2,147,483,648 ~ 2,147,483,647
unsigned long (int)4 byte0 ~ 4,294,967,295
__int81 byte-128 ~ 127
__int162 byte-32,768 ~ 32,767
__int324 byte-2,147,483,648 ~ 2,147,483,647
__int648 byte-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
실수형float4 byte3.4E-38(-3.4*10^38) ~ 3.4E+38(3.4*10^38) (7digits)
(long) double8 byte1.79E-308(-1.79*10^308) ~ 1.79E+308(1.79*10^308) (15digits)

 

OS별(16bit/32bit/64bit) 크기 사용의 요점은 다음과 같다.
  * int는 시스템의 기본연산 단위를 사용한다. (16bit=>2byte, 32=>4byte, 64=>4byte)
  * 64bit에서 long형을 8byte로 확장하였다. (16bit=>4byte, 32=>4byte, 64=>8byte)

 

다음코드로 자료형의 크기를 확인할 수 있다.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
#include "stdafx.h"
#include <iostream>
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    cout << "char \t\t: " << sizeof(char) << " bytes\n";
    cout << "unsigned char \t: " << sizeof(unsigned char) << " bytes\n";
    cout << "wchar_t \t: " << sizeof(wchar_t) << " bytes\n";
    cout << "bool \t\t: " << sizeof(bool) << " bytes\n";
    cout << "short \t\t: " << sizeof(short) << " bytes\n";
    cout << "unsigned short \t: " << sizeof(unsigned short) << " bytes\n";
    cout << "int \t\t: " << sizeof(int) << " bytes\n";
    cout << "unsigned int \t: " << sizeof(unsigned int) << " bytes\n";
    cout << "long  \t\t: " << sizeof(long) << " bytes\n";
    cout << "unsigned long \t: " << sizeof(unsigned long) << " bytes\n";
    cout << "__int8 \t\t: " << sizeof(__int8) << " bytes\n";
    cout << "__int16 \t: " << sizeof(__int16) << " bytes\n";
    cout << "__int32 \t: " << sizeof(__int32) << " bytes\n";
    cout << "__int64 \t: " << sizeof(__int64) << " bytes\n";
    cout << "float \t\t: " << sizeof(float) << " bytes\n";
    cout << "double \t\t: " << sizeof(double) << " bytes\n";
    return 0;
}

data_type

출처 superchangho | superchangho
원문 http://blog.naver.com/superchangho/70048122632
예전에 서버 개발팀에 꼽사리 끼어서 스터디를 할때 OutputDebugString이란 함수에 대해서 들었었던 기억이 있다
그 당시 서버 개발팀 팀장님이 이거 되게 유용한 함수라고 막 얘기를 해줬었던 기억도 있는데
이건 머 써보지도 않았고, 써볼 생각도 안했으니 이게 얼마나 유용한지 안 유용한지도 몰랐었는데

요근래 Win32 프로그래밍을 할일이 있어서 이것저것 해보고 있는데
Win32 프로그램에선 TRACE를 안먹는 다는 사실을 알고는 ;;;

프로그램 실행중에 확인해봐야 하는 값이 있는데, 이건 뭐 TRACE만 집어넣으면
Error 뜨면서 컴파일이 안되니... 노가다로 하나하나 보고 있는데
우연히 생각난 OutputDebugString....
역시 사람은 공부를 해야 된다;;;; ㅋㅋㅋ

그래서 구글링을 해봤더니, 요거 쵸큼 짱인듯 ㅡㅡb
이제부터 사용법
일단은 DebugView라는 프로그램을 다운받는다.
다운은 요기(http://technet.microsoft.com/ko-kr/sysinternals/bb896647(en-us).aspx)서 받으면 된다
검색할 필요없이 첨부된 파일 먼저 다운받으시고, 원하는 곳에 저장해놓은후

비쥬얼 스튜디오로 진입
그림과 같이 Tools -> External Tools 선택


선택하면 아래와 같은 창이 뜬다. Add를 눌러서 다운받은 DebugView가 저장되어 있는 위치 지정해 놓으면
비쥬얼 스튜디오와 DebugView 연결 시키는 단계는 끝..



비쥬얼 스튜디오와 DebugView를 연동 시켰으니, 이제는 코드로 넘어가서 보면,
일단 코드에서 사용할 함수를 만들어 준다. 그리 어려운 코드는 아니라서 스리슬쩍 변수명 개판으로 해서 하나 만들었음 ㅋㅋ



요렇게 만들어 놓은후에, 사용하고자 하는 곳에서 Changho_TRACE를 호출해 준다 
요렇게



이렇게 만든후에 DebugView를 켜놓고 프로그램을 실행시키면 아래와 같은 결과를 볼수 있다.


이 방법을 사용하면, 무거운 Debugger를 띄우지 않고서도 Release모드로 TRACE 기능을 그대로 사용할수 있는 장점이 있다.
바로 그냥 Ctrl + F5를 사용해서 프로그램을 실행시키더라도 이런 디버그 메시지를 모두 볼수 있다
아 그리고, filtering 기능이 지원되기 때문에 자기가 원하는 메시지들에다가 highlighting을 줄수 있다
또한 원격 디버깅 까지 가능하다는 사실~!~~~

주의 사항
DebugView를 사용할때 F5(디버그모드)로 실행시키면 안된다. DebugView로 와야 하는 메시지들을 비쥬얼 스튜디오의 Debugger가 모두 가로채 가버리기 때문에 DebugView로는 아무것도 안오기 때문에, 메시지가 하나도 안나온다. 


출처 : http://minihp.cyworld.com/28001296/211666719

 

 

 

★ Dialog Control 에 색깔 입히는 방법

 

1. VIew - Class Wizard 실행

 

2. Class Name : 해당 Class 선택

 

3. Object IDs :  해당 Class 선택

 

4. Messages : WM_CTLCOLOR 선택

 

5. OnCtlColor 함수가 생성되면 다음과 같이 추가.

 

HBRUSH CFingerAuthenticationDllDlg::

          OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
   HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   CBrush B;

  

    // 색을 입힐 Dialog 의 Ctrl ID 

    if(IDC_SNSSAMPLE_AUTHENTICATION ==  

       ::GetDlgCtrlID(pWnd->m_hWnd))             // 현재 Dialog
    {
        B.CreateStockObject(WHITE_BRUSH);
        return (HBRUSH)B;
    }
 
    return hbr;
}

=========================================================

 

☆ OnCtlColor 함수원형

 

afx_msg HBRUSH OnCtlColor

           ( CDC* pDC, CWnd* pWnd, UINT nCtlColor );

 


 ● CTLCOLOR_BTN   Button control

 ● CTLCOLOR_DLG
   Dialog box

 ● CTLCOLOR_EDIT
   Edit control

 ● CTLCOLOR_LISTBOX
   List-box control

 ● CTLCOLOR_MSGBOX
   Message box

 ● CTLCOLOR_SCROLLBAR
   Scroll-bar control

 ● CTLCOLOR_STATIC
   Static control

 

=========================================================

+ Recent posts