This is the mail archive of the gdb-prs@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]

[Bug breakpoints/13457] `catch syscall' doesn't work for parentafter `fork' is called


http://sourceware.org/bugzilla/show_bug.cgi?id=13457

Pedro Alves <palves at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |palves at redhat dot com

--- Comment #1 from Pedro Alves <palves at redhat dot com> 2012-10-24 16:17:46 UTC ---
Looking at confirming whether the issue is still present in current head, I
debugged this a little.

When handling the fork, we get here:

      /* Immediately detach breakpoints from the child before there's
     any chance of letting the user delete breakpoints from the
     breakpoint lists.  If we don't do this early, it's easy to
     leave left over traps in the child, vis: "break foo; catch
     fork; c; <fork>; del; c; <child calls foo>".  We only follow
     the fork on the last `continue', and by that time the
     breakpoint at "foo" is long gone from the breakpoint table.
     If we vforked, then we don't need to unpatch here, since both
     parent and child are sharing the same memory pages; we'll
     need to unpatch at follow/detach time instead to be certain
     that new breakpoints added between catchpoint hit time and
     vfork follow are detached.  */
      if (ecs->ws.kind != TARGET_WAITKIND_VFORKED)
    {
      /* This won't actually modify the breakpoint list, but will
         physically remove the breakpoints from the child.  */
      detach_breakpoints (ecs->ws.value.related_pid);
    }

Note this should be detaching breakpoints from the _child_ fork.
But we mess up, and "remove" the syscall catchpoint from the
parent (the current inferior):

(top-gdb) bt
#0  remove_catch_syscall (bl=0xea86f0) at ../../src/gdb/breakpoint.c:8036
#1  0x0000000000541d32 in remove_breakpoint_1 (bl=0xea86f0, is=mark_inserted)
at ../../src/gdb/breakpoint.c:3662
#2  0x000000000054196a in detach_breakpoints (ptid=...) at
../../src/gdb/breakpoint.c:3542
#3  0x00000000005b9011 in handle_inferior_event (ecs=0x7fffffffd3c0) at
../../src/gdb/infrun.c:3496

static int
remove_catch_syscall (struct bp_location *bl)
{
  struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
  struct inferior *inf = current_inferior ();
  struct catch_syscall_inferior_data *inf_data
    = get_catch_syscall_inferior_data (inf);

  --inf_data->total_syscalls_count;
  if (!c->syscalls_to_be_caught)
    --inf_data->any_syscall_count;

And so after the fork, we end up with the *_syscall_count's messed up in the
parent.

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


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