Blob Blame History Raw
diff -urp ltrace-0.5/ltrace.h ltrace-0.5-pm/ltrace.h
--- ltrace-0.5/ltrace.h	2009-03-03 02:07:44.000000000 +0100
+++ ltrace-0.5-pm/ltrace.h	2009-03-03 02:07:19.000000000 +0100
@@ -107,6 +107,9 @@ struct process {
 	int mask_32bit;		/* 1 if 64-bit ltrace is tracing 32-bit process.  */
 	unsigned int personality;
 	int tracesysgood;	/* signal indicating a PTRACE_SYSCALL trap */
+	int early;	/* for consistency checks, this is true for
+			 * children whose TRAP was delivered before
+			 * the fork message of the parent.  */
 
 	int callstack_depth;
 	struct callstack_element callstack[MAX_CALLDEPTH];
@@ -173,7 +176,7 @@ extern void reinitialize_breakpoints(str
 
 extern struct process *open_program(char *filename, pid_t pid);
 extern void open_pid(pid_t pid, int verbose);
-extern void open_forked_pid(pid_t pid);
+extern void open_forked_pid(pid_t pid, int early);
 extern void show_summary(void);
 
 /* Arch-dependent stuff: */
diff -urp ltrace-0.5/proc.c ltrace-0.5-pm/proc.c
--- ltrace-0.5/proc.c	2009-03-03 02:07:44.000000000 +0100
+++ ltrace-0.5-pm/proc.c	2009-03-03 02:07:19.000000000 +0100
@@ -59,10 +59,11 @@ void open_pid(pid_t pid, int verbose)
 	proc->pid = pid;
 }
 
-void open_forked_pid(pid_t pid)
+void open_forked_pid(pid_t pid, int early)
 {
 	char *filename = pid2name(pid);
 	struct process *proc = open_program(filename, 0);
 	proc->pid = pid;
 	proc->breakpoints_enabled = -1;
+	proc->early = early;
 }
diff -urp ltrace-0.5/wait_for_something.c ltrace-0.5-pm/wait_for_something.c
--- ltrace-0.5/wait_for_something.c	2009-03-03 02:07:44.000000000 +0100
+++ ltrace-0.5-pm/wait_for_something.c	2009-03-03 02:07:19.000000000 +0100
@@ -45,10 +45,24 @@ struct event *wait_for_something(void)
 		perror("wait");
 		exit(1);
 	}
+
 	event.proc = pid2proc(pid);
 	if (!event.proc) {
-		fprintf(stderr, "signal from wrong pid %u ?!?\n", pid);
-		exit(1);
+		if(!opt_f) {
+			fprintf(stderr, "signal from wrong pid %u ?!?\n", pid);
+			exit(1);
+		} else {
+			/* Parent forked, but we got child's STOP
+			 * signal first.  */
+			debug (1, "signal from forked child delivered ahead of time?");
+
+			event.thing = LT_EV_NONE;
+			event.e_un.signum = WSTOPSIG(status);
+			open_forked_pid(pid, 1);
+			event.proc = pid2proc(pid);
+			continue_after_signal(event.proc->pid, event.e_un.signum);
+			return &event;
+		}
 	}
 	get_arch_dep(event.proc);
 	event.proc->instruction_pointer = NULL;
@@ -104,7 +118,18 @@ struct event *wait_for_something(void)
 		child_pid = (pid_t) get_child_pid(event.proc->pid);
                 if (child_pid){
 			debug (3, "fork: get_child_pid gave us %d", child_pid);
-			open_forked_pid(child_pid);
+
+			struct process *it = list_of_processes;
+			for (; it != NULL; it = it->next)
+				if (it->pid == child_pid) {
+					if (!it->early)
+						fprintf (stderr,
+							 "Child %d re-delivered.\n",
+							 child_pid);
+					break;
+				}
+			if (!it)
+				open_forked_pid(child_pid, 0);
                 }
                 enable_all_breakpoints(event.proc);
 		continue_after_signal(event.proc->pid, event.e_un.signum);