2008-10-19 11 views
137

디버거가 어떻게 작동하는지 궁금합니다. Particulary는 이미 실행중인 실행 파일에 '첨부'할 수 있습니다. 나는 컴파일러가 기계어로 코드를 번역한다는 것을 이해하지만, 디버거가 어떻게 연결되는지를 '알 수 있습니까?'디버거는 어떻게 작동합니까?

+4

Eli의 기사가 http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1로 이동했습니다. – Oktalist

+0

@Oktalist이 기사는 흥미 롭습니다 만 API 레벨 추상화에 대해서만 이야기합니다. Linux에서 디버깅. 나는 OP가 후드에 대해 더 알고 싶어한다고 생각합니다. – smwikipedia

답변

74

디버거 작동 방식에 대한 자세한 내용은 디버깅중인 내용과 OS가 무엇인지에 따라 다릅니다. Windows에서의 네이티브 디버깅을 위해 MSDN에서 몇 가지 세부 정보를 찾을 수 있습니다 : Win32 Debugging API.

사용자가 디버거에게 연결할 프로세스를 이름 또는 프로세스 ID로 알려줍니다. 이것이 이름이라면 디버거는 프로세스 ID를 검색하고 시스템 호출을 통해 디버그 세션을 시작합니다. Windows에서는 DebugActiveProcess이됩니다.

일단 연결되면 디버거는 모든 UI와 비슷하게 이벤트 루프를 시작하지만 윈도우 시스템에서 오는 이벤트 대신 OS가 디버깅중인 프로세스에서 발생하는 이벤트를 기반으로 이벤트를 생성합니다. 예를 들어 예외 발생 . WaitForDebugEvent을 참조하십시오.

디버거는 대상 프로세스의 가상 메모리를 읽고 쓸 수 있으며 OS가 제공하는 API를 통해 레지스터 값을 조정할 수도 있습니다. Windows 용 debugging functions 목록을 참조하십시오.

디버거는 기호 파일의 정보를 사용하여 주소에서 소스 코드의 변수 이름과 위치로 변환 할 수 있습니다. 심볼 파일 정보는 별도의 API 집합이며 운영 체제의 핵심 부분은 아닙니다. Windows의 경우 이것은 Debug Interface Access SDK입니다.

관리되는 환경 (.NET, Java 등)을 디버깅하는 경우 프로세스는 일반적으로 비슷하지만 가상 컴퓨터 환경이 기본 OS가 아닌 디버그 API를 제공하므로 세부 사항이 다릅니다.

+3

이 질문은 어리석게 들릴지 모르지만 프로그램 내부의 특정 주소에 도달하면 OS가 어떻게 추적합니까? 예 : 주소 0x7710cafe에 breackpoint가 설정됩니다. 명령 포인터가 변경되면 OS (또는 CPU)가 명령 포인터를 모든 중단 점 주소와 비교해야합니까, 그렇지 않습니까? 어떻게 작동합니까 ..? – displayname

+2

@StefanFalk 저수준의 세부 사항 (x86)을 다루는 [대답] (http://stackoverflow.com/a/21746853/119527). –

+0

힌트를 보내 주셔서 감사합니다. – displayname

1

제 생각에는 응용 프로그램이나 DLL 파일을 컴파일 할 때 함수와 변수를 나타내는 기호가 포함 된 파일을 컴파일해야합니다.

디버그 빌드가있는 경우 이러한 심볼은 릴리스 빌드보다 훨씬 상세하므로 디버거에서 자세한 정보를 제공 할 수 있습니다. 디버거를 프로세스에 연결하면 현재 액세스중인 함수를 찾고 여기에서 사용 가능한 모든 디버깅 기호를 해결합니다 (컴파일 된 파일 내부의 모양을 알고 있으므로 메모리에있는 내용을 확인할 수 있습니다) ints, float, strings 등의 내용 포함). 첫 번째 포스터가 말했듯이이 정보와이 기호가 어떻게 작용하는지는 환경과 언어에 따라 다릅니다.

+1

이것은 상징에 관한 것입니다. 심볼보다 디버깅이 훨씬 더 큽니다. –

9

는 Windows OS에 있다면,이를위한 훌륭한 자원 존 로빈스에 의해 "마이크로 소프트 .NET 및 Microsoft Windows 용 디버깅 응용 프로그램"이 될 것입니다 :

(또는 심지어 이전 버전 : "Debugging Applications")

이 책에는 몇 가지 간단한 (그러나 작동하는) 디버거 코드가 포함 된 디버거 작동 방식에 대한 장이 있습니다.

유닉스/리눅스 디버깅의 세부 사항에 익숙하지 않으므로이 내용은 다른 OS에 전혀 적용되지 않을 수 있습니다. 그러나 매우 복잡한 주제에 대한 소개로서 개념과 세부 사항 및 API가 아니라면 대부분의 OS에 '포팅'해야한다고 생각합니다.

23

리눅스에서는 프로세스 디버깅이 ptrace(2) 시스템 호출로 시작됩니다. This article에는 간단한 디버깅 구성을 구현하기 위해 ptrace을 사용하는 방법에 대한 훌륭한 자습서가 있습니다.

+1

'(2)'는 "ptrace가 시스템 호출"보다 더 많은 (또는 적은) 것을 알려줍니까? – Lazer

+5

@eSKay, 아니요. '(2)'는 수동 섹션 번호입니다. 매뉴얼 섹션에 대한 설명은 http://en.wikipedia.org/wiki/Man_page#Manual_sections를 참조하십시오. –

+2

@AdamRosenfield 섹션 2가 특별히 "시스템 호출"이라는 사실을 제외하고는. 간접적으로, 예, 그것은'ptrace'가 시스템 콜이라는 것을 말해줍니다. –

3

디버깅을 이해하는 또 다른 중요한 소스는 Intel CPU 설명서 (인텔 ® 64 및 IA-32 아키텍처 소프트웨어 개발자 설명서)입니다. 볼륨 3A, 16 장에서는 특수 예외 및 하드웨어 디버깅 레지스터와 같은 디버깅 하드웨어 지원을 소개했습니다. 다음은 해당 장의 내용입니다.

T (트랩) 플래그, TSS - TSS에 T 플래그가 설정된 작업으로 전환하려고 시도한 경우 디버그 예외 (#DB)를 생성합니다. #

Window 또는 Linux가이 플래그를 사용하는지 여부는 확실하지 않지만 해당 장을 읽는 것은 매우 흥미 롭습니다.

희망이 있으면 도움이됩니다.

44

내가 알고있는 것처럼 : 86에 소프트웨어 브레이크 포인트에 대한

는, 디버거는 CC (int3)와 명령의 첫 번째 바이트를 대체합니다. 이 작업은 Windows에서 WriteProcessMemory으로 수행됩니다. CPU가 해당 명령에 도달하여 int3을 실행하면 CPU가 디버그 예외를 생성합니다. OS는이 인터럽트를 수신하여 프로세스가 디버깅 중임을 인식하고 디버거 프로세스에 중단 점에 도달했음을 알립니다.

중단 점에 도달하고 프로세스가 중지 된 후 디버거는 중단 점 목록을보고 CC을 원래 있던 바이트로 바꿉니다. 디버거는 TF, the Trap FlagEFLAGS (CONTEXT을 수정하여)에 설정하고 프로세스를 계속합니다. 트랩 플래그는 CPU가 다음 명령어에서 단일 단계 예외 (INT 1)를 자동으로 생성하도록합니다.

디버깅중인 프로세스가 다음 번에 중지되면 디버거가 중단 점 명령의 첫 번째 바이트를 CC으로 다시 바꾸고 프로세스가 계속됩니다.

이것이 모든 디버거에 의해 구현 된 방법인지는 확실치 않지만이 메커니즘을 사용하여 자체 디버깅을 관리하는 Win32 프로그램을 작성했습니다. 완전히 쓸모 없지만 교육적입니다.

관련 문제