aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Cespedes <cespedes@debian.org>1998-04-04 08:34:07 +0200
committerJuan Cespedes <cespedes@debian.org>1998-04-04 08:34:07 +0200
commit5e0acdb26c98f0d95a5266e579669b5c19eb02ce (patch)
tree8fbaea08e9f2de3201fbc91537d98d1e2c0daa8d
parent35d70634aacdf85a3cdf85792ce68989e27bc9c2 (diff)
downloadltrace-5e0acdb26c98f0d95a5266e579669b5c19eb02ce.tar.gz
Version: 0.2.8
* Fix important bug regarding -p: disable all breakpoints on exit (Bug#20616) * Compile cleanly on libc5 * Added `-t' option (Bug#20615)
-rw-r--r--TODO2
-rw-r--r--breakpoints.c6
-rw-r--r--debian/changelog8
-rw-r--r--etc/ltrace.conf16
-rw-r--r--ltrace.113
-rw-r--r--ltrace.c25
-rw-r--r--options.c31
-rw-r--r--options.h1
-rw-r--r--output.c21
-rw-r--r--process_event.c9
-rw-r--r--sysdeps/Linux/i386/regs.c8
-rw-r--r--sysdeps/Linux/i386/trace.c26
12 files changed, 133 insertions, 33 deletions
diff --git a/TODO b/TODO
index ba8f411..87f3971 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,5 @@
* Regarding option -p: disable breakpoints on exit
+* Option -e
* Improve documentation
* Display different argument types:
+ format
@@ -8,3 +9,4 @@
+ almost all...
* netscape:
+ Why does it show so many `breakpointed at:' messages?
+* Option -T
diff --git a/breakpoints.c b/breakpoints.c
index ded819d..e4c7cfe 100644
--- a/breakpoints.c
+++ b/breakpoints.c
@@ -14,6 +14,9 @@ void enable_all_breakpoints(struct process * proc)
insert_breakpoint(proc->pid, &tmp->brk);
tmp = tmp->next;
}
+ if (proc->current_symbol) {
+ insert_breakpoint(proc->pid, &proc->return_value);
+ }
}
proc->breakpoints_enabled = 1;
}
@@ -30,6 +33,9 @@ void disable_all_breakpoints(struct process * proc)
delete_breakpoint(proc->pid, &tmp->brk);
tmp = tmp->next;
}
+ if (proc->current_symbol) {
+ delete_breakpoint(proc->pid, &proc->return_value);
+ }
}
proc->breakpoints_enabled = 0;
}
diff --git a/debian/changelog b/debian/changelog
index 4ef9fd1..87716c3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+ltrace (0.2.8) frozen unstable; urgency=low
+
+ * Fix important bug regarding -p: disable all breakpoints on exit (Bug#20616)
+ * Compile cleanly on libc5
+ * Added `-t' option (Bug#20615)
+
+ -- Juan Cespedes <cespedes@debian.org> Sat, 4 Apr 1998 08:34:03 +0200
+
ltrace (0.2.7) unstable; urgency=low
* Some minor fixes
diff --git a/etc/ltrace.conf b/etc/ltrace.conf
index d67fea6..afe1584 100644
--- a/etc/ltrace.conf
+++ b/etc/ltrace.conf
@@ -38,6 +38,7 @@ int _IO_putc(char,file);
string setlocale(int, string);
; pwd.h
+string getpass(string);
void endpwent(void);
addr getpwnam(string);
@@ -51,6 +52,7 @@ int kill(int,int);
int fclose(file);
int ferror(file);
int fflush(file);
+char fgetc(file);
addr fgets(+string, uint, file);
int fileno(file);
int fprintf(file,format);
@@ -99,6 +101,11 @@ int uname(addr);
; sys/vfs.h
int statfs(string,addr);
+; syslog.h
+void closelog(void);
+void openlog(string,int,int);
+void syslog(int,format);
+
; term.h
int tputs(string, int, addr);
@@ -108,20 +115,29 @@ int time(addr);
; unistd.h
int chown(string,int,int);
int close(int);
+string crypt(string,addr);
int execlp(string,string,addr,addr,addr);
int fork(void);
string2 getcwd(addr,uint);
int geteuid(void);
+int getegid(void);
+int getgid(void);
int gethostname(+string2,int);
+string getlogin(void);
int getpid(void);
+int getuid(void);
int isatty(int);
int mkdir(string,octal);
int read(int, +string0, uint);
int rmdir(string);
+int setgid(int);
int sethostname(+string2,int);
+int setpgid(int,int);
+int setuid(int);
uint sleep(uint);
int symlink(string,string);
int sync(void);
+string ttyname(int);
int write(int, string3, uint);
; SYSCALLS
diff --git a/ltrace.1 b/ltrace.1
index 281a2c5..53ef378 100644
--- a/ltrace.1
+++ b/ltrace.1
@@ -6,7 +6,7 @@ ltrace \- A library call tracer
.SH SYNOPSIS
.B ltrace
-.I "[-difLS] [-a column] [-s strsize] [-o filename] [-u username] [-p pid] ... [command [arg ...]]"
+.I "[-difLSttt] [-a column] [-s strsize] [-o filename] [-u username] [-p pid] ... [command [arg ...]]"
.SH DESCRIPTION
.B ltrace
@@ -41,6 +41,17 @@ option).
.I \-S
Display system calls as well as library calls
.TP
+.I \-t
+Prefix each line of the trace with the time of day.
+.TP
+.I \-tt
+If given twice, the time printed will include the microseconds.
+.TP
+.I \-ttt
+If given thrice, the time printed will include the microseconds and
+the leading portion will be printed as the number of seconds since the
+epoch.
+.TP
.I \-a column
Align return values in a secific column (default column 50).
.TP
diff --git a/ltrace.c b/ltrace.c
index 3b7a387..1ce1108 100644
--- a/ltrace.c
+++ b/ltrace.c
@@ -4,6 +4,7 @@
#include <string.h>
#include <errno.h>
#include <sys/param.h>
+#include <signal.h>
#include "ltrace.h"
#include "elf.h"
@@ -14,8 +15,15 @@
char * command = NULL;
struct process * list_of_processes = NULL;
+static void normal_exit(void);
+static void signal_exit(int);
+
int main(int argc, char **argv)
{
+ atexit(normal_exit);
+ signal(SIGINT,signal_exit); /* Detach processes when interrupted */
+ signal(SIGTERM,signal_exit); /* ... or killed */
+
argv = process_options(argc, argv);
read_config_file("/etc/ltrace.conf");
if (getenv("HOME")) {
@@ -36,3 +44,20 @@ int main(int argc, char **argv)
}
}
+static void signal_exit(int sig)
+{
+ exit(2);
+}
+
+static void normal_exit(void)
+{
+ struct process * tmp = list_of_processes;
+
+ while(tmp) {
+ kill(tmp->pid, SIGSTOP);
+ disable_all_breakpoints(tmp);
+ continue_process(tmp->pid);
+ untrace_pid(tmp->pid);
+ tmp = tmp->next;
+ }
+}
diff --git a/options.c b/options.c
index 99a3baa..0b556d8 100644
--- a/options.c
+++ b/options.c
@@ -17,13 +17,14 @@ int opt_S = 0; /* display syscalls */
int opt_L = 1; /* display library calls */
int opt_f = 0; /* trace child processes as they are created */
char * opt_u = NULL; /* username to run command as */
+int opt_t = 0; /* print absolute timestamp */
/* List of pids given to option -p: */
struct opt_p_t * opt_p = NULL; /* attach to process with a given pid */
static void usage(void)
{
- fprintf(stderr, "Usage: ltrace [-dfiLS] [-a column] [-s strlen] [-o filename]\n"
+ fprintf(stderr, "Usage: ltrace [-dfiLSttt] [-a column] [-s strlen] [-o filename]\n"
" [-u username] [-p pid] ... [command [arg ...]]\n\n");
}
@@ -70,11 +71,25 @@ char ** process_options(int argc, char **argv)
argc--; argv++;
}
switch (*nextchar++) {
+ case 'd': opt_d++;
+ break;
+ case 'f': opt_f = 1;
+ break;
+ case 'i': opt_i++;
+ break;
+ case 'L': opt_L = 0;
+ break;
+ case 'S': opt_S = 1;
+ break;
+ case 't': opt_t++;
+ break;
case 'a': if (!argv[1]) { usage(); exit(1); }
opt_a = atoi(argv[1]);
argc--; argv++;
break;
- case 'd': opt_d++;
+ case 's': if (!argv[1]) { usage(); exit(1); }
+ opt_s = atoi(argv[1]);
+ argc--; argv++;
break;
case 'o': if (!argv[1]) { usage(); exit(1); }
output = fopen(argv[1], "w");
@@ -84,18 +99,6 @@ char ** process_options(int argc, char **argv)
}
argc--; argv++;
break;
- case 'i': opt_i++;
- break;
- case 's': if (!argv[1]) { usage(); exit(1); }
- opt_s = atoi(argv[1]);
- argc--; argv++;
- break;
- case 'L': opt_L = 0;
- break;
- case 'S': opt_S = 1;
- break;
- case 'f': opt_f = 1;
- break;
case 'u': if (!argv[1]) { usage(); exit(1); }
opt_u = argv[1];
argc--; argv++;
diff --git a/options.h b/options.h
index da17154..c22d3d6 100644
--- a/options.h
+++ b/options.h
@@ -9,6 +9,7 @@ extern int opt_L; /* display library calls */
extern int opt_S; /* display system calls */
extern int opt_f; /* trace child processes */
extern char * opt_u; /* username to run command as */
+extern int opt_t; /* print absolute timestamp */
struct opt_p_t {
pid_t pid;
diff --git a/output.c b/output.c
index d1284c1..9beab40 100644
--- a/output.c
+++ b/output.c
@@ -1,5 +1,8 @@
#include <stdio.h>
#include <stdarg.h>
+#include <time.h>
+#include <sys/time.h>
+#include <unistd.h>
#include "ltrace.h"
#include "options.h"
@@ -19,6 +22,24 @@ static void begin_of_line(enum tof type, struct process * proc)
} else if (list_of_processes->next) {
current_column += fprintf(output, "[pid %u] ", proc->pid);
}
+ if (opt_t) {
+ struct timeval tv;
+ struct timezone tz;
+ struct tm * tmp;
+
+ gettimeofday(&tv, &tz);
+ tmp = localtime(&tv.tv_sec);
+ if (opt_t>2) {
+ current_column += fprintf(output, "%lu.%06d ",
+ tv.tv_sec, (int)tv.tv_usec);
+ } else if (opt_t>1) {
+ current_column += fprintf(output, "%02d:%02d:%02d.%06d ",
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec, (int)tv.tv_usec);
+ } else {
+ current_column += fprintf(output, "%02d:%02d:%02d ",
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+ }
+ }
if (opt_i) {
if (type==LT_TOF_FUNCTION) {
current_column += fprintf(output, "[%08x] ",
diff --git a/process_event.c b/process_event.c
index f3c5295..c4a3b1f 100644
--- a/process_event.c
+++ b/process_event.c
@@ -142,9 +142,6 @@ static void process_syscall(struct event * event)
}
if (fork_p(event->e_un.sysnum) || exec_p(event->e_un.sysnum)) {
disable_all_breakpoints(event->proc);
- if (event->proc->current_symbol) {
- delete_breakpoint(event->proc->pid, &event->proc->return_value);
- }
} else if (!event->proc->breakpoints_enabled) {
enable_all_breakpoints(event->proc);
}
@@ -163,9 +160,6 @@ static void process_sysret(struct event * event)
event->proc->breakpoints_enabled = -1;
} else {
enable_all_breakpoints(event->proc);
- if (event->proc->current_symbol) {
- insert_breakpoint(event->proc->pid, &event->proc->return_value);
- }
}
}
if (fork_p(event->e_un.sysnum)) {
@@ -176,9 +170,6 @@ static void process_sysret(struct event * event)
}
}
enable_all_breakpoints(event->proc);
- if (event->proc->current_symbol) {
- insert_breakpoint(event->proc->pid, &event->proc->return_value);
- }
}
event->proc->current_syscall = -1;
continue_process(event->proc->pid);
diff --git a/sysdeps/Linux/i386/regs.c b/sysdeps/Linux/i386/regs.c
index fb737d1..2e51297 100644
--- a/sysdeps/Linux/i386/regs.c
+++ b/sysdeps/Linux/i386/regs.c
@@ -1,6 +1,14 @@
#include <sys/types.h>
#include <sys/ptrace.h>
+#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
+# define PTRACE_PEEKUSER PTRACE_PEEKUSR
+#endif
+
+#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
+# define PTRACE_POKEUSER PTRACE_POKEUSR
+#endif
+
int get_instruction_pointer(pid_t pid)
{
return ptrace(PTRACE_PEEKUSER, pid, 4*EIP, 0);
diff --git a/sysdeps/Linux/i386/trace.c b/sysdeps/Linux/i386/trace.c
index e9d3027..fb862ad 100644
--- a/sysdeps/Linux/i386/trace.c
+++ b/sysdeps/Linux/i386/trace.c
@@ -5,12 +5,20 @@
#include "ltrace.h"
+#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
+# define PTRACE_PEEKUSER PTRACE_PEEKUSR
+#endif
+
+#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
+# define PTRACE_POKEUSER PTRACE_POKEUSR
+#endif
+
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
int syscall_p(struct process * proc, int status, int * sysnum)
{
if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
- *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4*ORIG_EAX);
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4*ORIG_EAX, 0);
if (*sysnum>=0) {
if (proc->current_syscall!=*sysnum) {
return 1;
@@ -37,25 +45,25 @@ void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp, in
long gimme_arg(enum tof type, struct process * proc, int arg_num)
{
if (arg_num==-1) { /* return value */
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EAX);
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EAX, 0);
}
if (type==LT_TOF_FUNCTION) {
- return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+4*(arg_num+1));
+ return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+4*(arg_num+1), 0);
} else if (type==LT_TOF_SYSCALL) {
#if 0
switch(arg_num) {
- case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EBX);
- case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ECX);
- case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDX);
- case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ESI);
- case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDI);
+ case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EBX, 0);
+ case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ECX, 0);
+ case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDX, 0);
+ case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ESI, 0);
+ case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDI, 0);
default:
fprintf(stderr, "gimme_arg called with wrong arguments\n");
exit(2);
}
#else
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num);
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num, 0);
#endif
} else {
fprintf(stderr, "gimme_arg called with wrong arguments\n");