Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > b3bd92884018251b87f9099340c300c3 > files > 22

ltrace-0.5-13.45svn.el5_7.12.src.rpm

diff -urp ltrace-0.5/sysdeps/linux-gnu/proc.c ltrace-0.5-pm/sysdeps/linux-gnu/proc.c
--- ltrace-0.5/sysdeps/linux-gnu/proc.c	2011-08-04 22:23:29.823001142 +0200
+++ ltrace-0.5-pm/sysdeps/linux-gnu/proc.c	2011-08-04 22:22:59.858271112 +0200
@@ -1,3 +1,4 @@
+#define _GNU_SOURCE /* For getline.  */
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -15,6 +16,7 @@
 #include <sys/syscall.h>
 #include "ltrace.h"
 #include <stdlib.h>
+#include <error.h>
 
 /* /proc/pid doesn't exist just after the fork, and sometimes `ltrace'
  * couldn't open it to find the executable.  So it may be necessary to
@@ -174,10 +176,13 @@ process_status(pid_t pid)
 	if (file != NULL) {
 		each_line_starting(file, "State:\t", &process_status_cb, &ret);
 		fclose(file);
-	}
-	if (ret == ps_invalid)
-		fprintf(stderr, "Couldn't determine status of process %d\n",
-			pid);
+		if (ret == ps_invalid)
+			error(0, errno, "process_status %d", pid);
+	} else
+		/* If the file is not present, the process presumably
+		 * exited already.  */
+		ret = ps_zombie;
+
 	return ret;
 }
 
diff -urp ltrace-0.5/sysdeps/linux-gnu/trace.c ltrace-0.5-pm/sysdeps/linux-gnu/trace.c
--- ltrace-0.5/sysdeps/linux-gnu/trace.c	2011-08-04 22:23:29.830001541 +0200
+++ ltrace-0.5-pm/sysdeps/linux-gnu/trace.c	2011-08-04 22:24:15.025556523 +0200
@@ -104,9 +104,11 @@ continue_process(pid_t pid)
 
 /**
  * This is used for bookkeeping related to PIDs that the event
- * handlers work with.  */
+ * handlers work with.
+ */
 struct pid_task {
-	pid_t pid;
+	pid_t pid;	/* This may be 0 for tasks that exited
+			 * mid-handling.  */
 	int sigstopped;
 	int got_event;
 	int delivered;
@@ -171,6 +173,7 @@ task_stopped(struct process * task, void
 static struct pid_task *
 get_task_info(struct pid_set * pids, pid_t pid)
 {
+	assert(pid != 0);
 	size_t i;
 	for (i = 0; i < pids->count; ++i)
 		if (pids->tasks[i].pid == pid)
@@ -245,7 +248,8 @@ process_stopping_done(struct process_sto
 {
 	size_t i;
 	for (i = 0; i < self->pids.count; ++i)
-		if (self->pids.tasks[i].delivered)
+		if (self->pids.tasks[i].pid != 0
+		    && self->pids.tasks[i].delivered)
 			continue_process(self->pids.tasks[i].pid);
 	continue_process(self->task_enabling_breakpoint->pid);
 	destroy_event_handler(leader);
@@ -286,7 +290,8 @@ continue_for_sigstop_delivery(struct pid
 {
 	size_t i;
 	for (i = 0; i < pids->count; ++i) {
-		if (pids->tasks[i].sigstopped
+		if (pids->tasks[i].pid != 0
+		    && pids->tasks[i].sigstopped
 		    && !pids->tasks[i].delivered
 		    && pids->tasks[i].got_event) {
 			ptrace(PTRACE_SYSCALL, pids->tasks[i].pid, 0, 0);
@@ -295,11 +300,17 @@ continue_for_sigstop_delivery(struct pid
 }
 
 static int
+event_exit_p(struct event * event)
+{
+	return event != NULL && (event->thing == LT_EV_EXIT
+				 || event->thing == LT_EV_EXIT_SIGNAL);
+}
+
+static int
 event_exit_or_none_p(struct event * event)
 {
 	return event == NULL
-		|| event->thing == LT_EV_EXIT
-		|| event->thing == LT_EV_EXIT_SIGNAL
+		|| event_exit_p(event)
 		|| event->thing == LT_EV_NONE;
 }
 
@@ -326,7 +337,8 @@ await_sigstop_delivery(struct pid_set * 
 		int all_clear = 1;
 		size_t i;
 		for (i = 0; i < pids->count; ++i)
-			if (pids->tasks[i].sigstopped
+			if (pids->tasks[i].pid != 0
+			    && pids->tasks[i].sigstopped
 			    && !pids->tasks[i].delivered) {
 				all_clear = 0;
 				break;
@@ -358,12 +370,17 @@ process_stopping_on_event(Event_Handler 
 	int state = self->state;
 	int event_to_queue = !event_exit_or_none_p(event);
 
+	/* Deactivate the entry if the task exits.  */
+	if (event_exit_p(event) && task_info != NULL)
+		task_info->pid = 0;
+
 	switch (state) {
 	case psh_stopping:
 		/* If everyone is stopped, singlestep.  */
 		if (each_task(leader, &task_stopped, NULL) == NULL) {
-			ptrace(PTRACE_SINGLESTEP,
-			       self->task_enabling_breakpoint->pid, 0, 0);
+			if (ptrace(PTRACE_SINGLESTEP,
+				   self->task_enabling_breakpoint->pid, 0, 0))
+				perror("PTRACE_SINGLESTEP");
 			self->state = state = psh_singlestep;
 		}
 		break;
@@ -602,6 +619,8 @@ ltrace_exiting_install_handler(struct pr
 		size_t i;
 		for (i = 0; i < other->pids.count; ++i) {
 			struct pid_task * oti = &other->pids.tasks[i];
+			if (oti->pid == 0)
+				continue;
 			struct pid_task * task_info
 				= add_task_info(&handler->pids, oti->pid);
 			if (task_info == NULL) {
Только в ltrace-0.5-pm/sysdeps/linux-gnu: trace.c~