디버거가 어떻게 작동하는지 궁금합니다. 특히 이미 실행중인 실행 파일에 '첨부'할 수있는 항목입니다. 컴파일러가 코드를 기계 언어로 변환한다는 것을 알고 있지만 디버거가 첨부 된 내용을 어떻게 '알고'있습니까?
디버거가 어떻게 작동하는지 궁금합니다. 특히 이미 실행중인 실행 파일에 '첨부'할 수있는 항목입니다. 컴파일러가 코드를 기계 언어로 변환한다는 것을 알고 있지만 디버거가 첨부 된 내용을 어떻게 '알고'있습니까?
답변:
디버거 작동 방식에 대한 자세한 내용은 디버깅 대상 및 OS에 따라 다릅니다. Windows의 기본 디버깅의 경우 MSDN에 대한 세부 사항을 찾을 수 있습니다 : Win32 Debugging API .
사용자는 이름 또는 프로세스 ID로 연결할 프로세스를 디버거에 알려줍니다. 이름 인 경우 디버거는 프로세스 ID를 조회하고 시스템 호출을 통해 디버그 세션을 시작합니다. Windows에서 이것은 DebugActiveProcess 입니다.
연결되면 디버거는 UI와 마찬가지로 이벤트 루프에 들어가지만 윈도우 시스템에서 들어오는 이벤트 대신 OS는 디버깅중인 프로세스에서 발생하는 상황 (예 : 예외 발생)에 따라 이벤트를 생성합니다. WaitForDebugEvent를 참조하십시오 .
디버거는 대상 프로세스의 가상 메모리를 읽고 쓸 수 있으며 OS에서 제공하는 API를 통해 레지스터 값을 조정할 수도 있습니다. Windows 용 디버깅 기능 목록을 참조하십시오 .
디버거는 심볼 파일의 정보를 사용하여 주소에서 소스 이름의 변수 이름 및 위치로 변환 할 수 있습니다. 심볼 파일 정보는 별도의 API 세트이며 OS의 핵심 부분이 아닙니다. Windows에서 이는 디버그 인터페이스 액세스 SDK를 통해 이루어 집니다.
관리되는 환경 (.NET, Java 등)을 디버깅하는 경우 프로세스는 일반적으로 비슷하지만 가상 시스템 환경이 기본 OS가 아닌 디버그 API를 제공하므로 세부 사항이 다릅니다.
내가 이해 한대로 :
x86의 소프트웨어 중단 점의 경우 디버거는 명령어의 첫 번째 바이트를 CC
( int3
)로 바꿉니다 . 이것은 WriteProcessMemory
Windows에서 수행됩니다 . CPU가 해당 명령을 받고를 실행 int3
하면 CPU가 디버그 예외를 생성합니다. OS는이 인터럽트를 수신하고 프로세스가 디버깅되고 있음을 인식하고 중단 점에 도달했음을 디버거 프로세스에 알립니다.
중단 점에 도달하고 프로세스가 중지 된 후 디버거는 중단 점 목록을보고 CC
원래 있던 바이트로 대체합니다 . 디버거 TF
는를EFLAGS
수정 하여 트랩 플래그 를 설정 CONTEXT
하고 프로세스를 계속합니다. 트랩 플래그는 CPU가 INT 1
다음 명령어에서 단일 단계 예외 ( ) 를 자동으로 생성 하도록합니다.
다음에 디버깅중인 프로세스가 중지되면 디버거가 중단 점 명령어의 첫 번째 바이트를 다시로 바꾸고 CC
프로세스가 계속됩니다.
이것이 모든 디버거에 의해 어떻게 구현되는지 확실하지 않지만이 메커니즘을 사용하여 자체적으로 디버깅하는 Win32 프로그램을 작성했습니다. 완전히 쓸모는 없지만 교육적입니다.
Linux에서 프로세스 디버깅은 ptrace (2) 시스템 호출로 시작합니다. 이 기사 에는 ptrace
간단한 디버깅 구성을 구현 하는 데 사용하는 방법에 대한 훌륭한 자습서가 있습니다 .
(2)
"ptrace는 시스템 호출"보다 더 많거나 적은 것을 알려줍 니까 ?
(2)
매뉴얼 섹션 번호입니다. 매뉴얼 섹션에 대한 설명은 en.wikipedia.org/wiki/Man_page#Manual_sections 를 참조하십시오 .
ptrace
시스템 호출이라고합니다.
(2)
우리가 man 2 ptrace
올바른 맨 페이지를 입력 하고 얻을 수 있다고 알려줍니다. 여기 ptrace
에 명확 하지 않지만 Linux man printf
와 비교할 수 있기 때문에 여기서 중요하지 않습니다 man 3 printf
.
Windows OS를 사용하는 경우 John Robbins의 "Microsoft .NET 및 Microsoft Windows 용 응용 프로그램 디버깅"에 대한 유용한 리소스가 있습니다.
(또는 이전 버전 : "디버깅 응용 프로그램" )
이 책에는 몇 가지 간단한 (하지만 작동하는) 디버거 용 코드가 포함 된 디버거 작동 방식에 대한 장이 있습니다.
유닉스 / 리눅스 디버깅에 대해서는 잘 모르기 때문에 다른 OS에는 전혀 적용되지 않을 수 있습니다. 그러나 매우 복잡한 주제에 대한 소개로 세부 사항과 API가 아닌 개념은 대부분의 OS로 '이동'해야한다고 생각합니다.
디버깅을 이해하는 또 다른 유용한 소스는 인텔 CPU 매뉴얼 (인텔 ® 64 및 IA-32 아키텍처 소프트웨어 개발자 매뉴얼)입니다. 3 장 16 장에서는 특별 예외 및 하드웨어 디버깅 레지스터와 같은 디버깅의 하드웨어 지원을 소개했습니다. 다음은 그 장의 내용입니다.
T (trap) 플래그, TSS — TSS에 T 플래그가 설정된 작업으로 전환하려고 할 때 디버그 예외 (#DB)를 생성합니다.
Window 또는 Linux에서이 플래그를 사용할지 여부는 확실하지 않지만 해당 장을 읽는 것이 매우 흥미 롭습니다.
이것이 누군가를 돕기를 바랍니다.
여기에 대답해야 할 두 가지 주요 질문이 있다고 생각합니다.
1. 디버거가 예외가 발생했음을 어떻게 알 수 있습니까?
디버깅중인 프로세스에서 예외가 발생하면 대상 프로세스에 정의 된 사용자 예외 처리기에서 예외에 응답 할 기회가 주어지기 전에 OS에서 디버거에 알립니다. 디버거가이 (첫 번째 기회) 예외 알림을 처리하지 않기로 선택하면 예외 디스패치 시퀀스가 더 진행되고 대상 스레드에 예외를 처리 할 기회가 주어집니다. 대상 프로세스에서 SEH 예외를 처리하지 않으면 디버거는 처리되지 않은 예외가 대상 프로세스에서 발생했음을 알리기 위해 두 번째 기회 알림이라는 다른 디버그 이벤트를 보냅니다. 출처
2. 디버거가 중단 점에서 중지하는 방법을 어떻게 알 수 있습니까?
간단한 대답 은 다음과 같습니다. 프로그램에 중단 점을 넣으면 디버거가 해당 지점의 코드를 소프트웨어 인터럽트 인 int3 명령어로 바꿉니다 . 결과적으로 프로그램이 일시 중단되고 디버거가 호출됩니다.
응용 프로그램이나 DLL 파일을 컴파일 할 때 컴파일 할 때마다 함수와 변수를 나타내는 기호가 포함된다는 것을 이해합니다.
디버그 빌드를 사용하는 경우이 기호는 릴리스 빌드 인 경우보다 훨씬 상세하므로 디버거가 더 많은 정보를 제공 할 수 있습니다. 디버거를 프로세스에 연결하면 현재 액세스중인 함수를 확인하고 여기에서 사용 가능한 모든 디버깅 기호를 확인합니다 (컴파일 된 파일의 내부가 어떤 모양인지 알기 때문에 메모리에 무엇이 있는지 알 수 있음) int, float, string 등의 내용을 포함합니다). 첫 번째 포스터가 말했듯이,이 정보와 이러한 기호의 작동 방식은 환경과 언어에 따라 다릅니다.