Github Stackoverflow Email

Software developer notes

In this post I will briefly tell about special type of breakpoints, which can greatly improve an ability to debug native code.

Almost every software developer, who worked with an unmanaged code, eventually faced such problems as access violation, stack corruption etc. One of the common reason is the unexpected rewrite of some virtual space's area. You can easily simulate such problem - just rewrite chunk of memory before pointer from malloc, in many implementations count of allocated bytes will be rewritten.

In such cases it would be great if we could set breakpoint which paused program whenever the specified chunk of memory is read/written/executed. Fortunately, the problem has been solved and hardware (data, processor) breakpoints were created. They cause a processor to trace any accesses to specified memory areas. Their usage is not hard, for example from WinDbg you can set them via ba (Break on Access) command, Visual studio debugger supports it too , other debuggers like gdb, lldb are not exceptions.

But in my opinion, the most flexible debugging can be achieved by incorporating hardware breakpoints directly into our code (this is very useful when you want to dynamicaly determine target address of the memory). There are libraries HwBpLib(header only!), hwbp4mw to simplify a work with breakpoints.

Let's take a little look on implementation in order to better understand some peculiarities. On systems like x86, x64 there are special Debug registers to enable tracing of memory accessses. The monitored memory areas are specified in DR0, DR1, DR2, DR3 address-breakpoint registers. As you can guess, the number of hardware breakpoints is limited up to 4. Debug-Control register (DR7) controls conditions of tracing (to check, whether any read or write accesses can trigger breakpoint). Debug-Status register (DR6) provides information about the triggered breakpoint (like the number of the breakpoint).

Besides registers specified above, vendors can provide additional extensions (quite interesting!). So, AMD64 extends DR0-DR3 registers by Address Masking. Special masks may be used to increase the range of breakpoints by excluding adddress bits from the breakpoint match. Also the Control-Transfer breakpoint feature was added. When the feature is enabled, processor keeps information about last branch instructon. You may use this information to better understand the code which caused breakpoint.

C

C++

About me

Hi! I am Alex, the author of this blog. Here are my technical (in the majority) thoughts and stories. I will be hoping that you find this site interesting and fun. Also you can feel free to contact me (support for comments will be added later).