디버거는 어떻게 작동합니까?


170

디버거가 어떻게 작동하는지 궁금합니다. 특히 이미 실행중인 실행 파일에 '첨부'할 수있는 항목입니다. 컴파일러가 코드를 기계 언어로 변환한다는 것을 알고 있지만 디버거가 첨부 된 내용을 어떻게 '알고'있습니까?



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

답변:


96

디버거 작동 방식에 대한 자세한 내용은 디버깅 대상 및 OS에 따라 다릅니다. Windows의 기본 디버깅의 경우 MSDN에 대한 세부 사항을 찾을 수 있습니다 : Win32 Debugging API .

사용자는 이름 또는 프로세스 ID로 연결할 프로세스를 디버거에 알려줍니다. 이름 인 경우 디버거는 프로세스 ID를 조회하고 시스템 호출을 통해 디버그 세션을 시작합니다. Windows에서 이것은 DebugActiveProcess 입니다.

연결되면 디버거는 UI와 마찬가지로 이벤트 루프에 들어가지만 윈도우 시스템에서 들어오는 이벤트 대신 OS는 디버깅중인 프로세스에서 발생하는 상황 (예 : 예외 발생)에 따라 이벤트를 생성합니다. WaitForDebugEvent를 참조하십시오 .

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

디버거는 심볼 파일의 정보를 사용하여 주소에서 소스 이름의 변수 이름 및 위치로 변환 할 수 있습니다. 심볼 파일 정보는 별도의 API 세트이며 OS의 핵심 부분이 아닙니다. Windows에서 이는 디버그 인터페이스 액세스 SDK를 통해 이루어 집니다.

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


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

3
@StefanFalk 나는 x86에서 일부 하위 수준 세부 사항을 다루는 답변 을 썼습니다 .
Jonathon Reinhart

변수 이름이 주소에 정확히 어떻게 매핑되는지 설명 할 수 있습니까? 응용 프로그램은 실행될 때마다 변수에 대해 동일한 메모리 주소를 사용합니까? 나는 항상 사용 가능한 메모리에서 매핑 된 것으로 발견했지만 바이트가 앱의 메모리 공간에서 동일한 지점에 직접 매핑되는지 여부는 전혀 생각하지 않았습니다. 이것이 주요 보안 문제인 것 같습니다.
제임스 조슈아 스트리트

@JamesJoshuaStreet 디버거에만 해당되는 세부 사항이라고 생각합니다.
moonman239

이 답변은 무언가를 보여줍니다. 그러나 op가 일부 API 추상화가 아닌 일부 하위 수준 세부 정보에 더 관심이 있다고 생각합니다.
smwikipedia

63

내가 이해 한대로 :

x86의 소프트웨어 중단 점의 경우 디버거는 명령어의 첫 번째 바이트를 CC( int3)로 바꿉니다 . 이것은 WriteProcessMemoryWindows에서 수행됩니다 . CPU가 해당 명령을 받고를 실행 int3하면 CPU가 디버그 예외를 생성합니다. OS는이 인터럽트를 수신하고 프로세스가 디버깅되고 있음을 인식하고 중단 점에 도달했음을 디버거 프로세스에 알립니다.

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

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

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


25

Linux에서 프로세스 디버깅은 ptrace (2) 시스템 호출로 시작합니다. 이 기사 에는 ptrace간단한 디버깅 구성을 구현 하는 데 사용하는 방법에 대한 훌륭한 자습서가 있습니다 .


1
(2)"ptrace는 시스템 호출"보다 더 많거나 적은 것을 알려줍 니까 ?
Lazer

5
@eSKay, 아닙니다. 은 (2)매뉴얼 섹션 번호입니다. 매뉴얼 섹션에 대한 설명은 en.wikipedia.org/wiki/Man_page#Manual_sections 를 참조하십시오 .
Adam Rosenfield

2
@AdamRosenfield 섹션 2가 구체적으로 "시스템 호출"이라는 사실을 제외하고. 따라서 간접적으로 ptrace시스템 호출이라고합니다.
Jonathon Reinhart

1
더 실질적으로, (2)우리가 man 2 ptrace올바른 맨 페이지를 입력 하고 얻을 수 있다고 알려줍니다. 여기 ptrace에 명확 하지 않지만 Linux man printf와 비교할 수 있기 때문에 여기서 중요하지 않습니다 man 3 printf.
날씬한

9

Windows OS를 사용하는 경우 John Robbins의 "Microsoft .NET 및 Microsoft Windows 용 응용 프로그램 디버깅"에 대한 유용한 리소스가 있습니다.

(또는 이전 버전 : "디버깅 응용 프로그램" )

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

유닉스 / 리눅스 디버깅에 대해서는 잘 모르기 때문에 다른 OS에는 전혀 적용되지 않을 수 있습니다. 그러나 매우 복잡한 주제에 대한 소개로 세부 사항과 API가 아닌 개념은 대부분의 OS로 '이동'해야한다고 생각합니다.


3

디버깅을 이해하는 또 다른 유용한 소스는 인텔 CPU 매뉴얼 (인텔 ® 64 및 IA-32 아키텍처 소프트웨어 개발자 매뉴얼)입니다. 3 장 16 장에서는 특별 예외 및 하드웨어 디버깅 레지스터와 같은 디버깅의 하드웨어 지원을 소개했습니다. 다음은 그 장의 내용입니다.

T (trap) 플래그, TSS — TSS에 T 플래그가 설정된 작업으로 전환하려고 할 때 디버그 예외 (#DB)를 생성합니다.

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

이것이 누군가를 돕기를 바랍니다.


2

여기에 대답해야 할 두 가지 주요 질문이 있다고 생각합니다.

1. 디버거가 예외가 발생했음을 어떻게 알 수 있습니까?

디버깅중인 프로세스에서 예외가 발생하면 대상 프로세스에 정의 된 사용자 예외 처리기에서 예외에 응답 할 기회가 주어지기 전에 OS에서 디버거에 알립니다. 디버거가이 (첫 번째 기회) 예외 알림을 처리하지 않기로 선택하면 예외 디스패치 시퀀스가 ​​더 진행되고 대상 스레드에 예외를 처리 할 기회가 주어집니다. 대상 프로세스에서 SEH 예외를 처리하지 않으면 디버거는 처리되지 않은 예외가 대상 프로세스에서 발생했음을 알리기 위해 두 번째 기회 알림이라는 다른 디버그 이벤트를 보냅니다. 출처

여기에 이미지 설명을 입력하십시오


2. 디버거가 중단 점에서 중지하는 방법을 어떻게 알 수 있습니까?

간단한 대답 은 다음과 같습니다. 프로그램에 중단 점을 넣으면 디버거가 해당 지점의 코드를 소프트웨어 인터럽트 인 int3 명령어로 바꿉니다 . 결과적으로 프로그램이 일시 중단되고 디버거가 호출됩니다.


1

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

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


2
이것은 단지 기호에 관한 것입니다. 심볼보다 디버깅에 훨씬 더 많은 것이 있습니다.
Jonathon Reinhart 6
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.