This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]