diff -urp ltrace-0.5/ltrace.h ltrace-0.5-pm/ltrace.h --- ltrace-0.5/ltrace.h 2011-08-01 20:57:06.687182222 +0200 +++ ltrace-0.5-pm/ltrace.h 2011-08-01 20:58:27.684660722 +0200 @@ -202,6 +202,14 @@ struct opt_c_struct { }; extern struct dict *dict_opt_c; +enum process_status { + ps_invalid, /* Failure. */ + ps_stop, /* Job-control stop. */ + ps_tracing_stop, + ps_zombie, + ps_other, /* Necessary other states can be added as needed. */ +}; + enum pcb_status { pcb_stop, /* The iteration should stop. */ pcb_cont, /* The iteration should continue. */ @@ -250,7 +258,7 @@ extern char *pid2name(pid_t pid); extern pid_t process_leader(pid_t pid); extern int process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n); extern int process_stopped(pid_t pid); -extern char process_status(pid_t pid); +extern enum process_status process_status(pid_t pid); extern void trace_set_options(struct process *proc, pid_t pid); extern void trace_me(void); extern int trace_pid(pid_t pid); Только в ltrace-0.5-pm: ltrace.h~ 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-01 20:57:06.668172722 +0200 +++ ltrace-0.5-pm/sysdeps/linux-gnu/proc.c 2011-08-01 20:59:27.721664221 +0200 @@ -135,19 +135,49 @@ process_stopped(pid_t pid) static enum pcb_status process_status_cb(const char * line, const char * prefix, void * data) { - *(char *)data = line[strlen(prefix)]; - return pcb_stop; + const char * status = line + strlen(prefix); + const char c = *status; + +#define RETURN(C) do { \ + *(enum process_status *)data = C; \ + return pcb_stop; \ + } while (0) + + switch (c) { + case 'Z': RETURN(ps_zombie); + case 't': RETURN(ps_tracing_stop); + case 'T': { + /* This can be either "T (stopped)" or, for older + * kernels, "T (tracing stop)". */ + if (!strcmp(status, "T (stopped)\n")) + RETURN(ps_stop); + else if (!strcmp(status, "T (tracing stop)\n")) + RETURN(ps_tracing_stop); + else { + fprintf(stderr, "Unknown process status: %s", + status); + RETURN(ps_stop); /* Some sort of stop + * anyway. */ + } + } + } + + RETURN(ps_other); +#undef RETURN } -char +enum process_status process_status(pid_t pid) { - char ret = '?'; + enum process_status ret = ps_invalid; FILE * file = open_status_file(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); return ret; } Только в ltrace-0.5-pm/sysdeps/linux-gnu: proc.c~ 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-01 20:57:06.690183722 +0200 +++ ltrace-0.5-pm/sysdeps/linux-gnu/trace.c 2011-08-01 21:00:12.891237724 +0200 @@ -154,19 +154,18 @@ struct process_stopping_handler static enum pcb_status task_stopped(struct process * task, void * data) { - int status; - /* If the task is already stopped, don't worry about it. * Likewise if it managed to become a zombie or terminate in * the meantime. This can happen when the whole thread group * is terminating. */ - switch (status = process_status(task->pid)) - case -1: - case 't': - case 'Z': + switch (process_status(task->pid)) { + case ps_invalid: + case ps_tracing_stop: + case ps_zombie: return pcb_cont; - - return pcb_stop; + default: + return pcb_stop; + } } static struct pid_task * Только в ltrace-0.5-pm/sysdeps/linux-gnu: trace.c~