facilities for x86 debugging introduction to pentium features that can assist programmers in their...

24
Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Post on 18-Dec-2015

229 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Facilities for x86 debugging

Introduction to Pentium features that can assist programmers in

their debugging of software

Page 2: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Any project ‘bugs’?

• As you work on designing your solution for the programming assignment in Project #1 it is possible (likely?) that you may run into some program failures

• What can you do if your program doesn’t behave as you had expected it world?

• How can you diagnose the causes?

• Where does your problem first appear?

Page 3: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Single-stepping

• An ability to trace through your program’s code, one instruction at a time, often can be extremely helpful in identifying where a program flaw is occurring – and also why

• The Pentium processor provides hardware assistance in implementing a ‘debugging’ capability such as ‘single-steping’.

Page 4: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

RF

The EFLAGS register

TF

816

RF = RESUME flag (bit 16) By setting this flag-bit in the EFLAGS register-image that got saved on the stack, the ‘iret’ instruction will be inhibited from generating yet another CPU exception

TF = TRAP flag (bit 8) By setting this flag-bit in the EFLAGS register-image that gets saved on the stack when ‘pushfl’ was executed, and then executing ‘popfl’, the CPU will begin executing a ‘single-step’ exception after each instruction-executes

Page 5: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

TF-bit in EFLAGS

• Our ‘trydebug.s’ demo shows how to use the TF-bit to perform ‘single-stepping’ of a Linux application program (e.g., ‘hello’)

• The ‘popfl’ instruction is used to set TF

• The exception-handler for INT-1 displays information about the state of the task

• But single-stepping starts only AFTER the immediately following instruction executes

Page 6: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

How to do it

• Here’s a code-fragment that we could use to initiate single-stepping from the start of our ‘ring3’ application-progam:

pushw $userSS # selector for ring3 stack-segmentpushw $userTOS # offset for ring3 ‘top-of-stack’ pushw $userCS # selector for ring3 code-segmentpushw $0 # offset for the ring3 entry-point

pushfl # push current EFLAGSbtsl $8, (%esp) # set image of the TF-bitpopfl # modify EFLAGS to set TFlret # transfer to ring3 application

Page 7: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Using ‘objdump’ output

• You can generate an assembler ‘listing’ of the instructions in our ‘hello’ application

• You can then use the listing to follow along with the ‘single-stepping’ through that code

• Here’s how to do it:

$ objdump –d hello > hello.u

• (The ‘-d’ option stands for ‘disassembly’)

Page 8: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

A slight ‘flaw’

• We cannot single-step the execution of an ‘int-0x80’ instruction (Linux’s system-calls)

• Our exception-handler’s ‘iret’ instruction will restore the TF-bit to EFLAGS, but the single-step ‘trap’ doesn’t take effect until after the immediately following instruction

• This means we ‘skip’ seeing a display of the registers immediately after ‘int-0x80’

Page 9: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Fixing that ‘flaw’

• The Pentium offers a way to overcome the problem of a delayed effect when TF is set

• We can use the Debug Registers to set an instruction ‘breakpoint’ which will interrupt the CPU at a specific instruction-address

• There are six Debug Registers:DR0, DR1, DR2, DR3 (breakpoints)DR6 (the Debug Status register)DR7 (the Debug Control register)

Page 10: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Breakpoint Address Registers

DR0

DR1

DR2

DR3

Page 11: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Special ‘MOV’ instructions

• Use ‘mov %reg, %DRn’ to write into DRn

• Use ‘mov %DRn, %reg’ to read from DRn

• Here ‘reg’ stands for any one of the CPU’s general-purpose registers (e.g., EAX, etc.)

• These instructions are ‘privileged’ (i.e., can only be executed by code running in ring0)

Page 12: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Debug Control Register (DR7)

0 0GD

0 0 1GE

LE

G3

L3

G2

L2

G1

L1

G0

L0

LEN3

R/W3

LEN2

R/W2

LEN1

R/W1

LEN0

R/W0

15 0

31 16

Least significant word

Most significant word

Page 13: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

What kinds of breakpoints?

LEN R/W

LEN 00 = one byte 01 = two bytes 10 = undefined 11 = four bytes

R/W 00 = break on instruction fetch only 01 = break on data writes only 10 = undefined (unless DE set in CR4) 11 = break on data reads or writes (but

not on instruction fetches)

Page 14: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Control Register 4

• The Pentium uses Control Register 4 to activate certain extended features of the processor, while still allowing for backward compatibility of software written for earlier Intel x86 processors

• An example: Debug Extensions (DE-bit)

other feature bitsCR4 DE

331 0

Page 15: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Debug Status Register (DR6)

BD

0 1 1 1 1 1 1 1B3

B2

B1

unused ( all bits here are set to 1 )

15 0

31 16

Least significant word

Most significant word

BS

BT

1B0

Page 16: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Where to set a breakpoint

• Suppose you want to trigger a ‘debug’ trap at the instruction immediately following the Linux software ‘int $0x80’ system-call

• Your debug exception-handler can use the saved CS:EIP values on its stack to check that ‘int $0x80’ has caused an exception

• Machine-code is: 0xCD, 0x80 (2 bytes)

• So set a ‘breakpoint’ at address EIP+2

Page 17: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

How to set this breakpoint

isrDBG: push %ebp

mov %esp, %ebp

pushal

# put breakpoint-address in DR0

mov 4(%ebp), %eax

add $2, %eax

mov %eax, %dr0

Page 18: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Setting a breakpoint (continued)

# enable local breakpoint for DR0mov %dr7, %eaxbts $0, %eax # set LE0mov %eax, %dr7…popalpop %ebpiret

Page 19: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Detecting a ‘breakpoint’

• Your debug exception-handler can read DR6 to check for any occurrences of breakpoints

mov %dr6, %eax ; get debug status

bt $0, %eax ; breakpoint #0?

jnc notBP0 ; no, another cause

bts $16, 12(%ebp) ; set the RF-bit

# or disable breakpoint0 in register DR7

notBP0:

Page 20: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

In-class exercise #1

• Our ‘trydebug.s’ demo illustrates the idea of single-stepping through a program, but after several steps it encounter a General Protection Exception (i.e., interrupt $0x0D)

• You will recognize a display of information from registers that gets saved on the stack

• Can you determine why this fault occurs, and then modify our code to eliminate it?

Page 21: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

The unlabeled stack layout

• Our ‘isrGPF’ handler doesn’t label its info:----- ES----- DS

EDI ESI

EBP ESP EBX EDX ECX EAX

error-code EIP

----- CSEFLAGS

Page 22: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

Intel x86 instruction-format

• Intel’s instructions vary in length from 1 to 15 bytes, and are comprised of five fields:

instructionprefixes

0,1,2 or 3 bytes

opcodefield

1 or 2 bytes

addressingmode field

0, 1 or 2 bytes

addressdisplacement

0, 1, 2 or 4 bytes

immediatedata

0, 1, 2 or 4 bytes

Maximum number of bytes = 15

Page 23: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

A few examples

• 1-byte instruction: in %dx, %al• 2-byte instruction: int $0x16• A prefixed instruction: rep movsb• And here’s a 12-byte instruction:

cmpl $0, %fs:0x400(%ebx, %edi, 2)– 1 prefix byte– 1 opcode byte– 2 address-mode bytes– 4 address-displacement bytes– 4 immediate-data bytes

Page 24: Facilities for x86 debugging Introduction to Pentium features that can assist programmers in their debugging of software

In-class exercise #2

• Modify the debug exception-handler in our ‘trydebug.s’ demo-program so it will use a different Debug Register (i.e.,, DR1, DR2, or DR3) to set an instruction-breakpoint at the entry-point to your ‘int $0x80’ system-service interrupt-routine (i.e., at ‘isrDBG’)

• This can allow you to do single-stepping of your system-call handlers (e.g., ‘do_write’)