2004-09-12 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 0fd4d23e41c1f9d6a313082a1ff5561281b3a495..c5e8ddd091240c7ef8c76be21b393013a6f3cd8e 100644 (file)
@@ -49,6 +49,8 @@
 #include "cli/cli-script.h"
 #include "gdb_assert.h"
 #include "block.h"
+#include "solist.h"
+#include "observer.h"
 
 #include "gdb-events.h"
 
@@ -627,7 +629,7 @@ commands_command (char *arg, int from_tty)
    shadow contents, not the breakpoints themselves.  From breakpoint.c.  */
 
 int
-read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
+deprecated_read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
 {
   int status;
   struct bp_location *b;
@@ -695,7 +697,7 @@ read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
       if (bp_addr > memaddr)
        {
          /* Copy the section of memory before the breakpoint.  */
-         status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
+         status = deprecated_read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
          if (status != 0)
            return status;
        }
@@ -703,7 +705,7 @@ read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
       if (bp_addr + bp_size < memaddr + len)
        {
          /* Copy the section of memory after the breakpoint.  */
-         status = read_memory_nobpt (bp_addr + bp_size,
+         status = deprecated_read_memory_nobpt (bp_addr + bp_size,
                                      myaddr + bp_addr + bp_size - memaddr,
                                      memaddr + len - (bp_addr + bp_size));
          if (status != 0)
@@ -1767,37 +1769,6 @@ software_breakpoint_inserted_here_p (CORE_ADDR pc)
   return 0;
 }
 
-/* Return nonzero if FRAME is a dummy frame.  We can't use
-   DEPRECATED_PC_IN_CALL_DUMMY because figuring out the saved SP would
-   take too much time, at least using frame_register() on the 68k.
-   This means that for this function to work right a port must use the
-   bp_call_dummy breakpoint.  */
-
-int
-deprecated_frame_in_dummy (struct frame_info *frame)
-{
-  struct breakpoint *b;
-
-  /* This function is used by two files: get_frame_type(), after first
-     checking that !DEPRECATED_USE_GENERIC_DUMMY_FRAMES; and
-     sparc-tdep.c, which doesn't yet use generic dummy frames anyway.  */
-  gdb_assert (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES);
-
-  ALL_BREAKPOINTS (b)
-  {
-    if (b->type == bp_call_dummy
-       && frame_id_eq (b->frame_id, get_frame_id (frame))
-    /* We need to check the PC as well as the frame on the sparc,
-       for signals.exp in the testsuite.  */
-       && (get_frame_pc (frame)
-           >= (b->loc->address
-               - DEPRECATED_SIZEOF_CALL_DUMMY_WORDS / sizeof (LONGEST) * DEPRECATED_REGISTER_SIZE))
-       && get_frame_pc (frame) <= b->loc->address)
-      return 1;
-  }
-  return 0;
-}
-
 /* breakpoint_thread_match (PC, PTID) returns true if the breakpoint at
    PC is valid for process/thread PTID.  */
 
@@ -2590,7 +2561,9 @@ which its expression is valid.\n");
 }
 
 /* Get a bpstat associated with having just stopped at address
-   BP_ADDR.  */
+   BP_ADDR in thread PTID.  STOPPED_BY_WATCHPOINT is 1 if the
+   target thinks we stopped due to a hardware watchpoint, 0 if we
+   know we did not trigger a hardware watchpoint, and -1 if we do not know.  */
 
 /* Determine whether we stopped at a breakpoint, etc, or whether we
    don't understand this stop.  Result is a chain of bpstat's such that:
@@ -2607,7 +2580,7 @@ which its expression is valid.\n");
    commands, FIXME??? fields.  */
 
 bpstat
-bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
+bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid, int stopped_by_watchpoint)
 {
   struct breakpoint *b, *temp;
   /* True if we've hit a breakpoint (as opposed to a watchpoint).  */
@@ -2623,15 +2596,10 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
     if (!breakpoint_enabled (b) && b->enable_state != bp_permanent)
       continue;
 
-    /* Hardware watchpoints are treated as non-existent if the reason we 
-       stopped wasn't a hardware watchpoint (we didn't stop on some data 
-       address).  Otherwise gdb won't stop on a break instruction in the code
-       (not from a breakpoint) when a hardware watchpoint has been defined.  */
     if (b->type != bp_watchpoint
-       && !((b->type == bp_hardware_watchpoint
-             || b->type == bp_read_watchpoint
-             || b->type == bp_access_watchpoint)
-            && target_stopped_data_address () != 0)
+       && b->type != bp_hardware_watchpoint
+       && b->type != bp_read_watchpoint
+       && b->type != bp_access_watchpoint
        && b->type != bp_hardware_breakpoint
        && b->type != bp_catch_fork
        && b->type != bp_catch_vfork
@@ -2647,6 +2615,18 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
          continue;
       }
 
+    /* Continuable hardware watchpoints are treated as non-existent if the 
+       reason we stopped wasn't a hardware watchpoint (we didn't stop on 
+       some data address).  Otherwise gdb won't stop on a break instruction 
+       in the code (not from a breakpoint) when a hardware watchpoint has 
+       been defined.  */
+
+    if ((b->type == bp_hardware_watchpoint
+        || b->type == bp_read_watchpoint
+        || b->type == bp_access_watchpoint)
+       && !stopped_by_watchpoint)
+      continue;
+
     if (b->type == bp_hardware_breakpoint)
       {
        if (b->loc->address != bp_addr)
@@ -3945,8 +3925,8 @@ breakpoint_adjustment_warning (CORE_ADDR from_addr, CORE_ADDR to_addr,
   char astr1[40];
   char astr2[40];
 
-  strcpy (astr1, local_hex_string_custom ((unsigned long) from_addr, "08l"));
-  strcpy (astr2, local_hex_string_custom ((unsigned long) to_addr, "08l"));
+  strcpy (astr1, hex_string_custom ((unsigned long) from_addr, 8));
+  strcpy (astr2, hex_string_custom ((unsigned long) to_addr, 8));
   if (have_bnum)
     warning ("Breakpoint %d address previously adjusted from %s to %s.",
              bnum, astr1, astr2);
@@ -4280,7 +4260,7 @@ create_thread_event_breakpoint (CORE_ADDR address)
   
   b->enable_state = bp_enabled;
   /* addr_string has to be used or breakpoint_re_set will delete me.  */
-  xasprintf (&b->addr_string, "*0x%s", paddr (b->loc->address));
+  b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
 
   return b;
 }
@@ -4410,6 +4390,46 @@ disable_breakpoints_in_shlibs (int silent)
   }
 }
 
+/* Disable any breakpoints that are in in an unloaded shared library.  Only
+   apply to enabled breakpoints, disabled ones can just stay disabled.  */
+
+void
+disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
+{
+  struct breakpoint *b;
+  int disabled_shlib_breaks = 0;
+
+#if defined (PC_SOLIB)
+  /* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK.  */
+  ALL_BREAKPOINTS (b)
+  {
+    if ((b->loc->loc_type == bp_loc_hardware_breakpoint
+       || b->loc->loc_type == bp_loc_software_breakpoint)
+       && breakpoint_enabled (b) 
+       && !b->loc->duplicate)
+      {
+       char *so_name = PC_SOLIB (b->loc->address);
+       if (so_name 
+           && !strcmp (so_name, solib->so_name))
+          {
+           b->enable_state = bp_shlib_disabled;
+           /* At this point, we cannot rely on remove_breakpoint
+              succeeding so we must mark the breakpoint as not inserted
+              to prevent future errors occurring in remove_breakpoints.  */
+           b->loc->inserted = 0;
+           if (!disabled_shlib_breaks)
+             {
+               target_terminal_ours_for_output ();
+               warning ("Temporarily disabling breakpoints for unloaded shared library \"%s\"",
+                         so_name);
+             }
+           disabled_shlib_breaks = 1;
+         }
+      }
+  }
+#endif
+}
+
 /* Try to reenable any breakpoints in shared libraries.  */
 void
 re_enable_breakpoints_in_shlibs (void)
@@ -4924,7 +4944,7 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
        else
          /* addr_string has to be used or breakpoint_re_set will delete
             me.  */
-         xasprintf (&b->addr_string, "*0x%s", paddr (b->loc->address));
+         b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
        b->cond_string = cond_string[i];
        b->ignore_count = ignore_count;
        b->enable_state = bp_enabled;
@@ -4948,6 +4968,10 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
               be copied too.  */
            if (pending_bp->commands)
              b->commands = copy_command_lines (pending_bp->commands);
+           
+           /* We have to copy over the ignore_count and thread as well.  */
+           b->ignore_count = pending_bp->ignore_count;
+           b->thread = pending_bp->thread;
          }
        mention (b);
       }
@@ -5051,7 +5075,8 @@ breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
 
          Give the target a chance to bless sals.sals[i].pc before we
          try to make a breakpoint for it. */
-      if (PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
+#ifdef DEPRECATED_PC_REQUIRES_RUN_BEFORE_USE
+      if (DEPRECATED_PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
        {
          if (address == NULL)
            error ("Cannot break without a running program.");
@@ -5059,6 +5084,7 @@ breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
            error ("Cannot break on %s without a running program.", 
                   address);
        }
+#endif
     }
 }
 
@@ -7116,6 +7142,8 @@ breakpoint_re_set_one (void *bint)
   struct breakpoint *b = (struct breakpoint *) bint;
   struct value *mark;
   int i;
+  int not_found;
+  int *not_found_ptr = NULL;
   struct symtabs_and_lines sals;
   char *s;
   enum enable_state save_enable;
@@ -7166,11 +7194,19 @@ breakpoint_re_set_one (void *bint)
       save_enable = b->enable_state;
       if (b->enable_state != bp_shlib_disabled)
         b->enable_state = bp_disabled;
+      else
+       /* If resetting a shlib-disabled breakpoint, we don't want to
+          see an error message if it is not found since we will expect
+          this to occur until the shared library is finally reloaded.
+          We accomplish this by giving decode_line_1 a pointer to use
+          for silent notification that the symbol is not found.  */
+       not_found_ptr = &not_found;
 
       set_language (b->language);
       input_radix = b->input_radix;
       s = b->addr_string;
-      sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL, NULL);
+      sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL,
+                           not_found_ptr);
       for (i = 0; i < sals.nelts; i++)
        {
          resolve_sal_pc (&sals.sals[i]);
@@ -7771,6 +7807,10 @@ _initialize_breakpoint (void)
   static struct cmd_list_element *breakpoint_show_cmdlist;
   struct cmd_list_element *c;
 
+#ifdef SOLIB_ADD
+  observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
+#endif
+
   breakpoint_chain = 0;
   /* Don't bother to call set_breakpoint_count.  $bpnum isn't useful
      before a breakpoint is set.  */
@@ -8084,7 +8124,7 @@ such is available.  (However, any hardware watchpoints that were\n\
 created before setting this to nonzero, will continue to use watchpoint\n\
 hardware.)",
                   &setlist);
-  add_show_from_set (c, &showlist);
+  deprecated_add_show_from_set (c, &showlist);
 
   can_use_hw_watchpoints = 1;
 
@@ -8102,16 +8142,13 @@ pending breakpoint behavior",
                  0/*allow-unknown*/, &showlist);
 
   add_setshow_auto_boolean_cmd ("pending", no_class, &pending_break_support, "\
-Set debugger's behavior regarding pending breakpoints.\n\
-If on, an unrecognized breakpoint location will cause gdb to create a\n\
-pending breakpoint.  If off, an unrecognized breakpoint location results in\n\
-an error.  If auto, an unrecognized breakpoint location results in a\n\
-user-query to see if a pending breakpoint should be created.","\
-Show debugger's behavior regarding pending breakpoints.\n\
+Set debugger's behavior regarding pending breakpoints.", "\
+Show debugger's behavior regarding pending breakpoints.", "\
 If on, an unrecognized breakpoint location will cause gdb to create a\n\
 pending breakpoint.  If off, an unrecognized breakpoint location results in\n\
 an error.  If auto, an unrecognized breakpoint location results in a\n\
-user-query to see if a pending breakpoint should be created.",
+user-query to see if a pending breakpoint should be created.", "\
+Debugger's behavior regarding pending breakpoints is %s.",
                                NULL, NULL,
                                &breakpoint_set_cmdlist,
                                &breakpoint_show_cmdlist);
This page took 0.027197 seconds and 4 git commands to generate.