This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFC] Add task-specific breakpoint capability...
> That's a really good catch - Indeed, I forgot the change in infrun.c.
> And I moved the function declaration from ada-lang.h to breakpoint.h,
> as suggested. Not sure why we put that declaration in ada-lang.h in
> the first place - probably force of habits...
Humpf. Forgot the new patch. Here it is. I'll work on testing (in
particular making sure that the testcase does verify the infrun bit)
and documentation before I check this is in.
--
Joel
commit aa1a55c66239c2ec7b2d90c16e1bf1229b0cf541
Author: Joel Brobecker <brobecker@adacore.com>
Date: Tue Mar 24 11:24:49 2009 -0700
Provide support for (Ada) task-specific breakpoints.
* ada-lang.h (ada_get_task_number): Add declaration.
(breakpoint_ada_task_match): Move declaration to breakpoint.h.
* ada-tasks.c (ada_get_task_number): Make non-static.
* breakpoint.h (struct breakpoint): Add field "task".
(breakpoint_ada_task_match): Add declaration.
* breakpoint.c (breakpoint_ada_task_match): New function.
(print_one_breakpoint_location): Add handling of task-specific
breakpoints.
(create_breakpoint, create_breakpoints, find_condition_and_thread):
New parameter "task".
(break_command_really): Update calls to find_condition_and_thread
and create_breakpoints.
(breakpoint_re_set_one): Update call to find_condition_and_thread.
Set b->task.
* infrun.c (handle_inferior_event): Handle the case where GDB
hits a task-specific breakpoint that was meant for another task.
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 88b6c16..c9554a4 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -461,14 +461,14 @@ extern char *ada_main_name (void);
extern int valid_task_id (int);
+extern int ada_get_task_number (ptid_t);
+
extern void ada_adjust_exception_stop (bpstat bs);
extern void ada_print_exception_stop (bpstat bs);
extern int ada_get_current_task (ptid_t);
-extern int breakpoint_ada_task_match (CORE_ADDR, ptid_t);
-
extern int ada_print_exception_breakpoint_nontask (struct breakpoint *);
extern void ada_print_exception_breakpoint_task (struct breakpoint *);
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index d0ce5ab..4f0aaf5 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -160,7 +160,7 @@ static int stale_task_list_p = 1;
/* Return the task number of the task whose ptid is PTID, or zero
if the task could not be found. */
-static int
+int
ada_get_task_number (ptid_t ptid)
{
int i;
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 7e50342..5114ae7 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -1919,6 +1919,32 @@ breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid)
return 0;
}
+
+/* Return true if the breakpoint at PC is valid for the Ada task identified
+ by its PTID. */
+
+int
+breakpoint_ada_task_match (CORE_ADDR pc, ptid_t ptid)
+{
+ struct bp_location *bpt;
+ int taskid = ada_get_task_number (ptid);
+
+ ALL_BP_LOCATIONS (bpt)
+ {
+ if ((bpt->loc_type == bp_loc_software_breakpoint
+ || bpt->loc_type == bp_loc_hardware_breakpoint)
+ && (bpt->owner->enable_state == bp_enabled
+ || bpt->owner->enable_state == bp_permanent)
+ && bpt->address == pc
+ && (bpt->owner->task == 0 || bpt->owner->task == taskid))
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/* bpstat stuff. External routines' interfaces are documented
@@ -3556,12 +3582,20 @@ print_one_breakpoint_location (struct breakpoint *b,
break;
}
- if (!part_of_multiple && b->thread != -1)
+ if (!part_of_multiple)
{
- /* FIXME: This seems to be redundant and lost here; see the
- "stop only in" line a little further down. */
- ui_out_text (uiout, " thread ");
- ui_out_field_int (uiout, "thread", b->thread);
+ if (b->thread != -1)
+ {
+ /* FIXME: This seems to be redundant and lost here; see the
+ "stop only in" line a little further down. */
+ ui_out_text (uiout, " thread ");
+ ui_out_field_int (uiout, "thread", b->thread);
+ }
+ else if (b->task != 0)
+ {
+ ui_out_text (uiout, " task ");
+ ui_out_field_int (uiout, "task", b->task);
+ }
}
ui_out_text (uiout, "\n");
@@ -5113,7 +5147,7 @@ static void
create_breakpoint (struct symtabs_and_lines sals, char *addr_string,
char *cond_string,
enum bptype type, enum bpdisp disposition,
- int thread, int ignore_count,
+ int thread, int task, int ignore_count,
struct breakpoint_ops *ops, int from_tty, int enabled)
{
struct breakpoint *b = NULL;
@@ -5145,6 +5179,7 @@ create_breakpoint (struct symtabs_and_lines sals, char *addr_string,
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
b->thread = thread;
+ b->task = task;
b->cond_string = cond_string;
b->ignore_count = ignore_count;
@@ -5323,7 +5358,7 @@ static void
create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
char *cond_string,
enum bptype type, enum bpdisp disposition,
- int thread, int ignore_count,
+ int thread, int task, int ignore_count,
struct breakpoint_ops *ops, int from_tty,
int enabled)
{
@@ -5335,7 +5370,7 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
create_breakpoint (expanded, addr_string[i],
cond_string, type, disposition,
- thread, ignore_count, ops, from_tty, enabled);
+ thread, task, ignore_count, ops, from_tty, enabled);
}
update_global_location_list (1);
@@ -5442,7 +5477,7 @@ do_captured_parse_breakpoint (struct ui_out *ui, void *data)
If no thread is found, *THREAD is set to -1. */
static void
find_condition_and_thread (char *tok, CORE_ADDR pc,
- char **cond_string, int *thread)
+ char **cond_string, int *thread, int *task)
{
*cond_string = NULL;
*thread = -1;
@@ -5485,6 +5520,18 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
if (!valid_thread_id (*thread))
error (_("Unknown thread %d."), *thread);
}
+ else if (toklen >= 1 && strncmp (tok, "task", toklen) == 0)
+ {
+ char *tmptok;
+
+ tok = end_tok + 1;
+ tmptok = tok;
+ *task = strtol (tok, &tok, 0);
+ if (tok == tmptok)
+ error (_("Junk after task keyword."));
+ if (!valid_task_id (*task))
+ error (_("Unknown task %d\n"), *task);
+ }
else
error (_("Junk at end of arguments."));
}
@@ -5523,6 +5570,7 @@ break_command_really (char *arg, char *cond_string, int thread,
int i;
int pending = 0;
int not_found = 0;
+ int task = 0;
sals.sals = NULL;
sals.nelts = 0;
@@ -5624,7 +5672,8 @@ break_command_really (char *arg, char *cond_string, int thread,
re-parse it in context of each sal. */
cond_string = NULL;
thread = -1;
- find_condition_and_thread (arg, sals.sals[0].pc, &cond_string, &thread);
+ find_condition_and_thread (arg, sals.sals[0].pc, &cond_string,
+ &thread, &task);
if (cond_string)
make_cleanup (xfree, cond_string);
}
@@ -5641,7 +5690,7 @@ break_command_really (char *arg, char *cond_string, int thread,
hardwareflag ? bp_hardware_breakpoint
: bp_breakpoint,
tempflag ? disp_del : disp_donttouch,
- thread, ignore_count, ops, from_tty, enabled);
+ thread, task, ignore_count, ops, from_tty, enabled);
}
else
{
@@ -7480,11 +7529,14 @@ breakpoint_re_set_one (void *bint)
{
char *cond_string = 0;
int thread = -1;
+ int task = 0;
+
find_condition_and_thread (s, sals.sals[0].pc,
- &cond_string, &thread);
+ &cond_string, &thread, &task);
if (cond_string)
b->cond_string = cond_string;
b->thread = thread;
+ b->task = task;
b->condition_not_parsed = 0;
}
expanded = expand_line_sal_maybe (sals.sals[0]);
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 94287de..3e8e69e 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -423,9 +423,12 @@ struct breakpoint
hardware. */
enum watchpoint_triggered watchpoint_triggered;
- /* Thread number for thread-specific breakpoint, or -1 if don't care */
+ /* Thread number for thread-specific breakpoint, or -1 if don't care. */
int thread;
+ /* Ada task number for task-specific breakpoint, or 0 if don't care. */
+ int task;
+
/* Count of the number of times this breakpoint was taken, dumped
with the info, but not used for anything else. Useful for
seeing how many times you hit a break prior to the program
@@ -668,6 +671,8 @@ extern int software_breakpoint_inserted_here_p (CORE_ADDR);
extern int breakpoint_thread_match (CORE_ADDR, ptid_t);
+extern int breakpoint_ada_task_match (CORE_ADDR, ptid_t);
+
extern void until_break_command (char *, int, int);
extern void breakpoint_re_set (void);
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 6600bbb..43d0404 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -2633,7 +2633,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
if (regular_breakpoint_inserted_here_p (stop_pc))
{
ecs->random_signal = 0;
- if (!breakpoint_thread_match (stop_pc, ecs->ptid))
+ if (!breakpoint_thread_match (stop_pc, ecs->ptid)
+ || !breakpoint_ada_task_match (stop_pc, ecs->ptid))
thread_hop_needed = 1;
}
else if (singlestep_breakpoints_inserted_p)