diff options
author | Juan Cespedes <cespedes@debian.org> | 1998-04-12 00:04:39 +0200 |
---|---|---|
committer | Juan Cespedes <cespedes@debian.org> | 1998-04-12 00:04:39 +0200 |
commit | 28f60197b93b45422a73e5d1a6aa581584d6c4a5 (patch) | |
tree | ade1362d0aebc199e41f0f17ed8ef436b9e5cb1a | |
parent | 5e0acdb26c98f0d95a5266e579669b5c19eb02ce (diff) | |
download | ltrace-28f60197b93b45422a73e5d1a6aa581584d6c4a5.tar.gz |
Version 0.2.9
* Bug#20616 wasn't completely fixed; it didn't work with some programs (Fixed)
* Stopping ltrace with ^C DIDN'T WORK if -p option is not used!! (Fixed)
* Option -f caused program to segfault; fixed
* Fixed nasty bug about executing set[ug]id binaries:
When executing a program fails, don't left the program STOPPED.
* Make ltrace work with all setuid and setgid binaries when invoked as root
-rw-r--r-- | BUGS | 1 | ||||
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | debian/changelog | 11 | ||||
-rwxr-xr-x | debian/rules | 8 | ||||
-rw-r--r-- | etc/ltrace.conf | 13 | ||||
-rw-r--r-- | execute_program.c | 2 | ||||
-rw-r--r-- | ltrace.c | 71 | ||||
-rw-r--r-- | ltrace.h | 2 | ||||
-rw-r--r-- | output.c | 5 | ||||
-rw-r--r-- | process_event.c | 18 | ||||
-rw-r--r-- | read_config_file.c (renamed from config_file.c) | 2 | ||||
-rw-r--r-- | read_config_file.h (renamed from config_file.h) | 0 | ||||
-rw-r--r-- | wait_for_something.c | 12 |
14 files changed, 133 insertions, 25 deletions
@@ -1,4 +1,3 @@ -* processes attached with option -p die when the attacher is interrupted * Option -f sometimes fails to trace some children * Manual page is not accurate (config files...) * elf.c only supports elf32 binaries @@ -4,10 +4,13 @@ OS := $(shell uname -s) TOPDIR = $(shell pwd) CC = gcc -CFLAGS = -O2 -g -Wall -I$(TOPDIR) -I$(TOPDIR)/sysdeps/$(OS) -I- #-I$(TOPDIR)/sysdeps/$(ARCH) +CPPFLAGS = -I$(TOPDIR) -I$(TOPDIR)/sysdeps/$(OS) -I- -DHAVE_CONFIG_H #-I$(TOPDIR)/sysdeps/$(ARCH) +CFLAGS = -Wall -g -O2 +LDFLAGS = +LIBS = -OBJ = ltrace.o options.o elf.o output.o config_file.o \ - execute_program.o wait_for_something.o process_event.o \ +OBJ = ltrace.o options.o elf.o output.o read_config_file.o \ + execute_program.o wait_for_something.o process_event.o \ display_args.o breakpoints.o proc.o all: dummy @@ -34,4 +37,6 @@ install: ltrace dummy: +.PHONY: all clean dist install + .EXPORT_ALL_VARIABLES: @@ -1,5 +1,5 @@ -* Regarding option -p: disable breakpoints on exit * Option -e +* C++ name demangling * Improve documentation * Display different argument types: + format diff --git a/debian/changelog b/debian/changelog index 87716c3..f6798a7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +ltrace (0.2.9) frozen unstable; urgency=low + + * Bug#20616 wasn't completely fixed; it didn't work with some programs (Fixed) + * Stopping ltrace with ^C DIDN'T WORK if -p option is not used!! (Fixed) + * Option -f caused program to segfault; fixed + * Fixed nasty bug about executing set[ug]id binaries: + When executing a program fails, don't left the program STOPPED. + * Make ltrace work with all setuid and setgid binaries when invoked as root + + -- Juan Cespedes <cespedes@debian.org> Sat, 11 Apr 1998 22:50:38 +0200 + ltrace (0.2.8) frozen unstable; urgency=low * Fix important bug regarding -p: disable all breakpoints on exit (Bug#20616) diff --git a/debian/rules b/debian/rules index 23bb348..7ac8ef5 100755 --- a/debian/rules +++ b/debian/rules @@ -2,7 +2,10 @@ # # Copyright (C) 1997,1998 Juan Cespedes <cespedes@debian.org> +.PHONY: binary binary-indep binary-arch clean + build: + $(checkdir) $(MAKE) touch build @@ -11,6 +14,7 @@ binary: binary-arch binary-indep binary-indep: binary-arch: build + $(checkdir) test root = "`whoami`" || exit 1 $(RM) -rf debian/tmp @@ -29,7 +33,11 @@ binary-arch: build dpkg --build debian/tmp .. clean: + $(checkdir) $(RM) -f build debian/files debian/substvars $(MAKE) clean $(RM) -rf debian/tmp +define checkdir + test -f ltrace.c -a -f debian/rules +endef diff --git a/etc/ltrace.conf b/etc/ltrace.conf index afe1584..be6f7d6 100644 --- a/etc/ltrace.conf +++ b/etc/ltrace.conf @@ -13,6 +13,15 @@ ; string == (char *) ; stringN == (char *) [N>=0] [show only up to (arg N) bytes] +; ctype.h +char tolower(char); +char toupper(char); + +; dirent.h +int closedir(addr); +addr opendir(string); +addr readdir(addr); + ; errno.h addr __errno_location(void); @@ -60,6 +69,8 @@ int fputc(char,file); int fputs(string,file); uint fwrite(string,uint,uint,file); int printf(format); +int puts(string); +int remove(string); int sprintf(+string,format); ; stdlib.h @@ -92,6 +103,7 @@ string strstr(string,string); ; sys/stat.h int chmod(string,octal); +int fchmod(int,octal); int mkfifo(string,octal); octal umask(octal); @@ -138,6 +150,7 @@ uint sleep(uint); int symlink(string,string); int sync(void); string ttyname(int); +int unlink(string); int write(int, string3, uint); ; SYSCALLS diff --git a/execute_program.c b/execute_program.c index d451f7b..081c0a9 100644 --- a/execute_program.c +++ b/execute_program.c @@ -27,8 +27,8 @@ void execute_program(struct process * sp, char **argv) perror("fork"); exit(1); } else if (!pid) { /* child */ - change_uid(sp); trace_me(); + change_uid(sp); execvp(sp->filename, argv); fprintf(stderr, "Can't execute `%s': %s\n", sp->filename, strerror(errno)); exit(1); @@ -5,21 +5,27 @@ #include <errno.h> #include <sys/param.h> #include <signal.h> +#include <sys/wait.h> #include "ltrace.h" -#include "elf.h" #include "output.h" -#include "config_file.h" +#include "read_config_file.h" #include "options.h" char * command = NULL; struct process * list_of_processes = NULL; +int exiting=0; /* =1 if a SIGINT or SIGTERM has been received */ + static void normal_exit(void); static void signal_exit(int); +static pid_t my_pid; int main(int argc, char **argv) { + struct opt_p_t * opt_p_tmp; + + my_pid = getpid(); atexit(normal_exit); signal(SIGINT,signal_exit); /* Detach processes when interrupted */ signal(SIGTERM,signal_exit); /* ... or killed */ @@ -32,32 +38,67 @@ int main(int argc, char **argv) strcat(path, "/.ltrace.conf"); read_config_file(path); } - while (opt_p) { - open_pid(opt_p->pid, 1); - opt_p = opt_p->next; - } if (command) { execute_program(open_program(command), argv); } + opt_p_tmp = opt_p; + while (opt_p_tmp) { + open_pid(opt_p_tmp->pid, 1); + opt_p_tmp = opt_p_tmp->next; + } while(1) { process_event(wait_for_something()); } } -static void signal_exit(int sig) -{ - exit(2); -} - -static void normal_exit(void) +static void signal_alarm(int sig) { struct process * tmp = list_of_processes; + signal(SIGALRM,SIG_DFL); while(tmp) { + struct opt_p_t * tmp2 = opt_p; + while(tmp2) { + if (tmp->pid == tmp2->pid) { + tmp = tmp->next; + if (!tmp) { + return; + } + break; + } + tmp2 = tmp2->next; + } + if (opt_d>1) { + output_line(0,"Sending SIGSTOP to process %u\n",tmp->pid); + } kill(tmp->pid, SIGSTOP); - disable_all_breakpoints(tmp); - continue_process(tmp->pid); - untrace_pid(tmp->pid); tmp = tmp->next; } } + +static void signal_exit(int sig) +{ + exiting=1; + if (opt_d) { + output_line(0,"Received interrupt signal; exiting..."); + } + signal(SIGINT,SIG_IGN); + signal(SIGTERM,SIG_IGN); + signal(SIGALRM,signal_alarm); + if (opt_p) { + struct opt_p_t * tmp = opt_p; + while(tmp) { + if (opt_d>1) { + output_line(0,"Sending SIGSTOP to process %u\n",tmp->pid); + } + kill(tmp->pid, SIGSTOP); + tmp = tmp->next; + } + } + alarm(1); +} + +static void normal_exit(void) +{ + output_line(0,0); +} @@ -11,6 +11,8 @@ extern char * command; +extern int exiting; /* =1 if we have to exit ASAP */ + struct breakpoint { void * addr; unsigned char orig_value[BREAKPOINT_LENGTH]; @@ -72,13 +72,16 @@ void output_line(struct process * proc, char *fmt, ...) if (current_pid) { fprintf(output, " <unfinished ...>\n"); } + current_pid=0; + if (!fmt) { + return; + } begin_of_line(LT_TOF_NONE, proc); va_start(args, fmt); vfprintf(output, fmt, args); fprintf(output, "\n"); va_end(args); - current_pid=0; current_column=0; } diff --git a/process_event.c b/process_event.c index c4a3b1f..e5ca870 100644 --- a/process_event.c +++ b/process_event.c @@ -2,6 +2,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <signal.h> #include "ltrace.h" #include "output.h" @@ -90,15 +91,23 @@ static char * sysname(int sysnum) } } +static void remove_proc(struct process * proc); + static void process_signal(struct event * event) { + if (exiting && event->e_un.signum == SIGSTOP) { + pid_t pid = event->proc->pid; + disable_all_breakpoints(event->proc); + untrace_pid(pid); + remove_proc(event->proc); + continue_after_signal(pid, event->e_un.signum); + return; + } output_line(event->proc, "--- %s (%s) ---", shortsignal(event->e_un.signum), strsignal(event->e_un.signum)); continue_after_signal(event->proc->pid, event->e_un.signum); } -static void remove_proc(struct process * proc); - static void process_exit(struct event * event) { output_line(event->proc, "+++ exited (status %d) +++", @@ -117,6 +126,10 @@ static void remove_proc(struct process * proc) { struct process *tmp, *tmp2; + if (opt_d) { + output_line(0,"Removing pid %u\n", proc->pid); + } + if (list_of_processes == proc) { tmp = list_of_processes; list_of_processes = list_of_processes->next; @@ -129,6 +142,7 @@ static void remove_proc(struct process * proc) tmp2 = tmp->next; tmp->next = tmp->next->next; free(tmp2); + continue; } tmp = tmp->next; } diff --git a/config_file.c b/read_config_file.c index 1b03465..c6d6cb1 100644 --- a/config_file.c +++ b/read_config_file.c @@ -3,7 +3,7 @@ #include <ctype.h> #include "ltrace.h" -#include "config_file.h" +#include "read_config_file.h" #include "options.h" #include "output.h" diff --git a/config_file.h b/read_config_file.h index 9230c0a..9230c0a 100644 --- a/config_file.h +++ b/read_config_file.h diff --git a/wait_for_something.c b/wait_for_something.c index b5d8845..13ce577 100644 --- a/wait_for_something.c +++ b/wait_for_something.c @@ -21,6 +21,12 @@ struct event * wait_for_something(void) int status; int tmp; + if (!list_of_processes) { + if (opt_d) { + output_line(0, "No more children"); + } + exit(0); + } pid = wait(&status); if (pid==-1) { if (errno==ECHILD) { @@ -28,6 +34,12 @@ struct event * wait_for_something(void) output_line(0, "No more children"); } exit(0); + } else if (errno==EINTR) { + if (opt_d) { + output_line(0, "wait received EINTR ?"); + } + event.thing = LT_EV_NONE; + return &event; } perror("wait"); exit(1); |