, Guest!
Already a Member? Login or Register.



Main Menu



Login

Username:


Password:




Stay logged in
across browser sessions



Home > Articles > Debugging > Breakpoints by Yash K.S

Breakpoints by Yash K.S


Breakpoints

Posted: March 20th, 2007 @ 4:42am


A breakpoint is a mechanism to pause the program execution for further analysis of a program during runtime. After pausing you can view variable values if they are valid in current context. This will also help you to check CPU registers, call stack, memory dump and other debugger supported features.

There are two types of breakpoint we can set:

  • Hardware driven

  • Software driven

x86 Hardware driven

This provides three methods to pause the execution and allow user to examine the code:

  • INT 3

  • INT 1

  • Debug registers method

INT 3 (0xCC): This is a breakpoint interrupt provided by hardware which allows debugger to implement the handler and allow pausing the execution of code for further analysis. There are 2 ways to use this interrupt:

  • Insert 0xCC opcode inside the source by placing inline code __asm int 3

  • When user places breakpoint using IDE, it can place 0xCC in the place where ever developer sets it, during this method it has to keep original opcode in IDE buffer or some other means. Once debugger gets control, then it will remove 0xCC byte with the original opcode byte which is stored in IDE buffer and resume the execution or allow the user to analyze the runtime code.

INT 1(0xCD01): This is a single step interrupt provided by hardware which allows to implement the handler and allow pausing the execution of code for further analysis. To get control in Single Step handler of debugger, we also need to set a flag of TF(Trap flag) in EFLAGS register.


Once u gain control in handler, you need to reset the TF so that till you set it again it will not call your handler again and again recursively. Once you do all types of processing inside the handler, then you can set it back TF flag to get control for next instruction of a program which you are debugging.


Debug registers:  There are 8 debug registers from DB0 to DB7 and two model specific registers (MSR) and these Debug registers are provided by the hardware itself and CPU will act based on the Flags set in these registers. Debug registers holds the address of memory and I/O locations called breakpoints. These breakpoints are used to selected location in a program, data storage or I/O ports where developer want to pause a program execution and analyze the state of the program with the help of debugger.  


These debug registers are privileged instruction and the modifier code must be running in kernel mode. Hardware provides max only 4 breakpoints (DR0 to DR3).Each of these registers holds a liner address where the program execution should stop.  These debug registers triggering is completely depends on DR6 and DR7 registers. Debuggers either they need to have kernel module to support this feature or Operating system should provide API’s to facilitate to use these hardware provided breakpoints in a Debugger.

DR6 is used as a status registers to mention in what condition respective breakpoint should trigger. None of the flags of this registers will be cleared by CPU, only the callback of exception handler should clear it. Updating of this register happens only when debug exception is generated. This register contains following info:

  • B0 to B3 (Breakpoint condition detected) – Bit 0 to 3. If any of these bit is set, then it assume the respective breakpoint is triggered.

  • BD (debug register detected) – Bit 13. This indicates the next instruction in the execution flow is going to access the debug registers from DR0 to DR7.

  • BS (Single step) – Bit 14. This indicates that debug exception is generation since, TF(Trap flag) is detected in EFLAGS.

  • BT(Task switch) – Bit 15. This indicates that debug exception is triggered from a task switch where TF is set.

DR7 is used as control register. This will enable or disable breakpoint and also sets breakpoint conditions. This register holds following info:

  • L0 thru L3, local breakpoint enable – Bit 0, 2, 4 and 6. Enable the breakpoint for the current task. When breakpoint condition detected a debug exception is generated. CPU automatically clears this flag before switching to new task to avoid unnecessary breakpoint in new task.

  • Go thru G3, global breakpoint – Bit 1,3,5 and 7. Enable a breakpoint for all tasks. When breakpoint is detected, it generates debug exception. CPU will not clear this flag, since it needs to generate breakpoint exception for all tasks.

  • GD, general detect enable – Bit 13. Enabled debug register protection which causes a debug exception before executing any MOV instruction to move data to debug registers.

  • R/W0 thru R/W3 (read/write) - Bit 16, 17, 20, 21, 24, 25, 28 and 29. This flags specifies a condition for each breakpoint. DE(Debug extension) flag in control register CR4 determines how to interpret these flags. When DE flags is set:
    • 00 - Break on instruction execution only
    • 01 - Break on data writes only

    • 10 - Break on I/O reads or writes

    • 11 - Break on data reads or writes but not instruction fetches.

  • LEN0 thru LEN3, length – Bit 18, 19, 22, 23, 26, 27, 30 and 31. These bits helps in identifying the size of memory location specified in breakpoint registers (DR0 to DR3).

    • 00 - 1 byte

    • 01 - 2 byte

    • 10 - undefined

    • 11 - 4 byte


Software driven (Visual C/C++)

Debugger can implement breakpoints in its own style with the help of single step (INT 1) handler. Using the same method they will implement all conditional breakpoints. In each and every instruction they will check the conditions specified by the user and then if condition satisfies it will break it. This will affect the performance a bit since, for each and every instruction it should check for breakpoints and the conditions, but this is OK with the developer, since it is helping him to solve lot of problems.

They can even take help of underlying hardware by using debug registers (DR0 to DR3) Read/Write facility to implement data breakpoints.

 

Visual C++ supports following breakpoints with different conditions:

  • Breaking when it reaches a function: Set a breakpoint for a specific function by providing a full function name. If it’s in C++, then provide along with class name too.

 

 

Line number should be relative to Function. Line number which you provide here should have valid code and you cannot mention to any blank line. You also need to select language if you are debugging program for more then one language.

  • Breaking in a specific Location in a file: You can set a breakpoint to specific line within source file by Inserting Breakpoint and dialog looks like following:

 

Specify source filename along with line number. This line number is relative to source file. You can even specify to take different version of source file for this breakpoint.

 

  • Breaking when it reaches specified Address: You can specify runtime address of a function of any location. To achieve this you start a debugging with some breakpoint, then go to Dissembler window, look for address and Insert Breakpoint.

 

  • Breaking when a specified variables changes: You can specify to break at a specific location based on two conditions "Is TRUE" and "Has Changed".

 

 

If you want to check if some pointer is NULL, then enter expression as “ptrBuff == 0” and check “Is True” option, it breaks it when variable is 0. Enter expression in “Condition” field and check “Has changed” option for breaking into code when expression changes.

 

  • If you have loop and if you want to break inside loop based on pre conditions you can use this option. It provides four options :

    • Break always

    • Break when hit count is equal to “Some number”

    • Break when hit count is multiple of “Some number”

    • Break when hit count is greater or equal to “Some number”

 

 

  • Breakpoint filter based on Machine name, ProcessID, ProcessName, ThreadId, ThreadName with combination of one or more conditons using ||, & and !

 

 

  • You can print TRACE info in debug window along with built-in macro condition. You have option to continue execution automatically or you can execute the macro and break into code.

 

 

 In each of Visual C++ versions the way you invoke these dialog box’s changes. But, it got only above provided options in conditional breakpoint sections.



Copyright © 2005-2008 Yashks.com. All Rights Reserved

Processing Time: 24.9533 seconds.
 
Management Login

Powered By FlexCMS
Powered By FlexCMS