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~