gdbserver: on GDB breakpoint reinsertion, also delete the breakpoint's commands.

If GDB decides to change the breakpoint's conditions or commands,
it'll reinsert the same breakpoint again, with the new options
attached, without deleting the previous breakpoint.  E.g.,

 (gdb) set breakpoint always-inserted on
 (gdb) b main if 0
 Breakpoint 1 at 0x400594: file foo.c, line 21.
 Sending packet: $Z0,400594,1;X3,220027#68...Packet received: OK
 (gdb) b main
 Breakpoint 15 at 0x400594: file foo.c, line 21.
 Sending packet: $Z0,400594,1#49...Packet received: OK

GDBserver understands this and deletes the breakpoint's previous
conditions.  But, it forgets to delete the previous commands.

gdb/gdbserver/
2014-06-02  Pedro Alves  <palves@redhat.com>

	* ax.c (gdb_free_agent_expr): New function.
	* ax.h (gdb_free_agent_expr): New declaration.
	* mem-break.c (delete_gdb_breakpoint_1): Also clear the commands
	list.
	(clear_breakpoint_conditions, clear_breakpoint_commands): Make
	static.
	(clear_breakpoint_conditions_and_commands): New function.
	* mem-break.h (clear_breakpoint_conditions): Delete declaration.
	(clear_breakpoint_conditions_and_commands): New declaration.
This commit is contained in:
Pedro Alves 2014-06-02 22:27:32 +01:00
parent 96ae5695ce
commit 0a261ed82e
6 changed files with 66 additions and 9 deletions

View File

@ -1,3 +1,15 @@
2014-06-02 Pedro Alves <palves@redhat.com>
* ax.c (gdb_free_agent_expr): New function.
* ax.h (gdb_free_agent_expr): New declaration.
* mem-break.c (delete_gdb_breakpoint_1): Also clear the commands
list.
(clear_breakpoint_conditions, clear_breakpoint_commands): Make
static.
(clear_breakpoint_conditions_and_commands): New function.
* mem-break.h (clear_breakpoint_conditions): Delete declaration.
(clear_breakpoint_conditions_and_commands): New declaration.
2014-05-23 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* linux-aarch64-low.c (asm/ptrace.h): Include.

View File

@ -110,6 +110,16 @@ gdb_parse_agent_expr (char **actparm)
return aexpr;
}
void
gdb_free_agent_expr (struct agent_expr *aexpr)
{
if (aexpr != NULL)
{
free (aexpr->bytes);
free (aexpr);
}
}
/* Convert the bytes of an agent expression back into hex digits, so
they can be printed or uploaded. This allocates the buffer,
callers should free when they are done with it. */

View File

@ -58,6 +58,9 @@ struct agent_expr
of bytes in expression, a comma, and then the bytes. */
struct agent_expr *gdb_parse_agent_expr (char **actparm);
/* Release an agent expression. */
void gdb_free_agent_expr (struct agent_expr *aexpr);
/* Convert the bytes of an agent expression back into hex digits, so
they can be printed or uploaded. This allocates the buffer,
callers should free when they are done with it. */

View File

@ -1045,9 +1045,9 @@ delete_gdb_breakpoint_1 (char z_type, CORE_ADDR addr, int size)
if (bp == NULL)
return -1;
/* Before deleting the breakpoint, make sure to free
its condition list. */
clear_breakpoint_conditions (bp);
/* Before deleting the breakpoint, make sure to free its condition
and command lists. */
clear_breakpoint_conditions_and_commands (bp);
err = delete_breakpoint (bp);
if (err != 0)
return -1;
@ -1087,7 +1087,7 @@ delete_gdb_breakpoint (char z_type, CORE_ADDR addr, int size)
/* Clear all conditions associated with a breakpoint. */
void
static void
clear_breakpoint_conditions (struct breakpoint *bp)
{
struct point_cond_list *cond;
@ -1102,8 +1102,7 @@ clear_breakpoint_conditions (struct breakpoint *bp)
struct point_cond_list *cond_next;
cond_next = cond->next;
free (cond->cond->bytes);
free (cond->cond);
gdb_free_agent_expr (cond->cond);
free (cond);
cond = cond_next;
}
@ -1111,6 +1110,38 @@ clear_breakpoint_conditions (struct breakpoint *bp)
bp->cond_list = NULL;
}
/* Clear all commands associated with a breakpoint. */
static void
clear_breakpoint_commands (struct breakpoint *bp)
{
struct point_command_list *cmd;
if (bp->command_list == NULL)
return;
cmd = bp->command_list;
while (cmd != NULL)
{
struct point_command_list *cmd_next;
cmd_next = cmd->next;
gdb_free_agent_expr (cmd->cmd);
free (cmd);
cmd = cmd_next;
}
bp->command_list = NULL;
}
void
clear_breakpoint_conditions_and_commands (struct breakpoint *bp)
{
clear_breakpoint_conditions (bp);
clear_breakpoint_commands (bp);
}
/* Add condition CONDITION to GDBserver's breakpoint BP. */
static void

View File

@ -90,9 +90,10 @@ int breakpoint_here (CORE_ADDR addr);
int breakpoint_inserted_here (CORE_ADDR addr);
/* Clear all breakpoint conditions associated with this address. */
/* Clear all breakpoint conditions and commands associated with a
breakpoint. */
void clear_breakpoint_conditions (struct breakpoint *bp);
void clear_breakpoint_conditions_and_commands (struct breakpoint *bp);
/* Set target-side condition CONDITION to the breakpoint at ADDR.
Returns false on failure. On success, advances CONDITION pointer

View File

@ -3746,7 +3746,7 @@ process_serial_event (void)
here. If we already have a list of parameters, GDB
is telling us to drop that list and use this one
instead. */
clear_breakpoint_conditions (bp);
clear_breakpoint_conditions_and_commands (bp);
process_point_options (bp, &dataptr);
}
}