Пример #1
0
int
set_gdb_breakpoint_at (CORE_ADDR where)
{
  struct breakpoint *bp;

  if (breakpoint_data == NULL)
    return 1;

  /* If we see GDB inserting a second breakpoint at the same address,
     then the first breakpoint must have disappeared due to a shared
     library unload.  On targets where the shared libraries are
     handled by userspace, like SVR4, for example, GDBserver can't
     tell if a library was loaded or unloaded.  Since we refcount
     breakpoints, if we didn't do this, we'd just increase the
     refcount of the previous breakpoint at this address, but the trap
     was not planted in the inferior anymore, thus the breakpoint
     would never be hit.  */
  bp = find_gdb_breakpoint_at (where);
  if (bp != NULL)
    {
      delete_gdb_breakpoint_at (where);

      /* Might as well validate all other breakpoints.  */
      validate_breakpoints ();
    }

  bp = set_breakpoint_at (where, NULL);
  if (bp == NULL)
    return -1;

  bp->type = gdb_breakpoint;
  return 0;
}
Пример #2
0
static struct breakpoint *
set_gdb_breakpoint_1 (char z_type, CORE_ADDR addr, int size, int *err)
{
  struct breakpoint *bp;
  enum bkpt_type type;
  enum raw_bkpt_type raw_type;

  /* If we see GDB inserting a second code breakpoint at the same
     address, then either: GDB is updating the breakpoint's conditions
     or commands; or, the first breakpoint must have disappeared due
     to a shared library unload.  On targets where the shared
     libraries are handled by userspace, like SVR4, for example,
     GDBserver can't tell if a library was loaded or unloaded.  Since
     we refcount raw breakpoints, we must be careful to make sure GDB
     breakpoints never contribute more than one reference.  if we
     didn't do this, in case the previous breakpoint is gone due to a
     shared library unload, we'd just increase the refcount of the
     previous breakpoint at this address, but the trap was not planted
     in the inferior anymore, thus the breakpoint would never be hit.
     Note this must be careful to not create a window where
     breakpoints are removed from the target, for non-stop, in case
     the target can poke at memory while the program is running.  */
  if (z_type == Z_PACKET_SW_BP
      || z_type == Z_PACKET_HW_BP)
    {
      bp = find_gdb_breakpoint (z_type, addr, -1);

      if (bp != NULL)
	{
	  if (bp->raw->size != size)
	    {
	      /* A different size than previously seen.  The previous
		 breakpoint must be gone then.  */
	      bp->raw->inserted = -1;
	      delete_breakpoint (bp);
	      bp = NULL;
	    }
	  else if (z_type == Z_PACKET_SW_BP)
	    {
	      /* Check if the breakpoint is actually gone from the
		 target, due to an solib unload, for example.  Might
		 as well validate _all_ breakpoints.  */
	      validate_breakpoints ();

	      /* Breakpoints that don't pass validation are
		 deleted.  */
	      bp = find_gdb_breakpoint (z_type, addr, -1);
	    }
	}
    }
  else
    {
      /* Data breakpoints for the same address but different size are
	 expected.  GDB doesn't merge these.  The backend gets to do
	 that if it wants/can.  */
      bp = find_gdb_breakpoint (z_type, addr, size);
    }

  if (bp != NULL)
    {
      /* We already know about this breakpoint, there's nothing else
	 to do - GDB's reference is already accounted for.  Note that
	 whether the breakpoint inserted is left as is - we may be
	 stepping over it, for example, in which case we don't want to
	 force-reinsert it.  */
      return bp;
    }

  raw_type = Z_packet_to_raw_bkpt_type (z_type);
  type = Z_packet_to_bkpt_type (z_type);
  return set_breakpoint (type, raw_type, addr, size, NULL, err);
}