Skip to content

Commit

Permalink
New feature was added: changing a function's return value by the resu…
Browse files Browse the repository at this point in the history
…lt of corresponding wrapper-function written in python language. Function's parameters will be passed to the wrapper according to the definition in ltrace config file. Use "-M" option to use the feature (i386 & x86_64).

New feature was added: the quick time machine. Now it is possible to simulate time tracing the program. Use "-q" option followed by the timestamp. The time will go forward starting from that (i386 & x86_64).

New feature was added: fast return value patching. Use "-m" option to patch a function's return value. Only integers are supported by now (i386 & x86_64)

New argument type was added: "binary". It's the same as "string", but it is not limited by the first zero character.
  • Loading branch information
zenovich committed Nov 14, 2011
1 parent 8fe59f3 commit e659aaf
Show file tree
Hide file tree
Showing 28 changed files with 1,173 additions and 22 deletions.
3 changes: 3 additions & 0 deletions Makefile.am
Expand Up @@ -22,6 +22,7 @@ libltrace_la_SOURCES = \
libltrace.c \
options.c \
output.c \
mock.c \
proc.c \
read_config_file.c \
summary.c
Expand Down Expand Up @@ -61,6 +62,8 @@ noinst_HEADERS = \
dist_man1_MANS = \
ltrace.1

docdir = ${datadir}/doc/${PACKAGE}

dist_doc_DATA = \
COPYING \
README \
Expand Down
5 changes: 5 additions & 0 deletions breakpoints.c
Expand Up @@ -194,6 +194,11 @@ breakpoints_init(Process *proc) {
}
tmp2 = tmp2->next;
}

if (opt_q && !keep && (!strcmp((*tmp1)->name, "time") || !strcmp((*tmp1)->name, "gettimeofday") || !strcmp((*tmp1)->name, "clock_gettime"))) {
keep = 1;
}

if (!keep) {
*tmp1 = (*tmp1)->next;
} else {
Expand Down
9 changes: 9 additions & 0 deletions common.h
Expand Up @@ -25,6 +25,8 @@ extern char * command;

extern int exiting; /* =1 if we have to exit ASAP */

extern int opt_fake_return;

typedef struct Breakpoint Breakpoint;
struct Breakpoint {
void * addr;
Expand Down Expand Up @@ -54,6 +56,8 @@ enum arg_type {
ARGTYPE_FORMAT, /* printf-like format */
ARGTYPE_STRING, /* NUL-terminated string */
ARGTYPE_STRING_N, /* String of known maxlen */
ARGTYPE_BYTES, /* Array of bytes */
ARGTYPE_BYTES_N, /* Binary data of known maxlen */
ARGTYPE_ARRAY, /* Series of values in memory */
ARGTYPE_ENUM, /* Enumeration */
ARGTYPE_STRUCT, /* Structure of values */
Expand Down Expand Up @@ -213,6 +217,7 @@ struct opt_c_struct {

#include "options.h"
#include "output.h"
#include "mock.h"
#ifdef USE_DEMANGLE
#include "demangle.h"
#endif
Expand All @@ -226,6 +231,7 @@ extern Process * pid2proc(pid_t pid);
extern void handle_event(Event * event);
extern void execute_program(Process *, char **);
extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
extern long get_length(enum tof type, Process *proc, int len_spec, void *st, arg_type_info* st_info);
extern Breakpoint * address2bpstruct(Process * proc, void * addr);
extern void breakpoints_init(Process * proc);
extern void insert_breakpoint(Process * proc, void * addr, struct library_symbol * libsym);
Expand Down Expand Up @@ -254,6 +260,7 @@ extern void trace_me(void);
extern int trace_pid(pid_t pid);
extern void untrace_pid(pid_t pid);
extern void get_arch_dep(Process * proc);
extern void set_arch_dep(Process * proc);
extern void * get_instruction_pointer(Process * proc);
extern void set_instruction_pointer(Process * proc, void * addr);
extern void * get_stack_pointer(Process * proc);
Expand All @@ -267,10 +274,12 @@ extern void continue_after_signal(pid_t pid, int signum);
extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp);
extern void continue_enabling_breakpoint(pid_t pid, Breakpoint * sbp);
extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
extern void set_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info, long value);
extern void save_register_args(enum tof type, Process * proc);
extern int umovestr(Process * proc, void * addr, int len, void * laddr);
extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info);
extern size_t umovebytes (Process *proc, void * addr, void * laddr, size_t count);
extern size_t uunmovebytes (Process *proc, void * addr, void * laddr, size_t count);
extern int ffcheck(void * maddr);
extern void * sym2addr(Process *, struct library_symbol *);
extern int linkmap_init(Process *, struct ltelf *);
Expand Down
14 changes: 13 additions & 1 deletion configure.ac
@@ -1,3 +1,5 @@
m4_include([m4/as-python.m4])

# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
Expand Down Expand Up @@ -65,6 +67,14 @@ AC_CHECK_LIB([elf], [elf_begin],,
CPPFLAGS="${saved_CPPFLAGS}"
LDFLAGS="${saved_LDFLAGS}"

#Python
AS_PATH_PYTHON([2.6.0])
AM_CHECK_PYTHON_HEADERS([AM_CPPFLAGS="$AM_CPPFLAGS $PYTHON_INCLUDES"],[AC_MSG_NOTICE([could not find Python headers])])
AM_CHECK_PYTHON_LIBS(
[
AC_DEFINE([HAVE_PYTHON], [1], [we have python])
AM_LDFLAGS="${AM_LDFLAGS} $PYTHON_LIBS"
],[AC_MSG_NOTICE([could not find Python libs])])

# HAVE_LIBIBERTY
AC_CHECK_LIB([iberty], [cplus_demangle], [
Expand Down Expand Up @@ -109,7 +119,7 @@ case "${enable_libunwind}" in
enable_libunwind=no
else
AC_MSG_RESULT([$enable_libunwind])
AC_MSG_ERROR([libunwind.h or libunwind-ptrace.h cannot be found])
AC_MSG_ERROR([libunwind.h or libunwind-ptrace.h cannot be found])
fi
;;
(*) ;;
Expand Down Expand Up @@ -244,6 +254,8 @@ if test x$enable_werror = xyes; then
AM_CFLAGS="${AM_CFLAGS} -Werror"
fi

AM_LDFLAGS="${AM_LDFLAGS} -lrt"

AC_SUBST(AM_CPPFLAGS)
AC_SUBST(AM_CFLAGS)
AC_SUBST(AM_LDFLAGS)
Expand Down
4 changes: 3 additions & 1 deletion display_args.c
Expand Up @@ -18,7 +18,7 @@ static int display_format(enum tof type, Process *proc, int arg_num);
static size_t string_maxlength = INT_MAX;
static size_t array_maxlength = INT_MAX;

static long
long
get_length(enum tof type, Process *proc, int len_spec,
void *st, arg_type_info* st_info) {
long len;
Expand Down Expand Up @@ -216,9 +216,11 @@ display_value(enum tof type, Process *proc,
fprintf(stderr, "Should never encounter a format anywhere but at the top level (for now?)\n");
exit(1);
case ARGTYPE_STRING:
case ARGTYPE_BYTES:
return display_string(type, proc, (void*) value,
string_maxlength);
case ARGTYPE_STRING_N:
case ARGTYPE_BYTES_N:
return display_string(type, proc, (void*) value,
get_length(type, proc,
info->u.string_n_info.size_spec, st, st_info));
Expand Down
11 changes: 10 additions & 1 deletion etc/ltrace.conf
Expand Up @@ -25,6 +25,12 @@
; string[retval] == (char *) [show only up to (return val) bytes]
; string[arg0] == (char *) [same as string[retval]]
; string[N] == (char *) [N>0] [show only up to N bytes]
; binary == (char *)
; binary[argN] == (char *) [N>0] [show only up to (arg N) bytes]
; binary[eltN] == (char *) [N>0] [show only up to (elt N) bytes]
; binary[retval] == (char *) [show only up to (return val) bytes]
; binary[arg0] == (char *) [same as string[retval]]
; binary[N] == (char *) [N>0] [show only up to N bytes]
; type* == (type *) [pointer to any other type]
; enum (key=value,key=value,...) [enumeration, see below]
; array(type,argN)
Expand All @@ -38,6 +44,8 @@
; Backwards-compatibility:
; string0 == (char *) [same as string[retval]]
; stringN == (char *) [N>0] [same as string[argN]]
; binary0 == (char *) [same as binary[retval]]
; binaryN == (char *) [N>0] [same as binary[argN]]



Expand Down Expand Up @@ -378,6 +386,7 @@ int tcsetattr(int,int,addr);
; time.h
string ctime(addr);
int gettimeofday(addr, addr);
int clock_gettime(enum(CLOCK_REALTIME=0,CLOCK_MONOTONIC=1,CLOCK_PROCESS_CPUTIME_ID=2,CLOCK_THREAD_CPUTIME_ID=3,CLOCK_REALTIME_HR=4,CLOCK_MONOTONIC_HR=5),struct(int, long)*);
addr gmtime(addr);
addr localtime(addr);
ulong strftime(+string2,ulong,string,addr);
Expand Down Expand Up @@ -429,7 +438,7 @@ int truncate(string,ulong);
string ttyname(int);
int unlink(string);
void usleep(uint);
long write(int, string3, ulong);
long write(int, bytes3, ulong);
addr sbrk(long);
int getpagesize(void);
long lseek(int,long,int);
Expand Down
2 changes: 2 additions & 0 deletions handle_event.c
Expand Up @@ -605,6 +605,8 @@ handle_breakpoint(Event *event) {
}
event->proc->return_addr = event->e_un.brk_addr;
if (event->proc->state != STATE_IGNORED) {
mock_return(LT_TOF_FUNCTIONR, event->proc,
event->proc->callstack[i].c_un.libfunc->name);
output_right(LT_TOF_FUNCTIONR, event->proc,
event->proc->callstack[i].c_un.libfunc->name);
}
Expand Down
13 changes: 12 additions & 1 deletion libltrace.c
Expand Up @@ -9,6 +9,10 @@
#include <signal.h>
#include <sys/wait.h>

#ifdef HAVE_PYTHON
#include "Python.h"
#endif

#include "common.h"

char *command = NULL;
Expand Down Expand Up @@ -68,12 +72,19 @@ normal_exit(void) {
fclose(options.output);
options.output = NULL;
}
#ifdef HAVE_PYTHON
Py_Finalize();
#endif
}

void
ltrace_init(int argc, char **argv) {
struct opt_p_t *opt_p_tmp;

#ifdef HAVE_PYTHON
Py_Initialize();
#endif

atexit(normal_exit);
signal(SIGINT, signal_exit); /* Detach processes when interrupted */
signal(SIGTERM, signal_exit); /* ... or killed */
Expand Down Expand Up @@ -130,7 +141,7 @@ static void
dispatch_callbacks(Event * ev) {
int i;
/* Ignoring case 1: signal into a dying tracer */
if (ev->type==EVENT_SIGNAL &&
if (ev->type==EVENT_SIGNAL &&
exiting && ev->e_un.signum == SIGSTOP) {
return;
}
Expand Down

0 comments on commit e659aaf

Please sign in to comment.