'WinDBG'에 해당되는 글 4건

  1. 2012/11/07 Driver Verifier 와 STATUS_WAIT_n 2
  2. 2008/06/18 Windbg에서 조건문 bp 1
  3. 2006/12/08 리모트 디버깅 4
  4. 2006/11/01 WinDBG에서 USB2.0 디버깅

Driver Verifier 와 STATUS_WAIT_n
2012/11/07 08:55
작성중인 드라이버에 딱히 원인을 알수 없는 문제가 생겨 Driver Verifier 옵션을 모두 on 시키고 디버깅 작업시도.
드라이버를 UpperFilter 에 등록하고 IRP_MJ_PNP/IRP_MN_START_DEVICE 에서 STATUS_UNSUCCESSFUL를 return 하도록 하는 부분에서 Driver Verifier 가 아래와 같이 에러를 발생시켰다.
***********************************************************************
* THIS VALIDATION BUG IS FATAL AND WILL CAUSE THE VERIFIER TO HALT    *
* WINDOWS (BUGCHECK) WHEN THE MACHINE IS NOT UNDER A KERNEL DEBUGGER! *
***********************************************************************

WDM DRIVER ERROR: [xxxxx.sys @ 0xF77F1FE0] An IRP dispatch handler (
                  F77F1FE0 ) has returned a status that is inconsistent with
                  the Irp's IoStatus.Status field. ( Irp = 8746AE90 -
                  Irp->IoStatus.Status = 00000003 - returned = 00000000 )
IRP_MJ_PNP.IRP_MN_REMOVE_DEVICE -
[ DevObj=86C043B8, FileObject=00000000, Parameters=00000000 00000000 00000000 00000000 ]
http://www.microsoft.com/hwdq/bc/default.asp?os=5.1.2600&major=0xc9&minor=0x224&lang=0x9

Break, Ignore, Zap, Remove, Disable all (bizrd)?

IRP_MJ_PNP/IRP_MN_START_DEVICE 에서 STATUS_UNSUCCESSFUL 을 return 하는건 장치를 start 할수 없는경우 당연한 리턴값이므로 전혀 문제될것이 없다.

!drvstack 을 통해 driver stack 을 살펴보니 작성중인 드라이버 아래위로 VERIFIER 드라이버 보이고
작성중인 드라이버 앞단에서 status 값이 STATUS_SUCCESS 값이 아닌 STATUS_WAIT_2 또는 STATUS_WAIT_3 이 넘어온다.
그 값을 작성중인 드라이버에서는 STATUS_UNSUCCESSFUL 로 변경시켜 다시 아래의 VERIFIER 드라이버로 넘긴다.
(STATUS_WAIT_n 에 대한 정의는 아래와 같이 되어 있는데 전혀 도움이 안된다.)
0x00000001 STATUS_WAIT_1 The caller specified WaitAny for WaitType and one of the dispatcher objects in the Object array has been set to the signaled state.
이 과정에서 Driver Verifier 는 앞뒤의 status 값이 다르기 때문에 에러는 발생시킨다.
(Driver Verifier 의 모든 옵션을 on 했지만 아마도 Enhanced I/O verification 으로 추정)

그러면 왜 STATUS_SUCCESS 를 return 하지 않고 STATUS_WAIT_n 와 같은 값을 return 하는걸까?

아래 코드를 보면 IoCallDriver() 호출이후 성공시 다음 처리를 하도록 되어 있다.

status = IoCallDriver(...);
if status == STATUS_SUCCESS

그러나 위와 같은 코드에서는 Driver Verifier 옵션을 on 시켰을 경우 원하는 대로 동작하지 않는 경우가 생긴다.
물론 Driver Verifier 를 on 하지 않는 경우에도 원하는 동작을 하지 않는 경우가 생긴다.
(아래의 NT_SUCCESS macro 정의를 보면 성공값은 0으로 정의된 STATUS_SUCCESS 만 있는 것이 아니다.)

따라서 if 문 에서 성공값을 검사할때 STATUS_SUCCESS 값을 검사하지 않고 NT_SUCCESS(...)와 같은 macro 사용하여야 한다.

NT_SUCCESS(status)
 status의 값이 성공 유형에 대한 값(0−0x3FFFFFFF) 또는 정보 유형에 대한 값(0x40000000-0x7FFFFFFF) 이면 TRUE.

NT_INFORMATION(status)
 status의 값이 정보 유형에 대한 값(0x40000000-0x7FFFFFFF) 이면 TRUE.

NT_WARNING(status)
 status의 값이 경고 유형에 대한 값(0x80000000−0xBFFFFFFF) 이면 TRUE.

NT_ERROR(status)
 status의 값이 오류 유형에 대한 값(0xC0000000 - 0xFFFFFFFF) 이면 TRUE.


NTSTATUS 의 성공값 또는 기타 에러에 대한 검사는 NT_SUCCESS() 또는 NT_ERROR()를 사용해야 할듯.
2012/11/07 08:55 2012/11/07 08:55
Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

  • leokadiagady 2020/05/29 02:22  댓글주소  수정/삭제  댓글쓰기
    google.com
  • teodoragrzywa 2020/05/29 04:52  댓글주소  수정/삭제  댓글쓰기
    google.com

  • Windbg에서 조건문 bp
    2008/06/18 08:38

    MSDN 블러그를 보다 보니...
    Windgb로 조건문 bp 사용에 대해 자세한 설명을 해놓았다.
    http://blogs.msdn.com/debuggingtoolbox/archive/2008/06/12/special-command-if-and-j-to-use-in-breakpoints-and-scripts.aspx

    특정 지점에서 10번째 카운터에서 bp를 잡는 예제를 아래와 같이 써두었는데...

    r @$t0 = 0
    bp mtgdi!CBallThread::SingleStep "r @$t0 = @$t0 + 1;.if(@$t0 > 0n10){.echo More than 10 times...}.else{ gc }"

    누군가 달아놓은 코멘트가 압권...

    bp mtgdi!CBallThread::SingleStep 10

    딸랑 이 한줄이면 된단다.
    하아...


    2008/06/18 08:38 2008/06/18 08:38
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

  • 비밀방문자 2009/06/12 15:24  댓글주소  수정/삭제  댓글쓰기
    관리자만 볼 수 있는 댓글입니다.

  • 리모트 디버깅
    2006/12/08 13:17

    가끔 고객의 PC에서만 발생되는 버그를 Debugging 하기 위해서 고객을 방문해서 디버깅을 해야할때가 있다. 하지만 고객의 PC에 비주얼스튜디오를 설치 할수도 없고 설치한다고 한들 각종 환경설정은 어떻게 할것이냐 라는 문제에 봉착한다.
    그나마 VC++6 이면 설치하는데 별문제가 없겠지만 NET 2005의 경우라면 아예 설치할 생각을 말아야 한다.
    해서 리모트 디버깅을 해야 하는데 비주얼 스튜디오 버전에 따라 현지 사정에 따라 디버깅을 방법을 달리 해야 되는 경우가 많다.

    리모트디버깅은 위에서 말한것처럼 꼭 고객의 PC 뿐 아니라 개발환경이 설치되지 않은 clean 한 상태에서 테스트용 디버깅과 UI로 local 디버깅의 불편함도 해소 한다는 점에서 많은 이점이 있다.

    또한 이러한 방법들도 중요하지만 보다 중요한 것은 표준적인 디버깅환경이다. 같은 회사내에서도 다른 디버깅을 방법을 사용한다던가 개발자마다 다른 버전의 개발툴, 환경에서 오는 혼동도 무시 못한다. 먼저 이러한 부분에 있어서의 표준화가 먼저 되어야겠다.

    디버깅을 하기 전에 아래 링크에서 리모트디버깅을 위한 서버설정을 위한 파일들을 다운받도록 한다.
    http://hongyver.pe.kr/project/remotedbg.zip
    위의 파일들은 VC6~2005, WinDBG용 서버용 파일들이 있다. 원하는 파일을 고객 또는 디버깅 해야할 PC로 복사하여 사용한다.

    유저모드, 응용프로그램류를 디버깅할때
    VC++6에서 디버깅
    디버깅할 PC, 즉 고객의 PC에서 위에서 다운받은 파일중 msvcmon.exe(msvcmon.exe는 NET용이다.주의할것)를 실행시키면 아래와 같은 화면이 나온다.

    Visual C++ Debug Monitor에서 Setting을 눌러 Target machine name or address에 개발자 PC의 IP 또는 컴퓨터 이름을 입력한다.
    OK를 누르고 Connect를 누르면 Disconnecting 이라는 메세지가 나오면서 연결대기 상태가 된다. 이것으로 서버의 설정은 끝났다.
    그럼 다음으로 개발자 PC에서는 Project의 Setting을 눌러 Debug 란 탭을 눌러 아래의 화면처럼 설정한다.
    맨 아래의 Remote executable path and file name 란에 고객PC 또는 디버깅할 PC에 있는 디버깅할 파일명을 적는다. 상단의 Executable for debug session과 같은 파일명이다.
    그리고 나서 F5를 눌러 디버깅을 눌러 실행하면 고객PC에서는 프로그램이 실행되고 개발자의 PC에서는 디버깅이 가능하다.

    VS.NET 2005에서의 디버깅
    서 디버깅할 PC, 즉 고객의 PC에서 위에서 다운받은 파일중 msvsmon.exe(vc8이란 디렉토리에 있다.)를 실행시키면 아래와 같은 화면이 나온다.
    도구 -> 옵션을 눌러 위의 그림처럼 인증안함으로 설정하고 확인을 누르면 서버(고객PC 또는 디버깅할 PC)의 설정은 끝났다.

    다음으로 개발자 PC에서 비주얼스튜디어2005를 실행시켜 소스를 읽어들인다음  도구->프로세스연결 을 눌러 아래화면으로 띄운다.
    전송은 원격(네이티브 전용, 인증안함)으로 설정하고 한정자는 고객PC 또는 디버깅할 PC의 IP 번호 또는 컴퓨터이름을 입력하면 사용 가능한 프로세스 에 현재 고객PC 또는 디버깅할 PC의 프로세스들이 보인다. 이중 디버깅을 하고자 하는 프로세스를 클릭하고 연결을 누르면 디버깅이 가능하다. 그래서 원격지 PC에서 먼저 프로세스를 실행시켜야 두어야 한다.

    WinDBG
    고객PC 또는 디버깅할 PC에서 windbg.exe -server tcp:port=9090 (예시 포트번호) 로 수행한다.(바로가기를 만들어 속성에 추가해도 된다)
    개발자PC에서는 windbg.exe -remote tcp:Port=9090,Server=vmxp 로 서버에 접속할수 있다.
    아니면 아래의 그림처럼 메뉴의 File -> Connect to Remote Session 를 선택하여 Browse를 선택.
    Machine에 컴퓨터 이름 또는 IP번호를 입력하고 refresh를 누르면 Servers에 서버가 뜬다.
    서버를 클릭하여 접속한다.

    여기까지 해서 WinDBG로 고객PC와 개발자PC가 접속이 되었다면 실제로 디버깅을 수행하기 위해서는 고객PC 또는 디버깅할 PC에서 File -> Attach to a Process 를 선택하여 디버깅할 프로세스를 선택하여야 한다.
    비주얼 스튜디오에 비해 다소 불편하지만 보다 많은 정보와 폭 넓은 디버깅을 지원한다. 뿐만 아니라 꼭 TCP/IP 가 아닌 1394 나 시리얼을 통해서 디버깅이 가능하다.

    커널모드, 디바이스드라이버류
    SoftICE
    설치후 CTRL+D 로 디버깅이 가능하다.
    물론 Symblo Loader 라는 프로그램으로 디버깅하고자 하는 파일(EXE, DLL, SYS, DRV등등)을 File -> Open 한후  Module -> Load 를 수행하면 소스코드를 찾는데 이때 올바른 폴더를 지정해주면 CTRL+D 이후 디버깅에서 소스레벨의 디버깅이 가능하다.

    WinDBG
    설정방법은 아래 링크를 참조.
    단 WinDBG의 커널 디버깅에서는 SoftICE와는 달리 EXE 또는 DLL 디버깅을 할수 없고 커널관련 모듈(SYS)만 가능하다.
    역시 심볼설정을 통해 소스레벨의 디버깅이 가능하다.
    http://www.debuglab.com/board_detail.aspx?id=98&table=lecture&pagenum=10

    2006/12/08 13:17 2006/12/08 13:17
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

  • 우스 2007/02/01 00:18  댓글주소  수정/삭제  댓글쓰기
    안녕하세요^^;; 정말 좋은 정보인 것 같아서 담아가려구요^^;;
  • sunny 2007/06/25 11:53  댓글주소  수정/삭제  댓글쓰기
    넬름 퍼갔습니다. ;
  • 우왕... 2009/08/25 11:15  댓글주소  수정/삭제  댓글쓰기
    안녕하세요. 너무 좋은 내용이라 댓글 남기고 갑니다..잘 봤습니다.!!!!
    그런데 VS6.0 에서는 바로 F5 가 아니라 Build -> Debugger Remote Connection... 에서 Network (TCP/IP) -> Setting...부분에서 Target PC 의 IP를 입력해야 하는거 아닌가요? ^^;
    좋은 내용이라..제 블로그에 참조 했습니다 ^^;;

  • WinDBG에서 USB2.0 디버깅
    2006/11/01 09:59

    무지 편리할것 같아서...
    구글링을 해봤더니...

    일단 전용선이 필요한데다 국내 제작업체는 보이지 않는듯하고...
    제작하는 외국 업체도 Vista 만 지원한다니...

    결국 1394나 NullModem(COM1)으로 할수밖에 없구나...

    http://www.plxtech.com/products/NET2000/NET20DC/default.asp

    2006/11/01 09:59 2006/11/01 09:59
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다