[원문] http://northwind.springnote.com/pages/69967 northwind 님의 노트중에서 발췌

Compiler options for finding Bugs #1

 

 

 

Compiler options for a debug build #1

 

 

 Compiler options for a release build #1

 

디버그 런타임 라이브러리 사용시 특징 #1

 

릴리즈 모드에서 디버깅 하기 #1'

 

 설정을 변경하면 디버깅은 잘되나 배포판을 만들 경우에는 변경된 옵션을 환원하고 빌드하자.

자주 써야 할 경우 빌드 타입을 하나 더 만들어서 사용하는 것도 한가지 방법이다.

 

 

vs 6.0 기준

vs .net 기준

 

Registers And Pseudo-registers #1

 Register값은 “Registers" 윈도우에서 확인이 가능하지만 단순하고 값만을 알수 있다. 이 값들을 ”Address(Watch)" 박스에서도 확인이 가능하며 여러 부가 기능과 같이 쓸수 있다.

 예를 들어 EAX의 값을 확인 해볼려고 하면 Watch 항목에 “@EAX"혹은 ”@eax"와 같이 대소문자를 구분하지 않고 넣으면 이 래지스터의 값을 확인 할 수 있다.

 또한 Pseudo-register"의 값또한 확인 할수 있는데. "@ERR"의 Pseudo-register 값은 매우 유용하게 사용할 수 있는데 이 값이GetLastError의 값을 나타내기 때문이다. 만약 “@ERR,hr"이라고 입력한다면 Win32의 에러코드에 해당하는 택스트를 보여 줄것이다.

 

 

 

 

 

Pseudo-registers that the Watch window supports #1

 

Watch Window Formatting Symbols #1

 Watch 윈도우는 변수의 값을 볼수 있게 해주는데, 값을 십진수나 16진수로서 확인할 수 있다. 16진수는 팝업 메뉴에서 “Hexadecimal Display"를 선택하면 볼수 있다. 이 이외에도 여러 가지 옵션을 주어서 사용할 수 있는데 이들은 Watch Window에 등록되는 변수명 뒤에 ","를 삽입하고 그뒤에 옵션을 주어 사용할 수 있다.

 

 

 

 

 

디버깅에 도움이 되는 메모리 마킹 패턴 #1'

 

 

 

가끔 오류가 발생했을 경우에  만날수 있는 magic number. ( 디버깅 모드에서만 byte pattern 으로 마킹됨. )

 

non-MFC 프로젝트에서 메모리 릭(Memory Leck) 검출

 mfc 프로젝트에서는 DEBUG_NEW 가 기본적으로 제공되므로 메모리 릭을 검출하기가 용의하다. 하지만 일반 프로젝트에서는 추가적인 설정이 필요하다.

 위와 같은 코드를 기초 인클루드 파일에 추가하면 된다. ( 예를 들어 StdAfx.h 와 같은 곳에.. )

그리고 아랫 내용을 cpp 파일의 상단(인클루드 아랫 부분)에 추가하면 된다.

그리고

위와 같이 App 최초 구동시 메모리 릭 검출 디버깅 옵션을 켜준다.

 

그러면 디버그 모드로 실행 했을 경우 App 종료시 output 창에 메모리 릭 발생시 메모리 릭 정보가  해당 소스 파일과 라인등 정보와 함께 출력되는 것을 볼수 있을 것이다.

 

실수 연산 오류 발생시 Exception 발생 시키기 #2

    int stat = _controlfp(0, 0);
   stat &= ~(EM_ZERODIVIDE);
   _controlfp(stat, MCW_EM);

와 같이  EM_ZERODIVIDE 옵션을 추가하였다면 0으로 나눌 경우 해당 코드 부분에서 exception이 발생하므로 발생 부분을 즉시 확인할 수 있는 효과가 있다. 기타 다른 옵션은 MSDN 에서 _controlfp를 찾아서 확인하자.

 

Special Floating-Point Values and Their Representations #3

*, 1.#QNAN 의 경우 1.#INF ( 무한대의 값 ) 으로 연산시에 발생함.

 

 Pure virtual Function Call #4

순수 가상 함수를 파괴자 등에서 호출하여 생기는 오류 검출 방법.

 References
switch ~ case 문안에 변수를 초기화 하려고 하면 초기화가 생략 되었다는 메시지가 발생하게 된다.

switch(nNum)
{
case 1:
int i;
break;
}

이럴때는 case 안에 중괄호를 쳐주면 가능하다..


switch(nNum)
{
case 1:
{
int i;
}
break;

}

// 읽기용데이터작성

CString CPLC_Comm::MakeReadCmd(int nCpu, CString strAddress, int nSize)
{
    CString strCmd;

   // 01BRDI00001,020 CR LF //    01WRDD00001,05 CR LF     strCmd= "HHCMDSAAAAA,LLL";

    switch(strAddress.GetAt(0))
    {
        // Word Read    
        case 'X':
        case 'Y':            
        case 'I':            
        case 'E':            
        case 'L':            
        case 'M':        
        // 여기까지는Bit / Word Read 모두가능

        /*        
        // Bit Read                                                                
        strCmd.Format(_T("%.2dBRD%s,%.3d\r\n"),
                      nCpu,
                      strAddress,
                      nSize);
        */

        // 이하는Word만읽기가능...    
        case 'T':    // TP = Timer Current Value, TS = Timer preset value, TI = Timer current value(Count Up Type)
        case 'C':    // CP = Timer Current Value, CS = Timer preset value, CI = Timer current value(Count Up Type)
        case 'D':
        case 'B':
        case 'W':
        case 'Z':
        case 'R':
        case 'V':
            // Word Read
            strCmd.Format(_T("%.2dWRD%s,%.2d\r\n"),
                          nCpu,
                          strAddress,
                          nSize);        
            break;
    }
    return strCmd;
}

// 쓰기용데이터작성
CString CPLC_Comm::MakeWriteCmd(int nCpu, CString strAddress, CString strData)
{

// 01BRWI00001,020 CR LF //    01WRWD00001,05 CR LF    strCmd= "HHCMDSAAAAA,LLL,";
    CString strCmd;

    switch(strAddress.GetAt(0))
    {            
        // Bit Write    
        // X, M, Z 는쓰기불가..
        // 아래것은BitWord 모두가능하니까.. 구분해서처리하도록하자...
        case 'I':
        case 'Y':        
        case 'E':
        case 'L':
            // 여기까지는Bit/Word 모두사용가능

            if( strData.GetLength() < 5)                                // 길이가1이면1Bit만쓰자...
            {
                // 한비트씩쓰니까.. 길이는고정...
                strCmd.Format(_T("%.2dBWR%s,001,%s\r\n"),
                              nCpu,
                              strAddress,
                            // (strData.GetLength()),                            // 기존처럼.. 굳이.. 길이구할필요가없음..
                              strData);
            }
            else                                                                // 아니라면Word 형태로쓰자..
            {
                if(strData.GetLength() % 4 == 0)
                {
                    strCmd.Format(_T("%.2dWWR%s,%.2d,%s\r\n"),
                                  nCpu,
                                  strAddress,
                                  (int)(strData.GetLength() * 0.25),
                                  strData);
                }
                else
                {
                    _LOG_DISP(_T("Word 번지의값은4자리값만사용할수있습니다."));
                }
            }
            break;            

        // 여기부터는Word만가능
        case 'T':    // TP = Timer Current Value, TS = Timer preset value, TI = Timer current value(Count Up Type)
        case 'C':    // CP = Timer Current Value, CS = Timer preset value, CI = Timer current value(Count Up Type)     
        case 'D':    
        case 'B':
        case 'R':    
        case 'W':
        case 'V':    
        // Word Write
            if(strData.GetLength() % 4 == 0)
            {
                strCmd.Format(_T("%.2dWWR%s,%.2d,%s\r\n"),
                              nCpu,
                              strAddress,
                              (int)(strData.GetLength() * 0.25),
                              strData);
            }
            else
            {
                _LOG_DISP(_T("Word 번지의값은4자리값만사용할수있습니다."));
            }            
            break;

            // 특수명령어처리...
        case 'S':        
            switch(strAddress.GetAt(2))        
            {    
                case 'P':                                
                    strCmd.Format(_T("%.2dSTP\r\n"), nCpu);                    // Stop
                    break;                    

                case 'A':
                    strCmd.Format(_T("%.2dSTA\r\n"), nCpu);                    // Run
                    break;
            }
            break;
    }

    #ifdef _DEBUG
        //TRACE(strCmd);
        _LOG_DISP(strCmd);        
    #endif //_DEBUG    
    _LOG_DISP(strCmd);        
    return strCmd;
}

="X0"&REPT("0",3-LEN(DEC2HEX(ROW(A1)))) & DEC2HEX(ROW(A1))

 

참고용임…


정발위에도 모드칩 없이도 홈브류가 가능하다...

아래 블로그를 보고 내 WII에도 가능할 듯 싶어서 해 보았다.. 결과는 OK
(이전에도 나왔으나.. 그때 했을때는 실패ㅠㅠ .......
 정발은 안 되는가 싶었따... ㅠㅠ
까먹고 있다가 심심해서 검색해 본 결과 된다고 해서... 다시 시도~~)

HomeBrew가 모드칩 없이도 가능하다는것이다.. 물론 맨 아래쪽에 있는 IOS를 변경해야만 했다.
몇가지를 해 본 결과 가능했다.. 후후...
이제 위에서도 프로그래밍을 해볼수가 있겠군....


[관련 블로그]

정발위에도 홈브류 세계의 문이 열리게 된거 같습니다.  http://britzw.tistory.com/128

P.S


 


 

'1.소프트웨어 이야기 > 09.ETC' 카테고리의 다른 글

엑셀에서 16진후 변환 하는 함수 - 참고용  (0) 2009.08.28
Window 7 사용기  (0) 2009.05.08
mmTimer 사용  (0) 2009.02.09
자주 사용하는 프로그램 설치 결과..

프로그램 설치 및 실행 결과 (프로그램 명 / 설치 / 사용 / 비고)




#include "stdafx.h"

#include "windows.h"    

#include "Mmsystem.h"


void timeBeginPeriodTest()

{

    DWORD    dwStartTime = 0;

    DWORD    dwEndTime = 0;

    DWORD    dwTime;

    UINT    uTermTime = 1;


    // 타이머의 시간간격 설정(ms)

    timeBeginPeriod(uTermTime);


    // 시작 시간

    dwStartTime = timeGetTime();


    Sleep(10);


    // 경과 시간

    dwEndTime = timeGetTime();


    // 경과 시간 얻기

    dwTime = dwEndTime - dwStartTime;

    printf("경과시간 = %d msec\n", dwTime) ;


    // 타이머 종료(ms)

    timeEndPeriod(uTermTime);

}

1. winxp cd를 이용하여 cd-rom부팅  

2. winxp 복구선택 --> R 키 입력

도스 프롬프트가 나오면 복구 준비 완료

C:\>CHKDSK /P 를 입력후 엔터키를 누르고 완료 될때까지 대기

C:\>FIXBOOT 를 입력후  "Y" 키를 누른 후 완료 대기

C:\>EXIT

CD 빼고 재부팅

+ Recent posts