(hardware) watchpoints and actions

taylor, david david.taylor@emc.com
Thu Nov 12 20:45:00 GMT 2015

    From: duane@duaneellis.com [mailto:duane@duaneellis.com] 

    Two problems you need to address:

    a) Most "gdb-server" type things are rather "dumb" they do not know what symbols are.
        GDB's protocol speaks "address" as an integer like value, not symbolic.
        GDB's protocol has no idea what base+offset might be.
        GDB's protocol has no concept of "stack" or "register" based variables.
        The STUB or GDB-SERVER has no access to the dwarf (or whatever) debug information

Our remote stub does not know the symbols, does not have access to the debug information,
and does not need the symbols nor the debug information.

    Example: A linked list, you want to trace some data element, i.e.: 
    trace( listPtr->Data )

    At the breakpoint:

    The variable: "listPtr" might be on the stack or a register The Element "DATA" is at some base + offset

    Thus you can only trace global variables Secondary problem:  Has the compiler optimization updated the global? Or is it still in the register?

Not true.  The debug information, read by GDB, says where to find the variable.
GDB knows, it's in this register or it's at this offset from this register, or it's at this
memory location.

If you say, "collect listPtr->Data", then GDB knows where listPtr is.  And it knows the
offset of Data relative to the start of the object.  And it knows the size of Data.  It knows
what it needs to know to generate an agent expression.  Look at the command

  maint agent

Similarly, for evaluating without collecting, examine "maint agent-eval".

    How do you plan to solve this? I am also ignoring ENDIAN issues here.

Not an issue and already solved.  Our stubs (both old and new) contain substantial
tracepoint support.  And the tracepoint handling engine contains an agent expression

    b) Something in the target must 'interpret' the series of commands to execute when the watch point hits.

The tracepoint support already contains an agent expression 'interpreter'.

    Your options are: Install a small script interpreter into he gdb-stub/gdb-server This might work for a GDB-SERVER on linux... you have a rich environment.

We already have such an 'interpreter'.  It's been in our stub for more than a decade.
There is also such an 'interpreter' in gdb-server.

    Again - same problems as  above (access to debug information) It does not work well for JTAG type GDB-Servers.

It does not need and does not have access to debug information.  The expressions
that come across contain things like register numbers, constants (offsets, memory
addresses, sizes, whatever), and operators.  It works beautifully.  Look at the agent
expression section (I think it's one of the appendixes)  in the GDB manual.

Our machine has an operating system.  We communicate with our GDB stub via TCP/IP.

    The other option something like GDB-STUBS (rom-monitor based) solution, when the breakpoint/watchpoint exception occurs For example - you could do sometime of JIT compilation, and download code to the target that executes when the exception occurs.

    A simple example might be you insert a "JSR my_bp_handler" at the breakpoint location. 
    That JSR/CALL does something special.

It's an X86-64 processor.  A breakpoint or tracepoint causes an int3 instruction to be inserted.
The operating system invokes a handler for the int3 giving it information such as the address.


    Don't get me wrong, I am very aware of the problem you want to solve, and the challenges A good example might be a PID loop motor control, 100 times a second the CPU calculates new motor control variables and must re-write hardware registers otherwise the motor suddenly stops.

    Other examples might be a network protocol with data flowing... you have overrun and lost packets if you do not respond in time

    What actually works better is a hardware based trace scheme, and that is
    *VERY* chip/silicon/vendor specific.  One example is the ARM STM (system trace macrocell)

The hardware supports trapping on accesses to stub specified addresses.
It only supports a trapping on a small number of data addresses.

The data tracepoint stuff I described works.  It works around GDB rather than
working with GDB.  I'd like it to work with GDB.

    But the code that supports this type of stuff often works better if it is compiled into the actual application, which to some degree violates the "do not ship debug code in production code" rule.

The code *IS* compiled into the application.  The GDB stub is always compiled in.

The stub is NOT debug code.  It enables the developer to examine the system, set
breakpoints, tracepoints, watchpoints, or whatever.

Another rule is to test what you ship.  You don't want to debug with the stub removed. 
And if a problem is found in testing, it's much easier to track it down if the stub is
compiled in.  The stub is always compiled in.  It is part of the shipped product.



More information about the Gdb mailing list