ntdll.DbgBreakPoint에서 IDE 중단 문제

이 문제는 대부분의 개발자들은 겪지 않는 문제인데… 증상을 말하자면, 프로그램을 IDE 안에서 F9를 눌러 디버그 모드로 실행했을 때 어떤 특정 루틴에서 갑자기 어셈블리 화면이 뜨면서 IDE로 돌아오는 문제입니다. 아래 그림을 보시면 DbgBreakPoint라고 표시된 부분과 그 아래의 int 3 호출을 보실수 있을 겁니다.
사용자 삽입 이미지
보통 애플리케이션 실행중에 이렇게 느닷없이 IDE로 제어가 돌아오는 경우는 둘중의 하나인데, 개발자가 코드에 브레이크 포인트를 잡아놨거나, 아니면 뭔가 예외(exception)이 발생한 경우죠. 그런데 이 경우는 개발자가 브레이크 포인트를 잡지 않았는데 IDE로 돌아온 경우이기 때문에, 처음으로 이 현상을 만나게 되면 대부분의 개발자들이 예외라고 간주하고 이것이 뭔가 Delphi/C++Builder의 버그나 문제점이라고 오해를 많이 합니다.

하지만 이것은 Delphi나 C++Builder와는 무관한 문제이며, 실제로 운영 상황에서는 절대로 발생하지 않습니다. 실제로 이 현상이 발생하는 애플리케이션을 동일한 상황에서
IDE 내부가 아닌 별도로 실행하더라도 아무런 문제가 발견되지 않습니다. 정확하게 말하면, 이것은 윈도우 OS의 버그입니다.

DbgBreakPoint 함수는 Win32 API 함수로서, 코딩으로 브레이크 포인트 동작을 할 수 있도록 하는 역할을 합니다. 따라서 IDE 내부에서 디버그 모드로 실행하다가 이 루틴이 실행되면 그것이 Delphi 애플리케이션의 코드이든 아니면 OS에 속한 코드이든 실행을 멈추고 IDE로 돌아가도록 합니다. 그 순간에 자신이 개발한 Delphi의 코드가 아닌 OS의 코드가 실행되고 있었던 거죠.

Delphi/C++Builder IDE는 해당 애플리케이션의 코드를 넘어서서 OS 레벨이나 심지어는 다른 애플리케이션으로 제어권이 넘어간 상태에서도 디버그를 할 수가 있습니다. 해당 소스코드가 없는 경우에는 어셈블리 창으로 보여주죠. (소스가 없는 상태에서는 어셈블리라도 보여주는 것이 최선이니까요)

윈도우 OS의 일부인 ntdll.dll 내부에 이 DbgBreakPoint 함수에 대한 호출이 있는데요. 원래 마이크로소프트 내부의 윈도우 개발팀에서 윈도우 자체에 대한 디버깅을 하면서 집어넣었던 코드인데 미처 삭제하지 않았기 때문에 코드 내부적으로 특정 패턴의 호출이 일어나면 이런 현상이 발생합니다. 아마도 특정 윈도우 버전에서만 발생하는 것으로 생각되는데, 윈도우 비스타나 윈도우 7에서는 이런 문제가 발생했다는 리포트가 전혀 없었던 것으로 봐서 윈도우 XP 이하에서만 있었던 버그 같습니다.

이 문제(?)는 디버그 코드인 관계로 IDE 내부에서 디버깅 모드일 때만 발생하게 되며 실제로 별도로 실행했을 때는 전혀 발생하지 않습니다. 따라서 개발된 애플리케이션과는 아무런 상관이 없게 됩니다만, 다만 개발하고 있는 과정에서는 이 현상이 반복적으로 일어나면 개발자의 입장에서는 상당히 번거로울 것은 당연하겠죠.

그래서, 이 문제가 윈도우 OS의 문제임에도 개발자가 곤란을 겪을 수 있기 때문에, Delphi/C++Builder의 최근 버전들에는 이 문제에 대한 해결 방법이 마련되어 있습니다. IDE 메인 메뉴의 Tools->Options 메뉴 항목을 눌러 Options 다이얼로그를 띄우고, 왼쪽 트리에서 가장 아래의 Debugger Options->Embarcadero Debuggers를 선택한 후, 위에서 세번째에 있는 인 “Ignore non-user breakpoints” 체크박스에 체크하시면 됩니다.
사용자 삽입 이미지
이렇게 하면 이런 브레이크포인트 코드에 걸리지 않고 그대로 실행됩니다. 다만 이 옵션은 Delphi/C++Builder의 2007 버전 이상에만 있습니다.

6 comments for “ntdll.DbgBreakPoint에서 IDE 중단 문제

  1. 아주 nice한 포스팅입니다. 많은 도움이 되었습니다.

    그리고 혹시나 제가 델파이 버그를 발견하였다면 어디로 알려드려야 할까요?
    제가 imp@embarcadero.kr로 메일을 보냈는데 아무런 답장이 없으셔서
    말씀을 드립니다. 관련 버그는 VCL 버그입니다. 물론 전 Delphi 2010 업데이트 팩을 모두 다 받은 상태입니다.

  2. 아.. 언제쯤 메일을 보내셨는지…? 제가 대부분의 문의 메일들은 늦어도 며칠 이내로는 답변을 드리는데요. 제가 온갖 업무에 이리 뛰고 저리 뛰고 하다보니 간혹 놓치고 넘어가는 경우도 좀 있습니다. –;;;;

    보내신 메일의 명의와 날자를 알려주시면 찾아보고 답변을 드리도록 하겠습니다. ^^;;;

  3. 메일제목 “Delphi 2010관련 버그에 대해서..”입니다.
    보낸 사람은 “정 룡옥‏” 이고 메일주소는 “hackingfanatic@hotmail.com” 입니다.
    보냈을 때의 날짜는 “2010-07-18″입니다.
    설마 메일이 안 갔다면 ㅠㅠ

  4. 아! 정룡옥님이시군요. ㅎㅎ 아이디만 보고 다른 분이신 줄 알았습니다.

    보내주신 메일은 찾았구요. 보니까 한 가지도 아니고 헉 세 가지나 보내주셨네요.
    자세히 검토해보는 건 아마도 시간을 좀 들여야 할 거 같은데, 검토 후에 알려드리도록 하겠습니다.

    일단 대충 보니까 두번째 문제는 어떤 종류의 문제인지 감이 옵니다. 아마도 WM_NCCREATE 메시지의 처리와 관련이 있을 거 같네요. 탐색기인 explorer.exe가 다시 실행될 때는 이 메시지가 여러번 브로드캐스팅 되는 것 같더라구요.

    • 댓글로 나마 빠른 답변을 해주셔서 감사드립니다.^^
      제가 원하는거는 꼭 요번버전에 패치로 안 나오더라도 정식으로 다음 Delphi 2011이라던지 그런데에 수정되었으면 하는 바램입니다. ㅎㅎ

  5. 아.. 알겠습니다.
    그런데 지금 다음 버전은 거의 골드 코드에 가까운 상태라서, 바로 다음 버전의 RTM에 패치가 적용되도록 하기는 어려울 것 같네요. 그래도 꼭 제대로 픽스 되도록 노력하겠습니다. ^^

답글 남기기

이메일 주소는 공개되지 않습니다.