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]

[non-stop] 02/10 Don't trim ptids on fork/exec


With the previous patch installed, we hit an assertion inside
is_running on the follow-* tests.  Here is a backtrace:

#0  internal_error (file=0x830eadf "../../src/gdb/thread.c", line=515, 
string=0x830eac1 "%s: Assertion `%s' failed.")
    at ../../src/gdb/utils.c:817
#1  0x08142650 in is_executing (ptid={pid = 13049, lwp = 0, tid = 0}) 
at ../../src/gdb/thread.c:515
#2  0x08140dc3 in get_selected_block (addr_in_block=0x0) 
at ../../src/gdb/stack.c:1647
#3  0x0812df2a in decode_objc (argptr=0xffe590fc, funfirstline=1, 
file_symtab=0x0, canonical=0x0,
    saved_arg=0x8438088 "main") at ../../src/gdb/linespec.c:1125
#4  0x0812d691 in decode_line_1 (argptr=0xffe590fc, funfirstline=1, 
default_symtab=0x0, default_line=0,
    canonical=0x0, not_found_ptr=0xffe59104) at ../../src/gdb/linespec.c:746
#5  0x080f6e96 in breakpoint_re_set_one (bint=0x84382b0) 
at ../../src/gdb/breakpoint.c:7435
#6  0x08143ff8 in catch_errors (func=0x80f6d71 <breakpoint_re_set_one>, 
func_args=0x84382b0,
    errstring=0x84143d8 "Error in re-setting breakpoint 1: ", mask=6) 
at ../../src/gdb/exceptions.c:509
#7  0x080f710e in breakpoint_re_set () at ../../src/gdb/breakpoint.c:7577
#8  0x08128255 in clear_symtab_users () at ../../src/gdb/symfile.c:2837
#9  0x08124d75 in new_symfile_objfile (objfile=0x851e508, mainline=1, verbo=0) 
at ../../src/gdb/symfile.c:978
#10 0x081250f1 in symbol_file_add_with_addrs_or_offsets (abfd=0x848e700, 
from_tty=0, addrs=0x0, offsets=0x0,
    num_offsets=0, mainline=1, flags=0) at ../../src/gdb/symfile.c:1137
#11 0x08125149 in symbol_file_add_from_bfd (abfd=0x848e700, from_tty=0, 
addrs=0x0, mainline=1, flags=0)
    at ../../src/gdb/symfile.c:1156
#12 0x08125182 in symbol_file_add (
    
name=0x84662c8 "/home/pedro/gdb/nonstop_head/build-32/gdb/testsuite/gdb.base/execd-prog", 
from_tty=0, addrs=0x0,
    mainline=1, flags=0) at ../../src/gdb/symfile.c:1169
#13 0x081251d5 in symbol_file_add_main_1 (
    
args=0x84662c8 "/home/pedro/gdb/nonstop_head/build-32/gdb/testsuite/gdb.base/execd-prog", 
from_tty=0, flags=0)
    at ../../src/gdb/symfile.c:1191
#14 0x081251a4 in symbol_file_add_main (
    
args=0x84662c8 "/home/pedro/gdb/nonstop_head/build-32/gdb/testsuite/gdb.base/execd-prog", 
from_tty=0)
    at ../../src/gdb/symfile.c:1185
#15 0x08135152 in follow_exec (pid=13049,
    
execd_pathname=0x84662c8 "/home/pedro/gdb/nonstop_head/build-32/gdb/testsuite/gdb.base/execd-prog")
    at ../../src/gdb/infrun.c:423
#16 0x08137078 in handle_inferior_event (ecs=0xffe59490) 
at ../../src/gdb/infrun.c:1935

The issue is that the thread module should never see an inferior_ptid
not listed in the thread list if there are threads in the thread
list.  We accept that an ptid is not listed iff there are no
threads listed, so targets that don't yet register the main
thread in the thread/task list continue working.

Now, the assert triggers, because, across an exec and a fork, we're
transfering a ptid to the core with only that has the pid member filled.
A problem similar to the other crash across an exec when doing an
"info thread" we just fixed recently (execl.exp).

From infrun.c:handle_inferior_event:

(gdb)
1923
1924        case TARGET_WAITKIND_EXECD:
1925          if (debug_infrun)
1926            fprintf_unfiltered (gdb_stdlog, "infrun: 
TARGET_WAITKIND_EXECD\n");
1927          stop_signal = TARGET_SIGNAL_TRAP;
1928
1929          pending_follow.execd_pathname =
1930            savestring (ecs->ws.value.execd_pathname,
1931                        strlen (ecs->ws.value.execd_pathname));
1932
(gdb)
1933          /* This causes the eventpoints and symbol table to be reset.  
Must
1934             do this now, before trying to determine whether to stop. */
1935          follow_exec (PIDGET (inferior_ptid), 
pending_follow.execd_pathname);
1936          xfree (pending_follow.execd_pathname);

The fix is to not trim the ptids the targets report.

The patch touches inf-ttrace.c to adapt to the new interface, but
unfortunatelly, I have no HPUX access to test it.  If someone
could do a spin there for me, it would be really appreciated.

win32-nat.c was also touched.  I've tested the whole series
on cygwin, although this hunk in question should be obvious --
related_pid is not used at all in either cygwin or mingw32, so
setting it is a nop really -- it is only defined on on
TARGET_WAITKIND_FORK|EXEC, but we don't support those on cygwin
or mingw.

-- 
Pedro Alves
2008-06-15  Pedro Alves  <pedro@codesourcery.com>

	* target.h (struct target_waitstatus): Store related_pid as a ptid.
	(inferior_has_forked, inferior_has_vforked, inferior_has_execd):
	Take a ptid_t.
	* breakpoint.h (struct breakpoint): Change forked_inferior_pid
	type to ptid.
	* breakpoint.c (print_it_typical, bpstat_check_location)
	(print_one_breakpoint_location, set_raw_breakpoint_without_location)
	(create_fork_vfork_event_catchpoint): Adjust.
	* infrun.c (fork_event): Change parent_pid and child_pid types to
	ptid.
	(follow_exec, inferior_has_forked, inferior_has_vforked)
	(inferior_has_execd): Take a ptid_t and don't trim it.
	* linux-thread-db.c (thread_db_wait): Don't trim the returned ptid.
	* linux-nat.c (linux_child_follow_fork): Adjust.
	* inf-ptrace.c (inf_ptrace_wait): Adjust.
	* inf-ttrace.c (inf_ttrace_wait): Adjust.
	* win32-nat.c (get_win32_debug_event): Don't set related_pid.
	
---
 gdb/breakpoint.c |   19 ++++++++++---------
 gdb/breakpoint.h |    2 +-
 gdb/inf-ptrace.c |    4 ++--
 gdb/inf-ttrace.c |   15 ++++++++++++---
 gdb/infrun.c     |   26 +++++++++++++-------------
 gdb/linux-nat.c  |    9 +++++----
 gdb/target.h     |   12 ++++++------
 gdb/win32-nat.c  |    4 ++--
 8 files changed, 51 insertions(+), 40 deletions(-)

Index: src/gdb/target.h
===================================================================
--- src.orig/gdb/target.h	2008-06-10 11:50:57.000000000 +0100
+++ src/gdb/target.h	2008-06-10 11:52:11.000000000 +0100
@@ -91,13 +91,13 @@ enum target_waitkind
        (e.g. it called load(2) on AIX).  */
     TARGET_WAITKIND_LOADED,
 
-    /* The program has forked.  A "related" process' ID is in
+    /* The program has forked.  A "related" process' PTID is in
        value.related_pid.  I.e., if the child forks, value.related_pid
        is the parent's ID.  */
 
     TARGET_WAITKIND_FORKED,
 
-    /* The program has vforked.  A "related" process's ID is in
+    /* The program has vforked.  A "related" process's PTID is in
        value.related_pid.  */
 
     TARGET_WAITKIND_VFORKED,
@@ -140,7 +140,7 @@ struct target_waitstatus
       {
 	int integer;
 	enum target_signal sig;
-	int related_pid;
+	ptid_t related_pid;
 	char *execd_pathname;
 	int syscall_id;
       }
@@ -688,11 +688,11 @@ int target_write_memory_blocks (VEC(memo
 
 /* From infrun.c.  */
 
-extern int inferior_has_forked (int pid, int *child_pid);
+extern int inferior_has_forked (ptid_t pid, ptid_t *child_pid);
 
-extern int inferior_has_vforked (int pid, int *child_pid);
+extern int inferior_has_vforked (ptid_t pid, ptid_t *child_pid);
 
-extern int inferior_has_execd (int pid, char **execd_pathname);
+extern int inferior_has_execd (ptid_t pid, char **execd_pathname);
 
 /* From exec.c */
 
Index: src/gdb/breakpoint.h
===================================================================
--- src.orig/gdb/breakpoint.h	2008-06-10 11:49:22.000000000 +0100
+++ src/gdb/breakpoint.h	2008-06-10 11:52:11.000000000 +0100
@@ -439,7 +439,7 @@ struct breakpoint
     /* Process id of a child process whose forking triggered this
        catchpoint.  This field is only valid immediately after this
        catchpoint has triggered.  */
-    int forked_inferior_pid;
+    ptid_t forked_inferior_pid;
 
     /* Filename of a program whose exec triggered this catchpoint.
        This field is only valid immediately after this catchpoint has
Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c	2008-06-10 11:52:00.000000000 +0100
+++ src/gdb/breakpoint.c	2008-06-10 11:52:11.000000000 +0100
@@ -2313,7 +2313,7 @@ print_it_typical (bpstat bs)
       annotate_catchpoint (b->number);
       printf_filtered (_("\nCatchpoint %d (forked process %d), "),
 		       b->number, 
-		       b->forked_inferior_pid);
+		       ptid_get_pid (b->forked_inferior_pid));
       return PRINT_SRC_AND_LOC;
       break;
 
@@ -2321,7 +2321,7 @@ print_it_typical (bpstat bs)
       annotate_catchpoint (b->number);
       printf_filtered (_("\nCatchpoint %d (vforked process %d), "),
 		       b->number, 
-		       b->forked_inferior_pid);
+		       ptid_get_pid (b->forked_inferior_pid));
       return PRINT_SRC_AND_LOC;
       break;
 
@@ -2813,17 +2813,17 @@ bpstat_check_location (const struct bp_l
     return 0;
 
   if ((b->type == bp_catch_fork)
-      && !inferior_has_forked (PIDGET (inferior_ptid),
+      && !inferior_has_forked (inferior_ptid,
 			       &b->forked_inferior_pid))
     return 0;
   
   if ((b->type == bp_catch_vfork)
-      && !inferior_has_vforked (PIDGET (inferior_ptid),
+      && !inferior_has_vforked (inferior_ptid,
 				&b->forked_inferior_pid))
     return 0;
   
   if ((b->type == bp_catch_exec)
-      && !inferior_has_execd (PIDGET (inferior_ptid), &b->exec_pathname))
+      && !inferior_has_execd (inferior_ptid, &b->exec_pathname))
     return 0;
 
   return 1;
@@ -3651,10 +3651,11 @@ print_one_breakpoint_location (struct br
 	if (addressprint)
 	  ui_out_field_skip (uiout, "addr");
 	annotate_field (5);
-	if (b->forked_inferior_pid != 0)
+	if (!ptid_equal (b->forked_inferior_pid, null_ptid))
 	  {
 	    ui_out_text (uiout, "process ");
-	    ui_out_field_int (uiout, "what", b->forked_inferior_pid);
+	    ui_out_field_int (uiout, "what",
+			      ptid_get_pid (b->forked_inferior_pid));
 	    ui_out_spaces (uiout, 1);
 	  }
 	break;
@@ -4323,7 +4324,7 @@ set_raw_breakpoint_without_location (enu
   b->frame_id = null_frame_id;
   b->dll_pathname = NULL;
   b->triggered_dll_pathname = NULL;
-  b->forked_inferior_pid = 0;
+  b->forked_inferior_pid = null_ptid;
   b->exec_pathname = NULL;
   b->ops = NULL;
   b->condition_not_parsed = 0;
@@ -4696,7 +4697,7 @@ create_fork_vfork_event_catchpoint (int 
   b->addr_string = NULL;
   b->enable_state = bp_enabled;
   b->disposition = tempflag ? disp_del : disp_donttouch;
-  b->forked_inferior_pid = 0;
+  b->forked_inferior_pid = null_ptid;
   update_global_location_list ();
 
 
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2008-06-10 11:52:00.000000000 +0100
+++ src/gdb/infrun.c	2008-06-10 11:52:11.000000000 +0100
@@ -297,8 +297,8 @@ static struct
   enum target_waitkind kind;
   struct
   {
-    int parent_pid;
-    int child_pid;
+    ptid_t parent_pid;
+    ptid_t child_pid;
   }
   fork_event;
   char *execd_pathname;
@@ -362,9 +362,9 @@ follow_inferior_reset_breakpoints (void)
 /* EXECD_PATHNAME is assumed to be non-NULL. */
 
 static void
-follow_exec (int pid, char *execd_pathname)
+follow_exec (ptid_t pid, char *execd_pathname)
 {
-  int saved_pid = pid;
+  ptid_t saved_pid = pid;
   struct target_ops *tgt;
 
   /* This is an exec event that we actually wish to pay attention to.
@@ -404,7 +404,7 @@ follow_exec (int pid, char *execd_pathna
   gdb_flush (gdb_stdout);
   generic_mourn_inferior ();
   /* Because mourn_inferior resets inferior_ptid. */
-  inferior_ptid = pid_to_ptid (saved_pid);
+  inferior_ptid = saved_pid;
 
   if (gdb_sysroot && *gdb_sysroot)
     {
@@ -1897,7 +1897,7 @@ handle_inferior_event (struct execution_
       stop_signal = TARGET_SIGNAL_TRAP;
       pending_follow.kind = ecs->ws.kind;
 
-      pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid);
+      pending_follow.fork_event.parent_pid = ecs->ptid;
       pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;
 
       if (!ptid_equal (ecs->ptid, inferior_ptid))
@@ -1932,7 +1932,7 @@ handle_inferior_event (struct execution_
 
       /* This causes the eventpoints and symbol table to be reset.  Must
          do this now, before trying to determine whether to stop. */
-      follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname);
+      follow_exec (inferior_ptid, pending_follow.execd_pathname);
       xfree (pending_follow.execd_pathname);
 
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
@@ -4323,7 +4323,7 @@ discard_inferior_status (struct inferior
 }
 
 int
-inferior_has_forked (int pid, int *child_pid)
+inferior_has_forked (ptid_t pid, ptid_t *child_pid)
 {
   struct target_waitstatus last;
   ptid_t last_ptid;
@@ -4333,7 +4333,7 @@ inferior_has_forked (int pid, int *child
   if (last.kind != TARGET_WAITKIND_FORKED)
     return 0;
 
-  if (ptid_get_pid (last_ptid) != pid)
+  if (!ptid_equal (last_ptid, pid))
     return 0;
 
   *child_pid = last.value.related_pid;
@@ -4341,7 +4341,7 @@ inferior_has_forked (int pid, int *child
 }
 
 int
-inferior_has_vforked (int pid, int *child_pid)
+inferior_has_vforked (ptid_t pid, ptid_t *child_pid)
 {
   struct target_waitstatus last;
   ptid_t last_ptid;
@@ -4351,7 +4351,7 @@ inferior_has_vforked (int pid, int *chil
   if (last.kind != TARGET_WAITKIND_VFORKED)
     return 0;
 
-  if (ptid_get_pid (last_ptid) != pid)
+  if (!ptid_equal (last_ptid, pid))
     return 0;
 
   *child_pid = last.value.related_pid;
@@ -4359,7 +4359,7 @@ inferior_has_vforked (int pid, int *chil
 }
 
 int
-inferior_has_execd (int pid, char **execd_pathname)
+inferior_has_execd (ptid_t pid, char **execd_pathname)
 {
   struct target_waitstatus last;
   ptid_t last_ptid;
@@ -4369,7 +4369,7 @@ inferior_has_execd (int pid, char **exec
   if (last.kind != TARGET_WAITKIND_EXECD)
     return 0;
 
-  if (ptid_get_pid (last_ptid) != pid)
+  if (!ptid_equal (last_ptid, pid))
     return 0;
 
   *execd_pathname = xstrdup (last.value.execd_pathname);
Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c	2008-06-10 11:52:00.000000000 +0100
+++ src/gdb/linux-nat.c	2008-06-10 11:52:11.000000000 +0100
@@ -568,7 +568,7 @@ linux_child_follow_fork (struct target_o
   parent_pid = ptid_get_lwp (last_ptid);
   if (parent_pid == 0)
     parent_pid = ptid_get_pid (last_ptid);
-  child_pid = last_status.value.related_pid;
+  child_pid = PIDGET (last_status.value.related_pid);
 
   if (! follow_child)
     {
@@ -1623,7 +1623,7 @@ linux_handle_extended_wait (struct lwp_i
 			    _("wait returned unexpected status 0x%x"), status);
 	}
 
-      ourstatus->value.related_pid = new_pid;
+      ourstatus->value.related_pid = ptid_build (new_pid, new_pid, 0);
 
       if (event == PTRACE_EVENT_FORK)
 	ourstatus->kind = TARGET_WAITKIND_FORKED;
@@ -1655,7 +1655,8 @@ linux_handle_extended_wait (struct lwp_i
 	  else
 	    {
 	      new_lp->resumed = 1;
-	      ptrace (PTRACE_CONT, lp->waitstatus.value.related_pid, 0,
+	      ptrace (PTRACE_CONT,
+		      PIDGET (lp->waitstatus.value.related_pid), 0,
 		      status ? WSTOPSIG (status) : 0);
 	    }
 
@@ -2879,7 +2880,7 @@ linux_nat_kill (void)
   if (last.kind == TARGET_WAITKIND_FORKED
       || last.kind == TARGET_WAITKIND_VFORKED)
     {
-      ptrace (PT_KILL, last.value.related_pid, 0, 0);
+      ptrace (PT_KILL, PIDGET (last.value.related_pid), 0, 0);
       wait (&status);
     }
 
Index: src/gdb/inf-ptrace.c
===================================================================
--- src.orig/gdb/inf-ptrace.c	2008-06-10 11:49:22.000000000 +0100
+++ src/gdb/inf-ptrace.c	2008-06-10 11:52:11.000000000 +0100
@@ -399,7 +399,7 @@ inf_ptrace_wait (ptid_t ptid, struct tar
 	{
 	case PTRACE_FORK:
 	  ourstatus->kind = TARGET_WAITKIND_FORKED;
-	  ourstatus->value.related_pid = pe.pe_other_pid;
+	  ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid);
 
 	  /* Make sure the other end of the fork is stopped too.  */
 	  fpid = waitpid (pe.pe_other_pid, &status, 0);
@@ -414,7 +414,7 @@ inf_ptrace_wait (ptid_t ptid, struct tar
 	  gdb_assert (pe.pe_other_pid == pid);
 	  if (fpid == ptid_get_pid (inferior_ptid))
 	    {
-	      ourstatus->value.related_pid = pe.pe_other_pid;
+	      ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid);
 	      return pid_to_ptid (fpid);
 	    }
 
Index: src/gdb/inf-ttrace.c
===================================================================
--- src.orig/gdb/inf-ttrace.c	2008-06-10 11:49:22.000000000 +0100
+++ src/gdb/inf-ttrace.c	2008-06-10 11:52:11.000000000 +0100
@@ -839,6 +839,7 @@ inf_ttrace_wait (ptid_t ptid, struct tar
   lwpid_t lwpid = ptid_get_lwp (ptid);
   ttstate_t tts;
   struct thread_info *ti;
+  ptid_t related_ptid;
 
   /* Until proven otherwise.  */
   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
@@ -912,8 +913,11 @@ inf_ttrace_wait (ptid_t ptid, struct tar
       break;
 
     case TTEVT_FORK:
+      related_ptid = ptid_build (tts.tts_u.tts_fork.tts_fpid,
+				 tts.tts_u.tts_fork.tts_flwpid, 0);
+
       ourstatus->kind = TARGET_WAITKIND_FORKED;
-      ourstatus->value.related_pid = tts.tts_u.tts_fork.tts_fpid;
+      ourstatus->value.related_pid = related_ptid;
 
       /* Make sure the other end of the fork is stopped too.  */
       if (ttrace_wait (tts.tts_u.tts_fork.tts_fpid,
@@ -924,16 +928,21 @@ inf_ttrace_wait (ptid_t ptid, struct tar
       gdb_assert (tts.tts_event == TTEVT_FORK);
       if (tts.tts_u.tts_fork.tts_isparent)
 	{
+	  related_ptid = ptid_build (tts.tts_u.tts_fork.tts_fpid,
+				     tts.tts_u.tts_fork.tts_flwpid, 0);
 	  ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
-	  ourstatus->value.related_pid = tts.tts_u.tts_fork.tts_fpid;
+	  ourstatus->value.related_pid = related_ptid;
 	}
       break;
 
     case TTEVT_VFORK:
       gdb_assert (!tts.tts_u.tts_fork.tts_isparent);
 
+      related_ptid = ptid_build (tts.tts_u.tts_fork.tts_fpid,
+				 tts.tts_u.tts_fork.tts_flwpid, 0);
+
       ourstatus->kind = TARGET_WAITKIND_VFORKED;
-      ourstatus->value.related_pid = tts.tts_u.tts_fork.tts_fpid;
+      ourstatus->value.related_pid = related_ptid;
 
       /* HACK: To avoid touching the parent during the vfork, switch
 	 away from it.  */
Index: src/gdb/win32-nat.c
===================================================================
--- src.orig/gdb/win32-nat.c	2008-06-10 11:49:22.000000000 +0100
+++ src/gdb/win32-nat.c	2008-06-10 11:52:11.000000000 +0100
@@ -1300,7 +1300,7 @@ get_win32_debug_event (int pid, struct t
 	      /* Kludge around a Windows bug where first event is a create
 		 thread event.  Caused when attached process does not have
 		 a main thread. */
-	      retval = ourstatus->value.related_pid = fake_create_process ();
+	      retval = fake_create_process ();
 	     if (retval)
 	       saw_create++;
 	    }
@@ -1340,7 +1340,7 @@ get_win32_debug_event (int pid, struct t
       /* Add the main thread */
       th = win32_add_thread (main_thread_id,
 			     current_event.u.CreateProcessInfo.hThread);
-      retval = ourstatus->value.related_pid = current_event.dwThreadId;
+      retval = current_event.dwThreadId;
       break;
 
     case EXIT_PROCESS_DEBUG_EVENT:

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