aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Cespedes <cespedes@coco.thehackers.org>2009-07-03 11:55:44 +0200
committerJuan Cespedes <cespedes@coco.thehackers.org>2009-07-03 11:55:44 +0200
commit61da33723c5fb09762e38bd39a26ee15d62ffebc (patch)
treeebfece2b8b14d918468073e55b628165702ad753
parent8d1b92ba755f6d6229f5e230fc43d958b13836f8 (diff)
downloadltrace-61da33723c5fb09762e38bd39a26ee15d62ffebc.tar.gz
Added different callback handlers for each event
-rw-r--r--handle_event.c148
-rw-r--r--libltrace.c38
-rw-r--r--ltrace.h34
-rw-r--r--main.c22
-rw-r--r--output.h1
-rw-r--r--sysdeps/linux-gnu/breakpoint.c1
-rw-r--r--sysdeps/linux-gnu/events.c2
-rw-r--r--sysdeps/linux-gnu/ppc/regs.c8
8 files changed, 142 insertions, 112 deletions
diff --git a/handle_event.c b/handle_event.c
index 18f64c6..48b9945 100644
--- a/handle_event.c
+++ b/handle_event.c
@@ -34,13 +34,88 @@ static void callstack_push_symfunc(Process *proc,
struct library_symbol *sym);
static void callstack_pop(Process *proc);
+static char * shortsignal(Process *proc, int signum);
+static char * sysname(Process *proc, int sysnum);
+static char * arch_sysname(Process *proc, int sysnum);
+
+void
+handle_event(Event *event) {
+ debug(DEBUG_FUNCTION, "handle_event(pid=%d, type=%d)", event->proc ? event->proc->pid : -1, event->type);
+ switch (event->type) {
+ case EVENT_NONE:
+ debug(1, "event: none");
+ return;
+ case EVENT_SIGNAL:
+ debug(1, "event: signal (%s [%d])",
+ shortsignal(event->proc, event->e_un.signum),
+ event->e_un.signum);
+ handle_signal(event);
+ return;
+ case EVENT_EXIT:
+ debug(1, "event: exit (%d)", event->e_un.ret_val);
+ handle_exit(event);
+ return;
+ case EVENT_EXIT_SIGNAL:
+ debug(1, "event: exit signal (%s [%d])",
+ shortsignal(event->proc, event->e_un.signum),
+ event->e_un.signum);
+ handle_exit_signal(event);
+ return;
+ case EVENT_SYSCALL:
+ debug(1, "event: syscall (%s [%d])",
+ sysname(event->proc, event->e_un.sysnum),
+ event->e_un.sysnum);
+ handle_syscall(event);
+ return;
+ case EVENT_SYSRET:
+ debug(1, "event: sysret (%s [%d])",
+ sysname(event->proc, event->e_un.sysnum),
+ event->e_un.sysnum);
+ handle_sysret(event);
+ return;
+ case EVENT_ARCH_SYSCALL:
+ debug(1, "event: arch_syscall (%s [%d])",
+ arch_sysname(event->proc, event->e_un.sysnum),
+ event->e_un.sysnum);
+ handle_arch_syscall(event);
+ return;
+ case EVENT_ARCH_SYSRET:
+ debug(1, "event: arch_sysret (%s [%d])",
+ arch_sysname(event->proc, event->e_un.sysnum),
+ event->e_un.sysnum);
+ handle_arch_sysret(event);
+ return;
+ case EVENT_CLONE:
+ debug(1, "event: clone (%u)", event->e_un.newpid);
+ handle_clone(event);
+ return;
+ case EVENT_EXEC:
+ debug(1, "event: exec()");
+ handle_exec(event);
+ return;
+ case EVENT_BREAKPOINT:
+ debug(1, "event: breakpoint");
+ handle_breakpoint(event);
+ return;
+ case EVENT_NEW:
+ debug(1, "event: new process");
+ handle_new(event);
+ return;
+ default:
+ fprintf(stderr, "Error! unknown event?\n");
+ exit(1);
+ }
+}
+
/* TODO */
-void * address_clone(void * addr) {
+static void *
+address_clone(void * addr) {
debug(DEBUG_FUNCTION, "address_clone(%p)", addr);
return addr;
}
-void * breakpoint_clone(void * bp) {
+static void *
+breakpoint_clone(void * bp) {
Breakpoint * b;
debug(DEBUG_FUNCTION, "breakpoint_clone(%p)", bp);
b = malloc(sizeof(Breakpoint));
@@ -247,75 +322,6 @@ arch_sysname(Process *proc, int sysnum) {
}
}
-void
-handle_event(Event *event) {
- debug(DEBUG_FUNCTION, "handle_event(pid=%d, type=%d)", event->proc ? event->proc->pid : -1, event->type);
- switch (event->type) {
- case EVENT_NONE:
- debug(1, "event: none");
- return;
- case EVENT_SIGNAL:
- debug(1, "event: signal (%s [%d])",
- shortsignal(event->proc, event->e_un.signum),
- event->e_un.signum);
- handle_signal(event);
- return;
- case EVENT_EXIT:
- debug(1, "event: exit (%d)", event->e_un.ret_val);
- handle_exit(event);
- return;
- case EVENT_EXIT_SIGNAL:
- debug(1, "event: exit signal (%s [%d])",
- shortsignal(event->proc, event->e_un.signum),
- event->e_un.signum);
- handle_exit_signal(event);
- return;
- case EVENT_SYSCALL:
- debug(1, "event: syscall (%s [%d])",
- sysname(event->proc, event->e_un.sysnum),
- event->e_un.sysnum);
- handle_syscall(event);
- return;
- case EVENT_SYSRET:
- debug(1, "event: sysret (%s [%d])",
- sysname(event->proc, event->e_un.sysnum),
- event->e_un.sysnum);
- handle_sysret(event);
- return;
- case EVENT_ARCH_SYSCALL:
- debug(1, "event: arch_syscall (%s [%d])",
- arch_sysname(event->proc, event->e_un.sysnum),
- event->e_un.sysnum);
- handle_arch_syscall(event);
- return;
- case EVENT_ARCH_SYSRET:
- debug(1, "event: arch_sysret (%s [%d])",
- arch_sysname(event->proc, event->e_un.sysnum),
- event->e_un.sysnum);
- handle_arch_sysret(event);
- return;
- case EVENT_CLONE:
- debug(1, "event: clone (%u)", event->e_un.newpid);
- handle_clone(event);
- return;
- case EVENT_EXEC:
- debug(1, "event: exec()");
- handle_exec(event);
- return;
- case EVENT_BREAKPOINT:
- debug(1, "event: breakpoint");
- handle_breakpoint(event);
- return;
- case EVENT_NEW:
- debug(1, "event: new process");
- handle_new(event);
- return;
- default:
- fprintf(stderr, "Error! unknown event?\n");
- exit(1);
- }
-}
-
static void
handle_signal(Event *event) {
debug(DEBUG_FUNCTION, "handle_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum);
diff --git a/libltrace.c b/libltrace.c
index 731ead2..6827257 100644
--- a/libltrace.c
+++ b/libltrace.c
@@ -119,34 +119,38 @@ ltrace_init(int argc, char **argv) {
}
}
-static int num_ltrace_callbacks = 0;
-static void (**ltrace_callbacks)(Event *) = NULL;
+static int num_ltrace_callbacks[EVENT_MAX];
+static callback_func * ltrace_callbacks[EVENT_MAX];
void
-ltrace_add_callback(void (*func)(Event *)) {
- ltrace_callbacks = realloc(ltrace_callbacks, (num_ltrace_callbacks+1)*sizeof(*ltrace_callbacks));
- ltrace_callbacks[num_ltrace_callbacks++] = func;
-
- {
- int i;
+ltrace_add_callback(callback_func func, Event_type type) {
+ ltrace_callbacks[type] = realloc(ltrace_callbacks[type], (num_ltrace_callbacks[type]+1)*sizeof(callback_func));
+ ltrace_callbacks[type][num_ltrace_callbacks[type]++] = func;
+}
- printf("*** Added callback\n");
- printf("\tThere are %d callbacks:\n", num_ltrace_callbacks);
- for (i=0; i<num_ltrace_callbacks; i++) {
- printf("\t\t%10p\n", ltrace_callbacks[i]);
- }
+static void
+dispatch_callbacks(Event * ev) {
+ int i;
+ /* Ignoring case 1: signal into a dying tracer */
+ if (ev->type==EVENT_SIGNAL &&
+ exiting && ev->e_un.signum == SIGSTOP) {
+ return;
+ }
+ /* Ignoring case 2: process being born before a clone event */
+ if (ev->proc && ev->proc->state == STATE_IGNORED) {
+ return;
+ }
+ for (i=0; i<num_ltrace_callbacks[ev->type]; i++) {
+ ltrace_callbacks[ev->type][i](ev);
}
}
void
ltrace_main(void) {
- int i;
Event * ev;
while (1) {
ev = next_event();
- for (i=0; i<num_ltrace_callbacks; i++) {
- ltrace_callbacks[i](ev);
- }
+ dispatch_callbacks(ev);
handle_event(ev);
}
}
diff --git a/ltrace.h b/ltrace.h
index 9ba16a6..f918d8a 100644
--- a/ltrace.h
+++ b/ltrace.h
@@ -1,9 +1,6 @@
-typedef struct Process Process;
-typedef struct Event Event;
-struct Event {
- Process *proc;
- enum {
- EVENT_NONE,
+typedef enum Event_type Event_type;
+enum Event_type {
+ EVENT_NONE=0,
EVENT_SIGNAL,
EVENT_EXIT,
EVENT_EXIT_SIGNAL,
@@ -14,17 +11,26 @@ struct Event {
EVENT_CLONE,
EVENT_EXEC,
EVENT_BREAKPOINT,
- EVENT_NEW /* in this case, proc is NULL */
- } type;
+ EVENT_NEW, /* in this case, proc is NULL */
+ EVENT_MAX
+};
+
+typedef struct Process Process;
+typedef struct Event Event;
+struct Event {
+ Process * proc;
+ Event_type type;
union {
- int ret_val; /* EVENT_EXIT */
- int signum; /* EVENT_SIGNAL, EVENT_EXIT_SIGNAL */
- int sysnum; /* EVENT_SYSCALL, EVENT_SYSRET */
- void *brk_addr; /* EVENT_BREAKPOINT */
- int newpid; /* EVENT_CLONE, EVENT_NEW */
+ int ret_val; /* EVENT_EXIT */
+ int signum; /* EVENT_SIGNAL, EVENT_EXIT_SIGNAL */
+ int sysnum; /* EVENT_SYSCALL, EVENT_SYSRET */
+ void * brk_addr; /* EVENT_BREAKPOINT */
+ int newpid; /* EVENT_CLONE, EVENT_NEW */
} e_un;
};
+typedef void (*callback_func) (Event *);
+
extern void ltrace_init(int argc, char **argv);
-extern void ltrace_add_callback(void (*func)(Event *));
+extern void ltrace_add_callback(callback_func f, Event_type type);
extern void ltrace_main(void);
diff --git a/main.c b/main.c
index 04f6a30..bd443cf 100644
--- a/main.c
+++ b/main.c
@@ -4,18 +4,34 @@
#include "ltrace.h"
/*
+static int count_call =0;
+static int count_ret =0;
+
+static void
+callback_call(Event * ev) {
+ count_call ++;
+}
+static void
+callback_ret(Event * ev) {
+ count_ret ++;
+}
+
static void
-callback(Event * ev) {
- printf("\n\tcallback(ev->type=%d)\n", ev->type);
+endcallback(Event *ev) {
+ printf("%d calls\n%d rets\n",count_call, count_ret);
}
*/
int
main(int argc, char *argv[]) {
ltrace_init(argc, argv);
+
/*
- ltrace_add_callback(callback);
+ ltrace_add_callback(callback_call, EVENT_SYSCALL);
+ ltrace_add_callback(callback_ret, EVENT_SYSRET);
+ ltrace_add_callback(endcallback, EVENT_EXIT);
*/
+
ltrace_main();
return 0;
}
diff --git a/output.h b/output.h
index c882c0f..c58577a 100644
--- a/output.h
+++ b/output.h
@@ -1,4 +1,3 @@
void output_line(Process *proc, char *fmt, ...);
-
void output_left(enum tof type, Process *proc, char *function_name);
void output_right(enum tof type, Process *proc, char *function_name);
diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c
index df6e52c..ebd8d8a 100644
--- a/sysdeps/linux-gnu/breakpoint.c
+++ b/sysdeps/linux-gnu/breakpoint.c
@@ -4,6 +4,7 @@
#include <sys/ptrace.h>
#include <string.h>
+
#include "common.h"
static unsigned char break_insn[] = BREAKPOINT_VALUE;
diff --git a/sysdeps/linux-gnu/events.c b/sysdeps/linux-gnu/events.c
index 4ad6f88..3e681a8 100644
--- a/sysdeps/linux-gnu/events.c
+++ b/sysdeps/linux-gnu/events.c
@@ -60,7 +60,7 @@ next_event(void) {
}
if (opt_i) {
event.proc->instruction_pointer =
- get_instruction_pointer(event.proc);
+ get_instruction_pointer(event.proc);
}
switch (syscall_p(event.proc, status, &tmp)) {
case 1:
diff --git a/sysdeps/linux-gnu/ppc/regs.c b/sysdeps/linux-gnu/ppc/regs.c
index 714d57f..67df5c9 100644
--- a/sysdeps/linux-gnu/ppc/regs.c
+++ b/sysdeps/linux-gnu/ppc/regs.c
@@ -18,19 +18,17 @@
void *
get_instruction_pointer(Process *proc) {
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long) * PT_NIP,
- 0);
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_NIP, 0);
}
void
set_instruction_pointer(Process *proc, void *addr) {
- ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long) * PT_NIP, addr);
+ ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_NIP, addr);
}
void *
get_stack_pointer(Process *proc) {
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long) * PT_R1,
- 0);
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_R1, 0);
}
void *