GDB는 어떻게 실행을 일시 중지합니까? 사용하고 코드에서 중단 점을 설정하여 디버깅을 위해

아시다시피, GDB를 사용하고 코드에서 중단 점을 설정하여 디버깅을 위해 실행을 일시 중지 할 수 있습니다.

내 질문은 GDB가 프로세스를 일시 중지하고 i r예를 들어 레지스터의 내용을 볼 수있게하는 것 입니다. 다른 OS 프로세스에서 해당 레지스터를 지속적으로 사용하고 있지 않습니까? 어떻게 덮어 쓰지 않습니까?

라이브 데이터가 아닌 컨텐츠의 스냅 샷입니까?



답변

아키텍처에 따라 약간 씩 다르지만 중요한 점은 거의 보편적으로 적용됩니다.

  • 서비스 중단으로 인해 ISR을 실행하기 전에 CPU 상태 (레지스터 포함)가 메모리에 저장되고 ISR이 종료 될 때 복원됩니다.

  • 인터럽트 서비스 루틴이 해당 레지스터가 저장된 메모리 위치의 내용을 교환하면 컨텍스트 전환을 수행 할 수 있습니다 . 모든 스레드에는 스레드가 실행되지 않을 때 레지스터가 저장되는 메모리 영역이 있습니다.

  • 컨텍스트 스위치는 스레드가 I / O를 기다리고 있는지 여부, 동기화, 우선 순위, 신호 전달 등을 고려 하는 스레드 스케줄러에 의해 제어됩니다 . 종종 중단 카운트가 고려됩니다.

  • 디버거는 일시 중단 횟수를 증가시켜 스레드를 실행할 수 없도록합니다. 그런 다음 스레드의 저장된 레지스터 사본을 검사하고 변경할 수 있습니다.


답변

@BenVoigt의 훌륭한 정보 외에도 다음과 같이 추가 할 수 있습니다.

중단 점은 디버그하려는 프로세스의 기계 코드 값 (명령 또는 명령의 일부)을 원하는 (소스) 행에 해당하는 코드 위치의 특정 트랩 명령으로 대체하여 디버거에 의해 설정됩니다. 이 특정 트랩 명령어는 중단 점으로 사용하기위한 것입니다. 디버거는이를 알고 운영 체제도 알고 있습니다.

디버깅중인 프로세스 / 스레드가 트랩 명령에 도달하면 @Ben이 설명하는 프로세스를 트리거합니다. 여기에는 나중에 재개 될 수 있도록 현재 실행중인 스레드 (CPU 상태를 메모리에 저장 포함)를 일시 중단하는 컨텍스트 스왑의 절반이 포함됩니다. 이 트랩은 중단 점 트랩이므로 운영 체제는 @Ben이 설명하는 메커니즘을 사용하여 디버그중인 프로세스를 일시 중단 상태로 유지하고 디버거에 알리고 결국 재개합니다.

디버거는 시스템 호출을 사용하여 디버깅중인 일시 중단 된 프로세스 / 스레드의 저장된 상태에 액세스합니다.

디버거는 고장난 코드 줄을 실행 (재개)하기 위해 (현재 특정 트랩 명령이 있음) 중단 점 트랩 명령으로 덮어 쓴 원래 머신 코드 값을 복원하고 다른 트랩을 다른 곳에 설정합니다 (예 : 단일 스테핑, 또는 사용자가 새로운 중단 점을 만들고) @Ben이 설명하는 메커니즘을 사용하여 프로세스 / 스레드를 실행 가능으로 표시합니다.

실제 실행되는 세부 사항은 더 긴 실행 중단 점을 유지한다는 것은 실제 코드에 대한 중단 점 트랩을 교체하여 행이 실행될 수 있도록 한 다음 중단 점을 다시 교체하는 것과 같은 작업을 수행한다는 점에서 더 복잡 할 수 있습니다.

다른 OS 프로세스에서 해당 레지스터를 지속적으로 사용하고 있지 않습니까? 어떻게 덮어 쓰지 않습니까?

@Ben이 설명했듯이 타임 슬라이싱을 사용하여 여러 프로세스 / 스레드에서 프로세서를 공유 할 수있는 기존의 스레드 일시 중단 / 다시 시작 기능 ( 멀티 태스킹 의 컨텍스트 전환 / 스와핑 )을 사용합니다.

라이브 데이터가 아닌 컨텐츠의 스냅 샷입니까?

둘 다입니다. 중단 점에 도달 한 스레드는 일시 중단되므로 일시 중단시 라이브 데이터 (CPU 레지스터 등)의 스냅 샷 및 스레드가 재개 될 경우 프로세서로 복원 할 CPU 레지스터 값 권한 마스터 . 디버거의 사용자 인터페이스를 사용하여 (디버깅중인 프로세스의) CPU 레지스터를 읽거나 변경하는 경우 시스템 호출을 사용하여이 스냅 샷 / 마스터를 읽거나 변경합니다.


답변

엄밀히 말해, 가장 일반적인 경우 gdb 자체는 실행을 일시 중지하지 않습니다. 오히려, gdb는 OS를 요청하고 OS는 실행을 일시 중지합니다.

처음에는 차이가없는 구별처럼 보일 수 있지만 실제로는 차이가 있습니다. 차이점은 이것입니다. 스레드가 실행되도록 예약되지 않은 경우 (예 : 스레드가 실행되도록 예약 된 경우) 스레드의 실행을 일시 중지했다가 다시 시작할 수 있어야하기 때문에이 기능은 이미 일반적인 OS에 내장되어 있습니다. 현재 사용할 수 없음) OS를 예약하여 실행할 수있을 때까지 일시 중지해야합니다.

그렇게하기 위해, OS는 일반적으로 머신의 현재 상태를 저장하기 위해 각 스레드에 따로 설정된 메모리 블록을 가지고 있습니다. 스레드를 일시 중지해야하는 경우 머신의 현재 상태가 해당 영역에 저장됩니다. 스레드를 재개해야하는 경우 머신 상태가 해당 영역에서 복원됩니다.

디버거가 스레드를 일시 중지해야하는 경우 OS는 다른 이유로 스레드를 정확히 동일한 방식으로 일시 중지합니다. 그런 다음 일시 중지 된 스레드의 상태를 읽기 위해 디버거는 스레드의 저장된 상태를 확인합니다. 상태를 수정하면 디버거가 저장된 상태에 기록하고 스레드가 다시 시작될 때 적용됩니다.