Skip to content

Breakpoint

브레이크포인트(breakpoint), 중단점, 중지점은 소프트웨어 개발에서 프로그램을 의도적으로 잠시 또는 아예 멈추게 하는 장소를 가리키며 디버깅 목적으로 넣는 것이다. 대한민국 소프트웨어 개발 커뮤니티에서는 브포로 줄여서 쓰기도 한다.

브레이크포인트는 이미 실행중인 프로그램에 대한 정보를 알아내기 위한 수단으로 사용되며, 이를 이용해 프로그램 실행이 중단되어있는 상황에서 프로그래머는 각종 테스트 환경 (일반 목적의 레지스터, 메모리, 로그, 파일 등)을 점검하여 프로그램이 예측한대로 기능하고 있는지, 그렇지 않을 경우 문제점이 무엇인지 알아낸다. 따라서 브레이크포인트는 원하는 순간에 프로그램 실행을 중단하기 위한 조건을 함께 가질 수 있다.

Soft breakpoints

우리가 debugging 할 때 흔히 쓰는 breakpoint 이다. 1-byte 의 instruction 이다. process 의 실행을 멈추고 control 을 breakpoint exception handler 에 넘겨준다.

One-shot breakpoint
한 번 쓰이고 breakpoint list 에서 사라지는 것
Persistent breakpoint
breakpoint list 에서 저장되어 있고, 계속해서 쓰이는 것

soft breakpoint 를 만들기 위해서는 opcode 를 0xCC 로 바꿔야 한다. 예를 들어, 0x8BC3 (2-byte) 가 있다면 이중에 0x8B 1 byte 를 0xCC, interrupt 3(INT 3) instruction, 로 바꿔야 한다. 이 INT 3 instruction 이 halt CPU 를 하는 명령어 이다.

debug-mode run

우리가 debugger에서 breakpoint 를 설정하고 debug mode 로 실행할 때 이런 일이 일어난다.

  1. breakpoint 를 설정하면, debugger 가 첫byte 를 0xCC 로 바꾸고, 기존에 byte(opcode)는 어딘가에 저장해 놓는다.
  2. debug mode 로 run 을 해서 CPU 가 0xCC 를 만나서 INT3 event 가 발생되면, debugger 가 그 interrupt 를 받게 된다.
  3. 그러면, debugger 가 instruction pointer(EIP register) 가 breakpoint list 에 있는 녀석을 가리키고 있는지를 검사한다.
  4. 그래서 breakpoint list 에 있는 녀석이라면, 아까 저장해 놓은 byte(opcode)를 그 주소(0xCC 가 써져 있는)에 다시 쓰게 된다.(write)
  5. 그래서 유저가 resume을 했을 때 opcode 는 다시 온전하게 수행이 된다.

Hardware breakpoint

적은 수의 breakpoint 로 충분하다면 hardware breakpoint 가 알맞을 수 있다. 그리고 hardware breakpoint 는 soft breakpoint 와 다르게 software 의 변경을 가하지 않는다. soft breakpoint 와 다르게 INT1 event 를 사용한다. 이 INT1 event 는 sigle step event(debugger 에서 next step 을 누를 때) 와 hardware breakpoint 를 위해 쓰인다. hardware breakpoint 는 debug register 라는 것을 이용해 set 하게 된다. 일반적인 CPU 는 debug register(DR) 를 8개 가지고 있다. (DR0~DR7)

  • DR0~DR3 : breakpoint 들의 address 를 저장하기 위해 쓰인다.
  • DR4, DR5 는 예약되어 있고,
  • DR6는 status register 로 사용된다. 이 status register 는 breakpoint 의 type 을 알려준다.
  • DR7 은 on/off switch 역할을 한다. 그리고 다른 breakpoint 의 조건을 저장한다.

8개의 DR중에 DR0~DR3 만 breakpoint 의 address 를 저장하기 때문에, 실제로는 4개의 hardware breakpoint 를 만들 수 있다는 뜻이 된다.

DR7

DR7 에 특정 flag 를 설정해서 다음과 같은 조건에 호출되는 breakpoint 를 만들 수 있다.

  • 특정주소의 instruction 이 수행됐을 때(0x00)
  • data 가 특정 address 에 write 될 때(0x01)
  • 실행되지는 않지만, 특정 주소를 read 나 write 를 할 때(0x11)
  • Bits 0-7 은 DR0-DR3 의 on/off switch 역할을 하고, L, R field 는 scope를 나타낸다. local 인지, global 인지.
    • bit1 은 DR0-local,
    • bit2 는 DR0-global 이런 식으로 switch 역할을 한다.
    • switch 가 on 이 되면 enable 이 되는 것이다.
  • Bit 8-15 는 일반적인 debugging 목적으로 쓰이지 않는다.
  • Bit (16, 17) - (30, 31) 은 DR0-DR3 에 설정된 breakpoint의 Type과 length 를 나타낸다.
    • bit16,17 은 DR0의 type
    • bit18,19는 DR0의 length 이런 식으로 쓰인다.

Memory breakpoint

memory breakpoint 는 실제로 breakpoint 는 아니다. 개인적인 생각에는 우리가 흔히 생각하는 Page Fault 같은 것 같다. memory 의 가장 작은 단위가 memory page 이다. 이 memory page 가 할당될 때, 이 page 는 특정 permission set 을 갖게 된다. 이런 permission 의 종류에는 아래 4가지가 있다.

  • Page execution
  • Page read
  • Page write
  • Guard page

OS 에서 이 permission 들을 page 에 할당하게 된다. page 는 이 permission 을 여러 개 가질 수 있다. 그리고, OS 에서 제공하는 함수를 통해서 이 page 가 어떤 permission 을 가졌는지 query 할 수 있고, permission 을 변경할 수도 있다.

Guard Page

여기서 볼 것은 Guard page 이다.

  • heap 을 stack 에서 분리하는 데에 유용하고, 어떤 한계선이상으로 memory 를 쓰지 않게 할 수 있다.
  • 특정 메모리 영역을 접근했을 때 process 를 멈추는데 유용하다.

예를 들어, network 에 연결된 application 을 우리가 reverse engineering 할 때, packet 을 수신한 메모리 부분에 memory breakpoint(Guard Page) 를 걸어 놓을 수 있다. 이 breakpoint 가 application 이 수신한 packet 내용을 언제, 어떻게 이용되는지 알아낼 수 있게 해 준다. 그 memory page 에 대한 접근은 CPU 를 멈추고, guard page debugging exception 을 발생시킨다. buffer memory 에 접근한 instruction 이 무엇인지를 조사할 수 있고, 무엇을 하는지 알아낼 수 있다.

Soft breakpoint 와 Guard Page

이런 방법을 이용하면, software 를 변경해야 하는 soft breakpoint 의 대신에 사용해서 software 를 변경하지 않고 execution 을 멈출 수 있다.

See also

Favorite site