diff options
author | Luis Machado <luisgpm@br.ibm.com> | 2012-02-24 15:15:56 +0000 |
---|---|---|
committer | Luis Machado <luisgpm@br.ibm.com> | 2012-02-24 15:15:56 +0000 |
commit | 9f3a5c850eddd9e804c20a9c664e90b9e3d14140 (patch) | |
tree | 4beed3e5c90d5fcdf9bb8313cf056617828da55f /gdb/gdbserver/server.c | |
parent | 9f14eebc6a9d99804ad44f4f6084b7f279f488df (diff) | |
download | gdb-9f3a5c850eddd9e804c20a9c664e90b9e3d14140.zip gdb-9f3a5c850eddd9e804c20a9c664e90b9e3d14140.tar.gz gdb-9f3a5c850eddd9e804c20a9c664e90b9e3d14140.tar.bz2 |
2012-02-24 Luis Machado <lgustavo@codesourcery>
* server.c (handle_query): Advertise support for target-side
breakpoint condition evaluation.
(process_point_options): New function.
(process_serial_event): When inserting a breakpoint, check for
a target-side condition that should be evaluated.
* mem-break.c: Include regcache.h and ax.h.
(point_cond_list_t): New data structure.
(breakpoint) <cond_list>: New field.
(find_gdb_breakpoint_at): Make non-static.
(delete_gdb_breakpoint_at): Clear any target-side
conditions.
(clear_gdb_breakpoint_conditions): New function.
(add_condition_to_breakpoint): Likewise.
(add_breakpoint_condition): Likewise.
(gdb_condition_true_at_breakpoint): Likewise.
(gdb_breakpoint_here): Return result directly instead
of going through a local variable.
* mem-break.h (find_gdb_breakpoint_at): New prototype.
(clear_gdb_breakpoint_conditions): Likewise.
(add_breakpoint_condition): Likewise.
(gdb_condition_true_at_breakpoint): Likewise.
* linux-low.c (linux_wait_1): Evaluate target-side breakpoint condition.
(need_step_over_p): Take target-side breakpoint condition into
consideration.
Diffstat (limited to 'gdb/gdbserver/server.c')
-rw-r--r-- | gdb/gdbserver/server.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 37dc8d1..e3d1f7c 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -1621,6 +1621,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) strcat (own_buf, ";tracenz+"); } + /* Support target-side breakpoint conditions. */ + strcat (own_buf, ";ConditionalBreakpoints+"); + return; } @@ -2825,6 +2828,43 @@ main (int argc, char *argv[]) } } +/* Process options coming from Z packets for *point at address + POINT_ADDR. PACKET is the packet buffer. *PACKET is updated + to point to the first char after the last processed option. */ + +static void +process_point_options (CORE_ADDR point_addr, char **packet) +{ + char *dataptr = *packet; + + /* Check if data has the correct format. */ + if (*dataptr != ';') + return; + + dataptr++; + + while (*dataptr) + { + switch (*dataptr) + { + case 'X': + /* Conditional expression. */ + fprintf (stderr, "Found breakpoint condition.\n"); + add_breakpoint_condition (point_addr, &dataptr); + break; + default: + /* Unrecognized token, just skip it. */ + fprintf (stderr, "Unknown token %c, ignoring.\n", + *dataptr); + } + + /* Skip tokens until we find one that we recognize. */ + while (*dataptr && *dataptr != 'X' && *dataptr != ';') + dataptr++; + } + *packet = dataptr; +} + /* Event loop callback that handles a serial event. The first byte in the serial buffer gets us here. We expect characters to arrive at a brisk pace, so we read the rest of the packet with a blocking @@ -3147,7 +3187,22 @@ process_serial_event (void) case '4': /* access watchpoint */ require_running (own_buf); if (insert && the_target->insert_point != NULL) - res = (*the_target->insert_point) (type, addr, len); + { + /* Insert the breakpoint. If it is already inserted, nothing + will take place. */ + res = (*the_target->insert_point) (type, addr, len); + + /* GDB may have sent us a list of *point parameters to be + evaluated on the target's side. Read such list here. If we + already have a list of parameters, GDB is telling us to drop + that list and use this one instead. */ + if (!res && (type == '0' || type == '1')) + { + /* Remove previous conditions. */ + clear_gdb_breakpoint_conditions (addr); + process_point_options (addr, &dataptr); + } + } else if (!insert && the_target->remove_point != NULL) res = (*the_target->remove_point) (type, addr, len); break; |