aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUGS2
-rw-r--r--Makefile.in3
-rw-r--r--README4
-rw-r--r--breakpoints.c159
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure111
-rw-r--r--configure.in3
-rw-r--r--debian/changelog8
-rw-r--r--debian/control2
-rw-r--r--debian/copyright2
-rwxr-xr-xdebian/rules2
-rw-r--r--debug.c21
-rw-r--r--debug.h20
-rw-r--r--demangle.c117
-rw-r--r--dict.c151
-rw-r--r--dict.h18
-rw-r--r--elf.c24
-rw-r--r--execute_program.c58
-rw-r--r--ltrace.c17
-rw-r--r--ltrace.h2
-rw-r--r--options.c2
-rw-r--r--proc.c1
-rw-r--r--process_event.c39
-rw-r--r--read_config_file.c26
-rw-r--r--wait_for_something.c18
25 files changed, 367 insertions, 446 deletions
diff --git a/BUGS b/BUGS
index 2f3576e..c3be4a1 100644
--- a/BUGS
+++ b/BUGS
@@ -2,4 +2,4 @@
* Manual page is not accurate (config files...)
* elf.c only supports elf32 binaries
* netscape sometimes dies with SIGSEGV (is this still true?)
-* It only works on Linux/i386, Linux/m68k, and Linux/arm
+* It lacks support for several Linux archs, and many operating systems
diff --git a/Makefile.in b/Makefile.in
index 37f4873..2ca7e1f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -21,7 +21,8 @@ LIBS = @LIBS@
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 demangle.o
+ display_args.o breakpoints.o proc.o demangle.o dict.o \
+ debug.o
all: ltrace
diff --git a/README b/README
index 65cb433..992d9fe 100644
--- a/README
+++ b/README
@@ -2,7 +2,7 @@
A Dynamic Library Tracer
- Copyright 1997-2002 Juan Cespedes <cespedes@debian.org>
+ Copyright 1997-2003 Juan Cespedes <cespedes@debian.org>
Contents
@@ -67,7 +67,7 @@ This file is very incomplete and out-of-date.
6. License
----------
- Copyright (C) 1997-2002 Juan Cespedes <cespedes@debian.org>
+ Copyright (C) 1997-2003 Juan Cespedes <cespedes@debian.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/breakpoints.c b/breakpoints.c
index 9b113a7..73dd638 100644
--- a/breakpoints.c
+++ b/breakpoints.c
@@ -2,10 +2,6 @@
#include "config.h"
#endif
-#include "ltrace.h"
-#include "options.h"
-#include "output.h"
-
#include <stdlib.h>
#include <assert.h>
@@ -13,134 +9,43 @@
#include <sys/ptrace.h>
#endif
-/*****************************************************************************/
-
-/*
- Dictionary code done by Morten Eriksen <mortene@sim.no>.
-
- FIXME: should we merge with dictionary code in demangle.c? 19990704 mortene.
-*/
-
-struct dict_entry {
- struct process * proc;
- struct breakpoint brk; /* addr field of struct is the hash key. */
- struct dict_entry * next;
-};
-
-#define DICTTABLESIZE 997 /* Semi-randomly selected prime number. */
-static struct dict_entry * dict_buckets[DICTTABLESIZE];
-static int dict_initialized = 0;
-
-static void dict_init(void);
-static void dict_clear(void);
-static struct breakpoint * dict_enter(struct process * proc, void * brkaddr);
-struct breakpoint * dict_find_entry(struct process * proc, void * brkaddr);
-static void dict_apply_to_all(void (* func)(struct process *, struct breakpoint *, void * data), void * data);
-
-
-static void
-dict_init(void) {
- int i;
- /* FIXME: is this necessary? Check with ANSI C spec. 19990702 mortene. */
- for (i = 0; i < DICTTABLESIZE; i++) dict_buckets[i] = NULL;
- dict_initialized = 1;
-}
-
-static void
-dict_clear(void) {
- int i;
- struct dict_entry * entry, * nextentry;
-
- for (i = 0; i < DICTTABLESIZE; i++) {
- for (entry = dict_buckets[i]; entry != NULL; entry = nextentry) {
- nextentry = entry->next;
- free(entry);
- }
- dict_buckets[i] = NULL;
- }
-}
-
-static struct breakpoint *
-dict_enter(struct process * proc, void * brkaddr) {
- struct dict_entry * entry, * newentry;
- unsigned int bucketpos = ((unsigned long int)brkaddr) % DICTTABLESIZE;
-
- newentry = malloc(sizeof(struct dict_entry));
- if (!newentry) {
- perror("malloc");
- return NULL;
- }
-
- newentry->proc = proc;
- newentry->brk.addr = brkaddr;
- newentry->brk.enabled = 0;
- newentry->next = NULL;
-
- entry = dict_buckets[bucketpos];
- while (entry && entry->next) entry = entry->next;
-
- if (entry) entry->next = newentry;
- else dict_buckets[bucketpos] = newentry;
-
- if (opt_d > 2)
- output_line(0, "new brk dict entry at %p\n", brkaddr);
-
- return &(newentry->brk);
-}
-
-struct breakpoint *
-dict_find_entry(struct process * proc, void * brkaddr) {
- unsigned int bucketpos = ((unsigned long int)brkaddr) % DICTTABLESIZE;
- struct dict_entry * entry = dict_buckets[bucketpos];
- while (entry) {
- if ((entry->brk.addr == brkaddr) && (entry->proc == proc)) break;
- entry = entry->next;
- }
- return entry ? &(entry->brk) : NULL;
-}
-
-static void
-dict_apply_to_all(void (* func)(struct process *, struct breakpoint *, void * data), void * data) {
- int i;
-
- for (i = 0; i < DICTTABLESIZE; i++) {
- struct dict_entry * entry = dict_buckets[i];
- while (entry) {
- func(entry->proc, &(entry->brk), data);
- entry = entry->next;
- }
- }
-}
-
-#undef DICTTABLESIZE
+#include "ltrace.h"
+#include "options.h"
+#include "debug.h"
+#include "dict.h"
/*****************************************************************************/
struct breakpoint *
address2bpstruct(struct process * proc, void * addr) {
- return dict_find_entry(proc, addr);
+ return dict_find_entry(proc->breakpoints, addr);
}
void
insert_breakpoint(struct process * proc, void * addr) {
struct breakpoint * sbp;
- if (!dict_initialized) {
- dict_init();
- atexit(dict_clear);
+ if (!proc->breakpoints) {
+ proc->breakpoints = dict_init(dict_key2hash_int, dict_key_cmp_int);
+ /* atexit(brk_dict_clear); */ /* why bother to do this on exit? */
+ }
+ sbp = dict_find_entry(proc->breakpoints, addr);
+ if (!sbp) {
+ sbp = malloc(sizeof(struct breakpoint));
+ if (!sbp) {
+ return; /* TODO FIXME XXX: error_mem */
+ }
+ dict_enter(proc->breakpoints, addr, sbp);
+ sbp->addr = addr;
+ sbp->enabled = 0;
}
-
- sbp = dict_find_entry(proc, addr);
- if (!sbp) sbp = dict_enter(proc, addr);
- if (!sbp) return;
-
sbp->enabled++;
if (sbp->enabled==1 && proc->pid) enable_breakpoint(proc->pid, sbp);
}
void
delete_breakpoint(struct process * proc, void * addr) {
- struct breakpoint * sbp = dict_find_entry(proc, addr);
+ struct breakpoint * sbp = dict_find_entry(proc->breakpoints, addr);
assert(sbp); /* FIXME: remove after debugging has been done. */
/* This should only happen on out-of-memory conditions. */
if (sbp == NULL) return;
@@ -151,9 +56,10 @@ delete_breakpoint(struct process * proc, void * addr) {
}
static void
-enable_bp_cb(struct process * proc, struct breakpoint * sbp, void * data) {
- struct process * myproc = (struct process *)data;
- if (myproc == proc && sbp->enabled) enable_breakpoint(proc->pid, sbp);
+enable_bp_cb(void * addr, void * sbp, void * proc) {
+ if (((struct breakpoint *)sbp)->enabled) {
+ enable_breakpoint(((struct process *)proc)->pid, sbp);
+ }
}
void
@@ -174,27 +80,24 @@ enable_all_breakpoints(struct process * proc) {
}
#endif
- if (opt_d>0) {
- output_line(0, "Enabling breakpoints for pid %u...", proc->pid);
- }
- dict_apply_to_all(enable_bp_cb, proc);
+ debug(1, "Enabling breakpoints for pid %u...", proc->pid);
+ dict_apply_to_all(proc->breakpoints, enable_bp_cb, proc);
}
proc->breakpoints_enabled = 1;
}
static void
-disable_bp_cb(struct process * proc, struct breakpoint * sbp, void * data) {
- struct process * myproc = (struct process *)data;
- if (myproc == proc && sbp->enabled) disable_breakpoint(proc->pid, sbp);
+disable_bp_cb(void * addr, void * sbp, void * proc) {
+ if (((struct breakpoint *)sbp)->enabled) {
+ disable_breakpoint(((struct process *)proc)->pid, sbp);
+ }
}
void
disable_all_breakpoints(struct process * proc) {
if (proc->breakpoints_enabled) {
- if (opt_d>0) {
- output_line(0, "Disabling breakpoints for pid %u...", proc->pid);
- }
- dict_apply_to_all(disable_bp_cb, proc);
+ debug(1, "Disabling breakpoints for pid %u...", proc->pid);
+ dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc);
}
proc->breakpoints_enabled = 0;
}
diff --git a/config.h.in b/config.h.in
index 17769ca..1a271ed 100644
--- a/config.h.in
+++ b/config.h.in
@@ -24,8 +24,5 @@
/* Define if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
-/* Define if you have the dl library (-ldl). */
-#undef HAVE_LIBDL
-
/* Define if you have the iberty library (-liberty). */
#undef HAVE_LIBIBERTY
diff --git a/configure b/configure
index 9950894..0cce6dc 100755
--- a/configure
+++ b/configure
@@ -859,63 +859,16 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:864: checking for dlopen in -ldl" >&5
-ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-ldl $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 872 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen();
-
-int main() {
-dlopen()
-; return 0; }
-EOF
-if { (eval echo configure:883: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-ldl $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
echo $ac_n "checking for cplus_demangle in -liberty""... $ac_c" 1>&6
-echo "configure:911: checking for cplus_demangle in -liberty" >&5
+echo "configure:864: checking for cplus_demangle in -liberty" >&5
ac_lib_var=`echo iberty'_'cplus_demangle | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
-LIBS="-liberty -ldl $LIBS"
+LIBS="-liberty $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 919 "configure"
+#line 872 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -926,7 +879,7 @@ int main() {
cplus_demangle()
; return 0; }
EOF
-if { (eval echo configure:930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:883: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -955,7 +908,7 @@ fi
echo $ac_n "checking ltrace version""... $ac_c" 1>&6
-echo "configure:959: checking ltrace version" >&5
+echo "configure:912: checking ltrace version" >&5
ltrace_version=`sed -n '1s/ltrace (\([0-9.]\+\)).*/\1/p' ${srcdir}/debian/changelog`
sed -e "s/@VERSION@/${ltrace_version}/g" \
@@ -965,7 +918,7 @@ echo "$ac_t""$ltrace_version" 1>&6
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:969: checking how to run the C preprocessor" >&5
+echo "configure:922: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -980,13 +933,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 984 "configure"
+#line 937 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:990: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:943: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -997,13 +950,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 1001 "configure"
+#line 954 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1007: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:960: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1014,13 +967,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 1018 "configure"
+#line 971 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1024: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:977: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1045,12 +998,12 @@ fi
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1049: checking for ANSI C header files" >&5
+echo "configure:1002: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1054 "configure"
+#line 1007 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1058,7 +1011,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1062: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1015: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1075,7 +1028,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1079 "configure"
+#line 1032 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1093,7 +1046,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1097 "configure"
+#line 1050 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1114,7 +1067,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 1118 "configure"
+#line 1071 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1125,7 +1078,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-if { (eval echo configure:1129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
@@ -1152,17 +1105,17 @@ for ac_hdr in getopt.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1156: checking for $ac_hdr" >&5
+echo "configure:1109: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1161 "configure"
+#line 1114 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1166: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1119: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1189,12 +1142,12 @@ fi
done
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1193: checking for working const" >&5
+echo "configure:1146: checking for working const" >&5
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1198 "configure"
+#line 1151 "configure"
#include "confdefs.h"
int main() {
@@ -1243,7 +1196,7 @@ ccp = (char const *const *) p;
; return 0; }
EOF
-if { (eval echo configure:1247: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1200: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
@@ -1264,12 +1217,12 @@ EOF
fi
echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:1268: checking for uid_t in sys/types.h" >&5
+echo "configure:1221: checking for uid_t in sys/types.h" >&5
if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1273 "configure"
+#line 1226 "configure"
#include "confdefs.h"
#include <sys/types.h>
EOF
@@ -1298,12 +1251,12 @@ EOF
fi
echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:1302: checking for pid_t" >&5
+echo "configure:1255: checking for pid_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1307 "configure"
+#line 1260 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1333,12 +1286,12 @@ fi
for ac_func in getopt getopt_long
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1337: checking for $ac_func" >&5
+echo "configure:1290: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1342 "configure"
+#line 1295 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1361,7 +1314,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1365: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1318: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
diff --git a/configure.in b/configure.in
index 35acb4a..98dd645 100644
--- a/configure.in
+++ b/configure.in
@@ -12,8 +12,7 @@ AC_PROG_CC
AC_PROG_INSTALL
dnl Checks for libraries.
-AC_CHECK_LIB(dl, dlopen)
-AC_CHECK_LIB(iberty, cplus_demangle,,,-ldl)
+AC_CHECK_LIB(iberty, cplus_demangle,,,)
AC_MSG_CHECKING(ltrace version)
changequote(<<, >>)
diff --git a/debian/changelog b/debian/changelog
index 00f14b9..89b41ad 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+ltrace (0.3.27) unstable; urgency=low
+
+ * Removed dependency on libdl (it is no longer needed)
+ * Wrote generic dictionary, used in demangle.c and breakpoints.c
+ * Added debug.c for better debugging output
+
+ -- Juan Cespedes <cespedes@debian.org> Fri, 31 Jan 2003 18:58:55 +0100
+
ltrace (0.3.26) unstable; urgency=low
* Fixed `ltrace -L' in powerpc
diff --git a/debian/control b/debian/control
index 1de2c81..3e546bb 100644
--- a/debian/control
+++ b/debian/control
@@ -2,7 +2,7 @@ Source: ltrace
Section: utils
Priority: optional
Maintainer: Juan Cespedes <cespedes@debian.org>
-Standards-Version: 3.5.5
+Standards-Version: 3.5.6
Build-Depends: binutils-dev
Package: ltrace
diff --git a/debian/copyright b/debian/copyright
index 1893192..31535aa 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -4,7 +4,7 @@ Dynamic Library Tracer ``ltrace''.
Copyrights
----------
-Copyright (C) 1997-2002 Juan Cespedes <cespedes@debian.org>
+Copyright (C) 1997-2003 Juan Cespedes <cespedes@debian.org>
ARMLinux port: Copyright (C) 1998 Pat Beirne <pbeirne@home.com>
m68k port: Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
diff --git a/debian/rules b/debian/rules
index 6cd930a..5f7eb45 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,6 +1,6 @@
#! /usr/bin/make -f
#
-# Copyright (C) 1997-2002 Juan Cespedes <cespedes@debian.org>
+# Copyright (C) 1997-2003 Juan Cespedes <cespedes@debian.org>
.PHONY: binary binary-indep binary-arch clean
diff --git a/debug.c b/debug.c
new file mode 100644
index 0000000..125974a
--- /dev/null
+++ b/debug.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "debug.h"
+#include "options.h"
+#include "output.h"
+
+void
+debug_(int level, char *file, int line, char *func, char *fmt, ...) {
+ char buf[1024];
+ va_list args;
+
+ if (opt_d < level) {
+ return;
+ }
+ va_start(args, fmt);
+ vsnprintf(buf, 1024, fmt, args);
+ va_end(args);
+
+ output_line(NULL, "DEBUG: %s:%d: %s(): %s", file, line, func, buf);
+}
diff --git a/debug.h b/debug.h
new file mode 100644
index 0000000..90a10e5
--- /dev/null
+++ b/debug.h
@@ -0,0 +1,20 @@
+#include <features.h>
+
+void debug_(int level, char *file, int line, char *func, char *fmt, ...);
+
+# define debug(level, expr...) debug_(level, __FILE__, __LINE__, DEBUG_FUNCTION, expr)
+
+/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
+ which contains the name of the function currently being defined.
+ This is broken in G++ before version 2.6.
+ C9x has a similar variable called __func__, but prefer the GCC one since
+ it demangles C++ function names. */
+# if __GNUC_PREREQ (2, 4)
+# define DEBUG_FUNCTION __PRETTY_FUNCTION__
+# else
+# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+# define DEBUG_FUNCTION __func__
+# else
+# define DEBUG_FUNCTION ((__const char *) 0)
+# endif
+# endif
diff --git a/demangle.c b/demangle.c
index 8f0d24e..73fbf06 100644
--- a/demangle.c
+++ b/demangle.c
@@ -12,128 +12,33 @@
#include "output.h"
#include "demangle.h"
-/*****************************************************************************/
-
-/*
- The string dictionary code done by Morten Eriksen <mortene@sim.no>.
-
- FIXME: since this is a generic string dictionary, it should perhaps
- be cleaned up a bit, "object-ified" and placed in its own .c + .h
- pair of files? 19990702 mortene.
-*/
-
-struct dict_entry
-{
- unsigned int key;
- const char * mangled, * demangled;
- struct dict_entry * next;
-};
+#include "dict.h"
-#define DICTTABLESIZE 997 /* Semi-randomly selected prime number. */
-static struct dict_entry * dict_buckets[DICTTABLESIZE];
-static int dict_initialized = 0;
-
-static void dict_init(void);
-static void dict_clear(void);
-static void dict_enter(const char * mangled, const char * demangled);
-static const char * dict_find_entry(const char * mangled);
-static unsigned int dict_hash_string(const char * s);
-
-
-static void
-dict_init(void) {
- int i;
- /* FIXME: is this necessary? Check with ANSI C spec. 19990702 mortene. */
- for (i = 0; i < DICTTABLESIZE; i++) dict_buckets[i] = NULL;
- dict_initialized = 1;
-}
+/*****************************************************************************/
-static void
-dict_clear(void) {
- int i;
- struct dict_entry * entry, * nextentry;
-
- for (i = 0; i < DICTTABLESIZE; i++) {
- for (entry = dict_buckets[i]; entry != NULL; entry = nextentry) {
- nextentry = entry->next;
- free((void *)(entry->mangled));
- if (entry->mangled != entry->demangled)
- free((void *)(entry->demangled));
- free(entry);
- }
- dict_buckets[i] = NULL;
- }
-}
+static struct dict * d = NULL;
static void
-dict_enter(const char * mangled, const char * demangled) {
- struct dict_entry * entry, * newentry;
- unsigned int key = dict_hash_string(mangled);
-
- newentry = malloc(sizeof(struct dict_entry));
- if (!newentry) {
- perror("malloc");
- return;
- }
-
- newentry->key = key;
- newentry->mangled = mangled;
- newentry->demangled = demangled;
- newentry->next = NULL;
-
- entry = dict_buckets[key % DICTTABLESIZE];
- while (entry && entry->next) entry = entry->next;
-
- if (entry) entry->next = newentry;
- else dict_buckets[key % DICTTABLESIZE] = newentry;
-
- if (opt_d > 2)
- output_line(0, "new dict entry: '%s' -> '%s'\n", mangled, demangled);
-}
-
-static const char *
-dict_find_entry(const char * mangled) {
- unsigned int key = dict_hash_string(mangled);
- struct dict_entry * entry = dict_buckets[key % DICTTABLESIZE];
- while (entry) {
- if ((entry->key == key) && (strcmp(entry->mangled, mangled) == 0)) break;
- entry = entry->next;
- }
- return entry ? entry->demangled : NULL;
+my_demangle_dict_clear(void) {
+ /* FIXME TODO XXX: I should also free all (key,value) pairs */
+ dict_clear(d);
}
-static unsigned int
-dict_hash_string(const char * s) {
- unsigned int total = 0, shift = 0;
-
- while (*s) {
- total = total ^ ((*s) << shift);
- shift += 5;
- if (shift > 24) shift -= 24;
- s++;
- }
- return total;
-}
-
-#undef DICTTABLESIZE
-
-/*****************************************************************************/
-
const char *
my_demangle(const char * function_name) {
const char * tmp, * fn_copy;
- if (!dict_initialized) {
- dict_init();
- atexit(dict_clear);
+ if (!d) {
+ d = dict_init(dict_key2hash_string, dict_key_cmp_string);
+ atexit(my_demangle_dict_clear);
}
- tmp = dict_find_entry(function_name);
+ tmp = dict_find_entry(d, (void *)function_name);
if (!tmp) {
fn_copy = strdup(function_name);
tmp = cplus_demangle(function_name+strspn(function_name, "_"), DMGL_ANSI | DMGL_PARAMS);
if (!tmp) tmp = fn_copy;
- if (tmp) dict_enter(fn_copy, tmp);
+ if (tmp) dict_enter(d, (void *)fn_copy, (void *)tmp);
}
return tmp;
}
diff --git a/dict.c b/dict.c
new file mode 100644
index 0000000..f428820
--- /dev/null
+++ b/dict.c
@@ -0,0 +1,151 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "debug.h"
+
+/*
+ Dictionary based on code by Morten Eriksen <mortene@sim.no>.
+*/
+
+#include "dict.h"
+
+struct dict_entry {
+ unsigned int hash;
+ void * key;
+ void * value;
+ struct dict_entry * next;
+};
+
+/* #define DICTTABLESIZE 97 */
+#define DICTTABLESIZE 997 /* Semi-randomly selected prime number. */
+/* #define DICTTABLESIZE 9973 */
+/* #define DICTTABLESIZE 99991 */
+/* #define DICTTABLESIZE 999983 */
+
+struct dict {
+ struct dict_entry * buckets[DICTTABLESIZE];
+ unsigned int (*key2hash)(void *);
+ int (*key_cmp)(void *, void *);
+};
+
+struct dict *
+dict_init(unsigned int (*key2hash)(void *), int (*key_cmp)(void *, void *)) {
+ struct dict * d;
+ int i;
+
+ d = malloc(sizeof(struct dict));
+ if (!d) {
+ perror("malloc()");
+ exit(1);
+ }
+ for (i = 0; i < DICTTABLESIZE; i++) { /* better use memset()? */
+ d->buckets[i] = NULL;
+ }
+ d->key2hash = key2hash;
+ d->key_cmp = key_cmp;
+ return d;
+}
+
+void
+dict_clear(struct dict * d) {
+ int i;
+ struct dict_entry * entry, * nextentry;
+
+ for (i = 0; i < DICTTABLESIZE; i++) {
+ for (entry = d->buckets[i]; entry != NULL; entry = nextentry) {
+ nextentry = entry->next;
+ free(entry);
+ }
+ d->buckets[i] = NULL;
+ }
+ free(d);
+}
+
+int
+dict_enter(struct dict * d, void * key, void * value) {
+ struct dict_entry * entry, * newentry;
+ unsigned int hash = d->key2hash(key);
+ unsigned int bucketpos = hash % DICTTABLESIZE;
+
+ newentry = malloc(sizeof(struct dict_entry));
+ if (!newentry) {
+ perror("malloc");
+ exit(1);
+ }
+
+ newentry->hash = hash;
+ newentry->key = key;
+ newentry->value = value;
+ newentry->next = NULL;
+
+ entry = d->buckets[bucketpos];
+ while (entry && entry->next) entry = entry->next;
+
+ if (entry) entry->next = newentry;
+ else d->buckets[bucketpos] = newentry;
+
+ debug(3, "new dict entry at %p[%d]: (%p,%p)\n", d, bucketpos, key, value);
+ return 0;
+}
+
+void *
+dict_find_entry(struct dict * d, void * key) {
+ unsigned int hash = d->key2hash(key);
+ unsigned int bucketpos = hash % DICTTABLESIZE;
+ struct dict_entry * entry;
+
+ for (entry = d->buckets[bucketpos]; entry; entry = entry->next) {
+ if (hash != entry->hash) {
+ continue;
+ }
+ if (!d->key_cmp(key, entry->key)) {
+ break;
+ }
+ }
+ return entry ? entry->value : NULL;
+}
+
+void
+dict_apply_to_all(struct dict * d, void (*func)(void *key, void *value, void *data), void *data) {
+ int i;
+
+ for (i = 0; i < DICTTABLESIZE; i++) {
+ struct dict_entry * entry = d->buckets[i];
+ while (entry) {
+ func(entry->key, entry->value, data);
+ entry = entry->next;
+ }
+ }
+}
+
+/*****************************************************************************/
+
+unsigned int
+dict_key2hash_string(void * key) {
+ const char * s = (const char *)key;
+ unsigned int total = 0, shift = 0;
+
+ while (*s) {
+ total = total ^ ((*s) << shift);
+ shift += 5;
+ if (shift > 24) shift -= 24;
+ s++;
+ }
+ return total;
+}
+
+int
+dict_key_cmp_string(void * key1, void * key2) {
+ return strcmp((const char *)key1, (const char *)key2);
+}
+
+unsigned int
+dict_key2hash_int(void * key) {
+ return (unsigned int)key;
+}
+
+int
+dict_key_cmp_int(void * key1, void * key2) {
+ return key1 - key2;
+}
+
diff --git a/dict.h b/dict.h
new file mode 100644
index 0000000..6be0995
--- /dev/null
+++ b/dict.h
@@ -0,0 +1,18 @@
+/*
+ Dictionary based on code by Morten Eriksen <mortene@sim.no>.
+*/
+
+struct dict;
+
+extern struct dict * dict_init(unsigned int (*key2hash)(void *),
+ int (*key_cmp)(void *, void *));
+extern void dict_clear(struct dict * d);
+extern int dict_enter(struct dict * d, void * key, void * value);
+extern void * dict_find_entry(struct dict * d, void * key);
+extern void dict_apply_to_all(struct dict * d,
+ void (*func)(void *key, void *value, void *data), void *data);
+
+extern unsigned int dict_key2hash_string(void * key);
+extern int dict_key_cmp_string(void * key1, void * key2);
+extern unsigned int dict_key2hash_int(void * key);
+extern int dict_key_cmp_int(void * key1, void * key2);
diff --git a/elf.c b/elf.c
index b3f7a12..d1fb6ca 100644
--- a/elf.c
+++ b/elf.c
@@ -21,8 +21,7 @@
#include "ltrace.h"
#include "elf.h"
-#include "options.h"
-#include "output.h"
+#include "debug.h"
static void do_init_elf(struct ltelf *lte, const char *filename);
static void do_close_elf(struct ltelf *lte);
@@ -42,9 +41,7 @@ static void
do_init_elf(struct ltelf *lte, const char *filename) {
struct stat sbuf;
- if (opt_d > 0) {
- output_line(0, "Reading ELF from %s...", filename);
- }
+ debug(1, "Reading ELF from %s...", filename);
lte->fd = open(filename, O_RDONLY);
if (lte->fd == -1) {
@@ -137,11 +134,9 @@ do_load_elf_symtab(struct ltelf *lte) {
}
}
- if (opt_d > 1) {
- output_line(0, "symtab: 0x%08x", (unsigned)lte->symtab);
- output_line(0, "symtab_len: %lu", lte->symtab_len);
- output_line(0, "strtab: 0x%08x", (unsigned)lte->strtab);
- }
+ debug(2, "symtab: 0x%08x", (unsigned)lte->symtab);
+ debug(2, "symtab_len: %lu", lte->symtab_len);
+ debug(2, "strtab: 0x%08x", (unsigned)lte->strtab);
}
static void
@@ -165,14 +160,9 @@ add_library_symbol(
library_symbols->name = &lte->strtab[lte->symtab[i].st_name];
library_symbols->next = tmp;
- if (opt_d > 1) {
- output_line(
- 0,
- "addr: 0x%08x, symbol: \"%s\"",
+ debug(2, "addr: 0x%08x, symbol: \"%s\"",
(unsigned)lte->symtab[i].st_value,
- &lte->strtab[lte->symtab[i].st_name]
- );
- }
+ &lte->strtab[lte->symtab[i].st_name]);
}
/*
diff --git a/execute_program.c b/execute_program.c
index 0306678..6efc03c 100644
--- a/execute_program.c
+++ b/execute_program.c
@@ -13,40 +13,9 @@
#include "ltrace.h"
#include "options.h"
-#include "output.h"
+#include "debug.h"
#include "sysdep.h"
-static void change_uid(struct process * proc);
-
-void
-execute_program(struct process * sp, char **argv) {
- pid_t pid;
-
- if (opt_d) {
- output_line(0, "Executing `%s'...", sp->filename);
- }
-
- pid = fork();
- if (pid<0) {
- perror("ltrace: fork");
- exit(1);
- } else if (!pid) { /* child */
- change_uid(sp);
- trace_me();
- execvp(sp->filename, argv);
- fprintf(stderr, "Can't execute `%s': %s\n", sp->filename, strerror(errno));
- exit(1);
- }
-
- if (opt_d) {
- output_line(0, "PID=%d", pid);
- }
-
- sp->pid = pid;
-
- return;
-}
-
static void
change_uid(struct process * proc) {
uid_t run_uid, run_euid;
@@ -97,3 +66,28 @@ change_uid(struct process * proc) {
}
}
}
+
+void
+execute_program(struct process * sp, char **argv) {
+ pid_t pid;
+
+ debug(1, "Executing `%s'...", sp->filename);
+
+ pid = fork();
+ if (pid<0) {
+ perror("ltrace: fork");
+ exit(1);
+ } else if (!pid) { /* child */
+ change_uid(sp);
+ trace_me();
+ execvp(sp->filename, argv);
+ fprintf(stderr, "Can't execute `%s': %s\n", sp->filename, strerror(errno));
+ exit(1);
+ }
+
+ debug(1, "PID=%d", pid);
+
+ sp->pid = pid;
+
+ return;
+}
diff --git a/ltrace.c b/ltrace.c
index 78f74da..fbd6ca4 100644
--- a/ltrace.c
+++ b/ltrace.c
@@ -15,6 +15,7 @@
#include "output.h"
#include "read_config_file.h"
#include "options.h"
+#include "debug.h"
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
@@ -42,9 +43,7 @@ signal_alarm(int sig) {
}
tmp2 = tmp2->next;
}
- if (opt_d>1) {
- output_line(0,"Sending SIGSTOP to process %u\n",tmp->pid);
- }
+ debug(2,"Sending SIGSTOP to process %u\n",tmp->pid);
kill(tmp->pid, SIGSTOP);
tmp = tmp->next;
}
@@ -53,18 +52,14 @@ signal_alarm(int sig) {
static void
signal_exit(int sig) {
exiting=1;
- if (opt_d) {
- output_line(0,"Received interrupt signal; exiting...");
- }
+ debug(1,"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);
- }
+ debug(2,"Sending SIGSTOP to process %u\n",tmp->pid);
kill(tmp->pid, SIGSTOP);
tmp = tmp->next;
}
@@ -99,10 +94,10 @@ main(int argc, char **argv) {
strcat(path, "/.ltrace.conf");
read_config_file(path);
}
- if (opt_d && opt_e) {
+ if (opt_e) {
struct opt_e_t * tmp = opt_e;
while(tmp) {
- printf("Option -e: %s\n", tmp->name);
+ debug(1,"Option -e: %s\n", tmp->name);
tmp = tmp->next;
}
}
diff --git a/ltrace.h b/ltrace.h
index 4a9a783..a0af48f 100644
--- a/ltrace.h
+++ b/ltrace.h
@@ -5,6 +5,7 @@
#include <stdio.h>
#include "defs.h"
+#include "dict.h"
/* BREAKPOINT_LENGTH is defined in "sysdep.h" */
#include "sysdep.h"
@@ -76,6 +77,7 @@ struct callstack_element {
struct process {
char * filename;
pid_t pid;
+ struct dict * breakpoints;
int breakpoints_enabled; /* -1:not enabled yet, 0:disabled, 1:enabled */
int callstack_depth;
diff --git a/options.c b/options.c
index e261ab4..fa2c555 100644
--- a/options.c
+++ b/options.c
@@ -3,7 +3,7 @@
#endif
#ifndef VERSION
-# define VERSION "0.3.26"
+# define VERSION "0.3.27"
#endif
#include <string.h>
diff --git a/proc.c b/proc.c
index 3c0a936..294340d 100644
--- a/proc.c
+++ b/proc.c
@@ -23,6 +23,7 @@ open_program(char * filename) {
}
proc->filename = filename;
proc->pid = 0;
+ proc->breakpoints = NULL;
proc->breakpoints_enabled = -1;
proc->callstack_depth = 0;
proc->breakpoint_being_enabled = NULL;
diff --git a/process_event.c b/process_event.c
index 53012f4..e314c25 100644
--- a/process_event.c
+++ b/process_event.c
@@ -13,6 +13,7 @@
#include "output.h"
#include "options.h"
#include "elf.h"
+#include "debug.h"
#ifdef __powerpc__
#include <sys/ptrace.h>
@@ -34,44 +35,30 @@ void
process_event(struct event * event) {
switch (event->thing) {
case LT_EV_NONE:
- if (opt_d>0) {
- output_line(0, "event: none");
- }
+ debug(1, "event: none");
return;
case LT_EV_SIGNAL:
- if (opt_d>0) {
- output_line(0, "event: signal (%d)", event->e_un.signum);
- }
+ debug(1, "event: signal (%d)", event->e_un.signum);
process_signal(event);
return;
case LT_EV_EXIT:
- if (opt_d>0) {
- output_line(0, "event: exit (%d)", event->e_un.ret_val);
- }
+ debug(1, "event: exit (%d)", event->e_un.ret_val);
process_exit(event);
return;
case LT_EV_EXIT_SIGNAL:
- if (opt_d>0) {
- output_line(0, "event: exit signal (%d)", event->e_un.signum);
- }
+ debug(1, "event: exit signal (%d)", event->e_un.signum);
process_exit_signal(event);
return;
case LT_EV_SYSCALL:
- if (opt_d>0) {
- output_line(0, "event: syscall (%d)", event->e_un.sysnum);
- }
+ debug(1, "event: syscall (%d)", event->e_un.sysnum);
process_syscall(event);
return;
case LT_EV_SYSRET:
- if (opt_d>0) {
- output_line(0, "event: sysret (%d)", event->e_un.sysnum);
- }
+ debug(1, "event: sysret (%d)", event->e_un.sysnum);
process_sysret(event);
return;
case LT_EV_BREAKPOINT:
- if (opt_d>0) {
- output_line(0, "event: breakpoint");
- }
+ debug(1, "event: breakpoint");
process_breakpoint(event);
return;
default:
@@ -144,9 +131,7 @@ static void
remove_proc(struct process * proc) {
struct process *tmp, *tmp2;
- if (opt_d) {
- output_line(0,"Removing pid %u\n", proc->pid);
- }
+ debug(1, "Removing pid %u\n", proc->pid);
if (list_of_processes == proc) {
tmp = list_of_processes;
@@ -215,9 +200,7 @@ process_breakpoint(struct event * event) {
struct library_symbol * tmp;
int i,j;
- if (opt_d>1) {
- output_line(0,"event: breakpoint (0x%08x)", event->e_un.brk_addr);
- }
+ debug(2, "event: breakpoint (0x%08x)", event->e_un.brk_addr);
if (event->proc->breakpoint_being_enabled) {
/* Reinsert breakpoint */
continue_enabling_breakpoint(event->proc->pid, event->proc->breakpoint_being_enabled);
@@ -230,7 +213,7 @@ process_breakpoint(struct event * event) {
#ifdef __powerpc__
unsigned long a;
unsigned long addr = event->proc->callstack[i].c_un.libfunc->enter_addr;
- struct breakpoint *sbp = dict_find_entry(event->proc, addr);
+ struct breakpoint *sbp = address2bpstruct(event->proc, addr);
unsigned char break_insn[] = BREAKPOINT_VALUE;
/*
diff --git a/read_config_file.c b/read_config_file.c
index 931d9cf..2ba9099 100644
--- a/read_config_file.c
+++ b/read_config_file.c
@@ -8,8 +8,8 @@
#include "ltrace.h"
#include "read_config_file.h"
-#include "options.h"
#include "output.h"
+#include "debug.h"
/*
* "void" ARGTYPE_VOID
@@ -104,20 +104,14 @@ process_line (char * buf) {
int i;
line_no++;
- if (opt_d>2) {
- output_line(0, "Reading line %d of `%s'", line_no, filename);
- }
+ debug(3, "Reading line %d of `%s'", line_no, filename);
eat_spaces(&str);
fun.return_type = str2type(&str);
if (fun.return_type==ARGTYPE_UNKNOWN) {
- if (opt_d>2) {
- output_line(0, " Skipping line %d", line_no);
- }
+ debug(3, " Skipping line %d", line_no);
return NULL;
}
- if (opt_d>3) {
- output_line(0, " return_type = %d", fun.return_type);
- }
+ debug(4, " return_type = %d", fun.return_type);
eat_spaces(&str);
tmp = start_of_arg_sig(str);
if (!tmp) {
@@ -127,9 +121,7 @@ process_line (char * buf) {
*tmp = '\0';
fun.name = strdup(str);
str = tmp+1;
- if (opt_d>2) {
- output_line(0, " name = %s", fun.name);
- }
+ debug(3, " name = %s", fun.name);
fun.params_right = 0;
for(i=0; i<MAX_ARGS; i++) {
eat_spaces(&str);
@@ -171,9 +163,7 @@ read_config_file(char * file) {
filename = file;
- if (opt_d) {
- output_line(0, "Reading config file `%s'...", filename);
- }
+ debug(1, "Reading config file `%s'...", filename);
stream = fopen(filename, "r");
if (!stream) {
@@ -184,9 +174,7 @@ read_config_file(char * file) {
struct function * tmp = process_line(buf);
if (tmp) {
- if (opt_d > 1) {
- output_line(0, "New function: `%s'", tmp->name);
- }
+ debug(2, "New function: `%s'", tmp->name);
tmp->next = list_of_functions;
list_of_functions = tmp;
}
diff --git a/wait_for_something.c b/wait_for_something.c
index 8a471b2..aa1372f 100644
--- a/wait_for_something.c
+++ b/wait_for_something.c
@@ -12,7 +12,7 @@
#include "ltrace.h"
#include "options.h"
-#include "output.h"
+#include "debug.h"
static struct event event;
@@ -27,22 +27,16 @@ wait_for_something(void) {
int tmp;
if (!list_of_processes) {
- if (opt_d) {
- output_line(0, "No more children");
- }
+ debug(1, "No more children");
exit(0);
}
pid = wait(&status);
if (pid==-1) {
if (errno==ECHILD) {
- if (opt_d) {
- output_line(0, "No more children");
- }
+ debug(1, "No more children");
exit(0);
} else if (errno==EINTR) {
- if (opt_d) {
- output_line(0, "wait received EINTR ?");
- }
+ debug(1, "wait received EINTR ?");
event.thing = LT_EV_NONE;
return &event;
}
@@ -55,9 +49,7 @@ wait_for_something(void) {
exit(1);
}
event.proc->instruction_pointer = NULL;
- if (opt_d>2) {
- output_line(0,"signal from pid %u", pid);
- }
+ debug(3, "signal from pid %u", pid);
if (event.proc->breakpoints_enabled == -1) {
enable_all_breakpoints(event.proc);
event.thing = LT_EV_NONE;