Sync with upstream (ia64 ABI, -l, bug fixes)
This commit is contained in:
parent
ba67ad5a36
commit
f09484d326
1539
ltrace-0.6.0-abi-ia64.patch
Normal file
1539
ltrace-0.6.0-abi-ia64.patch
Normal file
File diff suppressed because it is too large
Load Diff
652
ltrace-0.6.0-cleanups.patch
Normal file
652
ltrace-0.6.0-cleanups.patch
Normal file
@ -0,0 +1,652 @@
|
||||
diff --git a/lens_default.c b/lens_default.c
|
||||
index f59d328..81025b1 100644
|
||||
--- a/lens_default.c
|
||||
+++ b/lens_default.c
|
||||
@@ -63,7 +63,7 @@ READER(read_double, double)
|
||||
int##BITS##_t i = l; \
|
||||
switch (format) { \
|
||||
case INT_FMT_unknown: \
|
||||
- if (i < -10000 || i > 10000) \
|
||||
+ if (l < -10000 || l > 10000) \
|
||||
case INT_FMT_x: \
|
||||
return fprintf(stream, "%#"PRIx##BITS, i); \
|
||||
case INT_FMT_i: \
|
||||
diff --git a/sysdeps/linux-gnu/ia64/breakpoint.c b/sysdeps/linux-gnu/ia64/breakpoint.c
|
||||
index a0bfaf9..a5071b8 100644
|
||||
--- a/sysdeps/linux-gnu/ia64/breakpoint.c
|
||||
+++ b/sysdeps/linux-gnu/ia64/breakpoint.c
|
||||
@@ -2,11 +2,12 @@
|
||||
* -Ian Wienand <ianw@gelato.unsw.edu.au> 10/3/2005
|
||||
*/
|
||||
|
||||
-#include "config.h"
|
||||
-
|
||||
#include <sys/ptrace.h>
|
||||
#include <string.h>
|
||||
-#include "common.h"
|
||||
+#include <assert.h>
|
||||
+
|
||||
+#include "breakpoint.h"
|
||||
+#include "debug.h"
|
||||
|
||||
static long long
|
||||
extract_bit_field(char *bundle, int from, int len) {
|
||||
@@ -161,9 +162,7 @@ arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp)
|
||||
|
||||
debug(1, "Enable Breakpoint at %p)", sbp->addr);
|
||||
|
||||
- if (slotnum > 2)
|
||||
- printf
|
||||
- ("Can't insert breakpoint for slot numbers greater than 2.");
|
||||
+ assert(slotnum <= 2);
|
||||
|
||||
addr &= ~0x0f;
|
||||
bundle.ubundle[0] = ptrace(PTRACE_PEEKTEXT, pid, addr, 0);
|
||||
diff --git a/sysdeps/linux-gnu/ia64/plt.c b/sysdeps/linux-gnu/ia64/plt.c
|
||||
index 323df65..76a4aac 100644
|
||||
--- a/sysdeps/linux-gnu/ia64/plt.c
|
||||
+++ b/sysdeps/linux-gnu/ia64/plt.c
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <gelf.h>
|
||||
+
|
||||
#include "proc.h"
|
||||
#include "common.h"
|
||||
+#include "library.h"
|
||||
|
||||
/* A bundle is 128 bits */
|
||||
#define BUNDLE_SIZE 16
|
||||
@@ -36,7 +38,7 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
|
||||
unsigned long addr =
|
||||
lte->plt_addr + (4 * BUNDLE_SIZE) + (BUNDLE_SIZE * entries) +
|
||||
(2 * ndx * BUNDLE_SIZE);
|
||||
- debug(3, "Found PLT %d entry at %lx\n", ndx, addr);
|
||||
+ debug(3, "Found PLT %zd entry at %lx\n", ndx, addr);
|
||||
|
||||
return addr;
|
||||
}
|
||||
diff --git a/breakpoints.c b/breakpoints.c
|
||||
index e7120ee..3eee38b 100644
|
||||
--- a/breakpoints.c
|
||||
+++ b/breakpoints.c
|
||||
@@ -302,35 +302,6 @@ enable_all_breakpoints(Process *proc)
|
||||
dict_apply_to_all(proc->breakpoints, enable_bp_cb,
|
||||
proc);
|
||||
}
|
||||
-#ifdef __mips__
|
||||
- {
|
||||
- /*
|
||||
- * I'm sure there is a nicer way to do this. We need to
|
||||
- * insert breakpoints _after_ the child has been started.
|
||||
- */
|
||||
- struct library_symbol *sym;
|
||||
- struct library_symbol *new_sym;
|
||||
- sym=proc->list_of_symbols;
|
||||
- while(sym){
|
||||
- void *addr= sym2addr(proc,sym);
|
||||
- if(!addr){
|
||||
- sym=sym->next;
|
||||
- continue;
|
||||
- }
|
||||
- if(dict_find_entry(proc->breakpoints,addr)){
|
||||
- sym=sym->next;
|
||||
- continue;
|
||||
- }
|
||||
- debug(2,"inserting bp %p %s",addr,sym->name);
|
||||
- new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
|
||||
- memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
|
||||
- new_sym->next=proc->list_of_symbols;
|
||||
- proc->list_of_symbols=new_sym;
|
||||
- insert_breakpoint(proc, addr, new_sym);
|
||||
- sym=sym->next;
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/handle_event.c b/handle_event.c
|
||||
index 5b6cc40..1720cb3 100644
|
||||
--- a/handle_event.c
|
||||
+++ b/handle_event.c
|
||||
@@ -232,6 +232,7 @@ pending_new_remove(pid_t pid) {
|
||||
debug(DEBUG_FUNCTION, "pending_new_remove(%d)", pid);
|
||||
|
||||
p = pending_news;
|
||||
+ pred = NULL;
|
||||
if (p->pid == pid) {
|
||||
pending_news = p->next;
|
||||
free(p);
|
||||
@@ -592,25 +593,6 @@ handle_breakpoint(Event *event)
|
||||
|
||||
for (i = event->proc->callstack_depth - 1; i >= 0; i--) {
|
||||
if (brk_addr == event->proc->callstack[i].return_addr) {
|
||||
-#if defined(__mips__)
|
||||
- void *addr = NULL;
|
||||
- struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc;
|
||||
- struct library_symbol *new_sym;
|
||||
- assert(sym);
|
||||
- addr = sym2addr(event->proc, sym);
|
||||
- sbp = dict_find_entry(leader->breakpoints, addr);
|
||||
- if (sbp) {
|
||||
- if (addr != sbp->addr) {
|
||||
- insert_breakpoint(event->proc, addr, sym);
|
||||
- }
|
||||
- } else {
|
||||
- new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
|
||||
- memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
|
||||
- new_sym->next = leader->list_of_symbols;
|
||||
- leader->list_of_symbols = new_sym;
|
||||
- insert_breakpoint(event->proc, addr, new_sym);
|
||||
- }
|
||||
-#endif
|
||||
for (j = event->proc->callstack_depth - 1; j > i; j--) {
|
||||
callstack_pop(event->proc);
|
||||
}
|
||||
diff --git a/ltrace-elf.c b/ltrace-elf.c
|
||||
index c8667a7..bc99c6a 100644
|
||||
--- a/ltrace-elf.c
|
||||
+++ b/ltrace-elf.c
|
||||
@@ -50,10 +50,6 @@
|
||||
#include "debug.h"
|
||||
#include "options.h"
|
||||
|
||||
-#ifdef PLT_REINITALISATION_BP
|
||||
-extern char *PLTs_initialized_by_here;
|
||||
-#endif
|
||||
-
|
||||
#ifndef ARCH_HAVE_LTELF_DATA
|
||||
int
|
||||
arch_elf_init(struct ltelf *lte, struct library *lib)
|
||||
diff --git a/ltrace.1 b/ltrace.1
|
||||
index 604f4da..fb64289 100644
|
||||
--- a/ltrace.1
|
||||
+++ b/ltrace.1
|
||||
@@ -7,7 +7,7 @@ ltrace \- A library call tracer
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B ltrace
|
||||
-.I "[-bCfghiLrStttV] [-a column] [-A maxelts] [-D level] [-e expr] [-l filename] [-n nr] [-o filename] [-p pid] ... [-s strsize] [-u username] [-w count] [-X extern] [-x extern] ... [--align=column] [--debug=level] [--demangle] [--help] [--indent=nr] [--library=filename] [--no-signals] [--output=filename] [--version] [--where=NR] [command [arg ...]]"
|
||||
+.I "[-bCfghiLrStttV] [-a column] [-A maxelts] [-D level] [-e expr] [-l filename] [-n nr] [-o filename] [-p pid] ... [-s strsize] [-u username] [-w count] [-x extern] ... [--align=column] [--debug=level] [--demangle] [--help] [--indent=nr] [--library=filename] [--no-signals] [--output=filename] [--version] [--where=NR] [command [arg ...]]"
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B ltrace
|
||||
@@ -158,14 +158,6 @@ correct execution of setuid and/or setgid binaries.
|
||||
Show backtrace of NR stack frames for each traced function. This option enabled
|
||||
only if libunwind support was enabled at compile time.
|
||||
.TP
|
||||
-.I \-X extern
|
||||
-Some architectures need to know where to set a breakpoint that will be hit
|
||||
-after the dynamic linker has run. If this flag is used, then the breakpoint
|
||||
-is set at
|
||||
-.IR extern ,
|
||||
-which must be an external function. By default, '_start' is used.
|
||||
-NOTE: this flag is only available on the architectures that need it.
|
||||
-.TP
|
||||
.I \-x filter
|
||||
A qualifying expression which modifies which symbol table entry points
|
||||
to trace. The format of the filter expression is described in the
|
||||
diff --git a/options.c b/options.c
|
||||
index 8dce7f8..b9472a8 100644
|
||||
--- a/options.c
|
||||
+++ b/options.c
|
||||
@@ -50,12 +50,6 @@ struct opt_p_t *opt_p = NULL; /* attach to process with a given pid */
|
||||
/* List of filenames give to option -F: */
|
||||
struct opt_F_t *opt_F = NULL; /* alternate configuration file(s) */
|
||||
|
||||
-#ifdef PLT_REINITALISATION_BP
|
||||
-/* Set a break on the routine named here in order to re-initialize breakpoints
|
||||
- after all the PLTs have been initialzed */
|
||||
-char *PLTs_initialized_by_here = PLT_REINITALISATION_BP;
|
||||
-#endif
|
||||
-
|
||||
static void
|
||||
err_usage(void) {
|
||||
fprintf(stderr, "Try `%s --help' for more information\n", progname);
|
||||
@@ -78,7 +72,6 @@ usage(void) {
|
||||
" -e expr modify which events to trace.\n"
|
||||
" -f trace children (fork() and clone()).\n"
|
||||
" -F, --config=FILE load alternate configuration file (may be repeated).\n"
|
||||
- " -g, --no-plt disable breakpoints on PLT entries.\n"
|
||||
" -h, --help display this help and exit.\n"
|
||||
" -i print instruction pointer at time of library call.\n"
|
||||
" -l, --library=FILE print library calls from this library only.\n"
|
||||
@@ -97,9 +90,6 @@ usage(void) {
|
||||
" -w=NR, --where=NR print backtrace showing NR stack frames at most.\n"
|
||||
#endif /* defined(HAVE_LIBUNWIND) */
|
||||
" -x NAME treat the global NAME like a library subroutine.\n"
|
||||
-#ifdef PLT_REINITALISATION_BP
|
||||
- " -X NAME same as -x; and PLT's will be initialized by here.\n"
|
||||
-#endif
|
||||
"\nReport bugs to ltrace-devel@lists.alioth.debian.org\n",
|
||||
progname);
|
||||
}
|
||||
@@ -560,14 +550,6 @@ process_options(int argc, char **argv)
|
||||
options.bt_depth = atoi(optarg);
|
||||
break;
|
||||
#endif /* defined(HAVE_LIBUNWIND) */
|
||||
- case 'X':
|
||||
-#ifdef PLT_REINITALISATION_BP
|
||||
- PLTs_initialized_by_here = optarg;
|
||||
-#else
|
||||
- fprintf(stderr, "WARNING: \"-X\" not used for this "
|
||||
- "architecture: assuming you meant \"-x\"\n");
|
||||
-#endif
|
||||
- /* Fall Thru */
|
||||
|
||||
case 'x':
|
||||
parse_filter_chain(optarg, &options.static_filter);
|
||||
diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h
|
||||
index 846961e..2d0ad65 100644
|
||||
--- a/sysdeps/linux-gnu/ppc/arch.h
|
||||
+++ b/sysdeps/linux-gnu/ppc/arch.h
|
||||
@@ -37,8 +37,6 @@
|
||||
#define ARCH_SUPPORTS_OPD
|
||||
#endif
|
||||
|
||||
-#define PLT_REINITALISATION_BP "_start"
|
||||
-
|
||||
#define ARCH_ENDIAN_BIG
|
||||
#define ARCH_HAVE_ATOMIC_SINGLESTEP
|
||||
#define ARCH_HAVE_ADD_PLT_ENTRY
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 177a498..47161f8 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -85,6 +85,7 @@ noinst_HEADERS = \
|
||||
type.h \
|
||||
value.h \
|
||||
value_dict.h \
|
||||
+ callback.h \
|
||||
expr.h \
|
||||
fetch.h \
|
||||
vect.h \
|
||||
diff --git a/callback.h b/callback.h
|
||||
new file mode 100644
|
||||
index 0000000..31e5c8f
|
||||
--- /dev/null
|
||||
+++ b/callback.h
|
||||
@@ -0,0 +1,50 @@
|
||||
+/*
|
||||
+ * This file is part of ltrace.
|
||||
+ * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
|
||||
+ *
|
||||
+ * 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 the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
+ * 02110-1301 USA
|
||||
+ */
|
||||
+
|
||||
+#ifndef _CALLBACK_H_
|
||||
+#define _CALLBACK_H_
|
||||
+
|
||||
+/* Notes on the iteration interface used across ltrace. Typically the
|
||||
+ * iteration function looks something like this:
|
||||
+ *
|
||||
+ * foo *each_foo(foo *start_after,
|
||||
+ * enum callback_status (*cb)(foo *f, void *data),
|
||||
+ * void *data);
|
||||
+ *
|
||||
+ * The iteration starts after the element designated by START_AFTER,
|
||||
+ * or at the first element if START_AFTER is NULL. CB is then called
|
||||
+ * for each element of the collection. DATA is passed verbatim to CB.
|
||||
+ * If CB returns CBS_STOP, the iteration stops and the current element
|
||||
+ * is returned. That element can then be passed as START_AFTER to
|
||||
+ * restart the iteration. NULL is returned when iteration ends.
|
||||
+ *
|
||||
+ * CBS_FAIL is not currently handled, and essentially means the same
|
||||
+ * thing as CBS_STOP. There's no provision for returning error
|
||||
+ * states. Errors need to be signaled to the caller via DATA,
|
||||
+ * together with any other data that the callback needs.
|
||||
+ */
|
||||
+enum callback_status {
|
||||
+ CBS_STOP, /* The iteration should stop. */
|
||||
+ CBS_CONT, /* The iteration should continue. */
|
||||
+ CBS_FAIL, /* There was an error. The iteration should stop
|
||||
+ * and return error. */
|
||||
+};
|
||||
+
|
||||
+#endif /* _CALLBACK_H_ */
|
||||
diff --git a/filter.c b/filter.c
|
||||
index 003010d..bf77b76 100644
|
||||
--- a/filter.c
|
||||
+++ b/filter.c
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "filter.h"
|
||||
#include "library.h"
|
||||
+#include "callback.h"
|
||||
|
||||
void
|
||||
filter_init(struct filter *filt)
|
||||
diff --git a/forward.h b/forward.h
|
||||
index e4233e5..8c03319 100644
|
||||
--- a/forward.h
|
||||
+++ b/forward.h
|
||||
@@ -12,3 +12,4 @@ struct param;
|
||||
struct param_enum;
|
||||
struct value;
|
||||
struct value_dict;
|
||||
+struct filter;
|
||||
diff --git a/library.c b/library.c
|
||||
index 2ce3427..cbd4a35 100644
|
||||
--- a/library.c
|
||||
+++ b/library.c
|
||||
@@ -25,8 +25,9 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "library.h"
|
||||
-#include "proc.h" // for enum callback_status
|
||||
+#include "callback.h"
|
||||
#include "debug.h"
|
||||
+#include "dict.h"
|
||||
#include "backend.h" // for arch_library_symbol_init, arch_library_init
|
||||
|
||||
#ifndef ARCH_HAVE_LIBRARY_DATA
|
||||
diff --git a/library.h b/library.h
|
||||
index 876a533..f207502 100644
|
||||
--- a/library.h
|
||||
+++ b/library.h
|
||||
@@ -23,6 +23,7 @@
|
||||
#define _LIBRARY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
+#include "callback.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
struct Process;
|
||||
@@ -144,9 +145,8 @@ void library_set_soname(struct library *lib,
|
||||
void library_set_pathname(struct library *lib,
|
||||
const char *new_name, int own_name);
|
||||
|
||||
-/* Iterate through list of symbols of library LIB. Restarts are
|
||||
- * supported via START_AFTER (see each_process for details of
|
||||
- * iteration interface). */
|
||||
+/* Iterate through list of symbols of library LIB. See callback.h for
|
||||
+ * notes on this interface. */
|
||||
struct library_symbol *library_each_symbol
|
||||
(struct library *lib, struct library_symbol *start_after,
|
||||
enum callback_status (*cb)(struct library_symbol *, void *),
|
||||
diff --git a/options.c b/options.c
|
||||
index b9472a8..87dddb0 100644
|
||||
--- a/options.c
|
||||
+++ b/options.c
|
||||
@@ -52,7 +52,7 @@ struct opt_F_t *opt_F = NULL; /* alternate configuration file(s) */
|
||||
|
||||
static void
|
||||
err_usage(void) {
|
||||
- fprintf(stderr, "Try `%s --help' for more information\n", progname);
|
||||
+ fprintf(stderr, "Try `%s --help' for more information.\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ search_for_command(char *filename) {
|
||||
m = n = strlen(path);
|
||||
}
|
||||
if (n + strlen(filename) + 1 >= PATH_MAX) {
|
||||
- fprintf(stderr, "Error: filename too long\n");
|
||||
+ fprintf(stderr, "Error: filename too long.\n");
|
||||
exit(1);
|
||||
}
|
||||
strncpy(pathname, path, n);
|
||||
@@ -173,7 +173,7 @@ add_filter_rule(struct filter *filt, const char *expr,
|
||||
struct filter_lib_matcher *matcher = malloc(sizeof(*matcher));
|
||||
|
||||
if (rule == NULL || matcher == NULL) {
|
||||
- fprintf(stderr, "rule near '%s' will be ignored: %s\n",
|
||||
+ fprintf(stderr, "Rule near '%s' will be ignored: %s.\n",
|
||||
expr, strerror(errno));
|
||||
fail:
|
||||
free(rule);
|
||||
@@ -193,7 +193,7 @@ add_filter_rule(struct filter *filt, const char *expr,
|
||||
if (status != 0) {
|
||||
char buf[100];
|
||||
regerror(status, &symbol_re, buf, sizeof buf);
|
||||
- fprintf(stderr, "rule near '%s' will be ignored: %s\n",
|
||||
+ fprintf(stderr, "Rule near '%s' will be ignored: %s.\n",
|
||||
expr, buf);
|
||||
goto fail;
|
||||
}
|
||||
@@ -301,8 +301,8 @@ parse_filter(struct filter *filt, char *expr)
|
||||
/* /XXX@YYY/ is the same as
|
||||
* /XXX/@/YYY/. */
|
||||
if (libend[0] != '/')
|
||||
- fprintf(stderr, "unmatched '/'"
|
||||
- " in symbol name\n");
|
||||
+ fprintf(stderr, "Unmatched '/'"
|
||||
+ " in symbol name.\n");
|
||||
else
|
||||
*libend-- = 0;
|
||||
}
|
||||
@@ -339,7 +339,7 @@ recursive_parse_chain(char *expr)
|
||||
{
|
||||
struct filter *filt = malloc(sizeof(*filt));
|
||||
if (filt == NULL) {
|
||||
- fprintf(stderr, "(part of) filter will be ignored: '%s': %s\n",
|
||||
+ fprintf(stderr, "(Part of) filter will be ignored: '%s': %s.\n",
|
||||
expr, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
@@ -359,7 +359,7 @@ parse_filter_chain(const char *expr, struct filter **retp)
|
||||
{
|
||||
char *str = strdup(expr);
|
||||
if (str == NULL) {
|
||||
- fprintf(stderr, "filter '%s' will be ignored: %s\n",
|
||||
+ fprintf(stderr, "Filter '%s' will be ignored: %s.\n",
|
||||
expr, strerror(errno));
|
||||
return;
|
||||
}
|
||||
@@ -598,7 +598,8 @@ process_options(int argc, char **argv)
|
||||
err_usage();
|
||||
}
|
||||
if (opt_r && opt_t) {
|
||||
- fprintf(stderr, "%s: Incompatible options -r and -t\n",
|
||||
+ fprintf(stderr,
|
||||
+ "%s: Options -r and -t can't be used together\n",
|
||||
progname);
|
||||
err_usage();
|
||||
}
|
||||
diff --git a/options.h b/options.h
|
||||
index 3ffee71..0806928 100644
|
||||
--- a/options.h
|
||||
+++ b/options.h
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
-struct filter;
|
||||
+#include "forward.h"
|
||||
|
||||
struct options_t {
|
||||
int align; /* -a: default alignment column for results */
|
||||
diff --git a/proc.h b/proc.h
|
||||
index 64c37a9..b61e420 100644
|
||||
--- a/proc.h
|
||||
+++ b/proc.h
|
||||
@@ -34,20 +34,11 @@
|
||||
#include "ltrace.h"
|
||||
#include "dict.h"
|
||||
#include "sysdep.h"
|
||||
+#include "callback.h"
|
||||
|
||||
struct library;
|
||||
struct breakpoint;
|
||||
|
||||
-/* XXX Move this somewhere where it makes sense. When the mess in
|
||||
- * common.h is disentangled, that would actually be a good place for
|
||||
- * this. */
|
||||
-enum callback_status {
|
||||
- CBS_STOP, /* The iteration should stop. */
|
||||
- CBS_CONT, /* The iteration should continue. */
|
||||
- CBS_FAIL, /* There was an error. The iteration should stop
|
||||
- * and return error. */
|
||||
-};
|
||||
-
|
||||
struct event_handler {
|
||||
/* Event handler that overrides the default one. Should
|
||||
* return NULL if the event was handled, otherwise the
|
||||
@@ -184,28 +175,16 @@ Process * pid2proc(pid_t pid);
|
||||
* Returns 0 on success or a negative value on failure. */
|
||||
int process_clone(struct Process *retp, struct Process *proc, pid_t pid);
|
||||
|
||||
-/* Iterate through the processes that ltrace currently traces. CB is
|
||||
- * called for each process. Tasks are considered to be processes for
|
||||
- * the purpose of this iterator.
|
||||
- *
|
||||
- * Notes on this iteration interface: The iteration starts after the
|
||||
- * process designated by START_AFTER, or at the first process if
|
||||
- * START_AFTER is NULL. DATA is passed verbatim to CB. If CB returns
|
||||
- * CBS_STOP, the iteration stops and the current iterator is returned.
|
||||
- * That iterator can then be used to restart the iteration. NULL is
|
||||
- * returned when iteration ends.
|
||||
- *
|
||||
- * There's no provision for returning error states. Errors need to be
|
||||
- * signaled to the caller via DATA, together with any other data that
|
||||
- * the callback needs. */
|
||||
+/* Iterate through the processes that ltrace currently traces. Tasks
|
||||
+ * are considered to be processes for the purpose of this iterator.
|
||||
+ * See callback.h for notes on iteration interfaces. */
|
||||
Process *each_process(Process *start_after,
|
||||
enum callback_status (*cb)(struct Process *proc,
|
||||
void *data),
|
||||
void *data);
|
||||
|
||||
-/* Iterate through list of tasks of given process PROC. Restarts are
|
||||
- * supported via START_AFTER (see each_process for details of
|
||||
- * iteration interface). */
|
||||
+/* Iterate through list of tasks of given process PROC. See
|
||||
+ * callback.h for notes on iteration interfaces. */
|
||||
Process *each_task(struct Process *proc, struct Process *start_after,
|
||||
enum callback_status (*cb)(struct Process *proc,
|
||||
void *data),
|
||||
@@ -227,8 +206,8 @@ void proc_add_library(struct Process *proc, struct library *lib);
|
||||
* was found and unlinked, otherwise returns a negative value. */
|
||||
int proc_remove_library(struct Process *proc, struct library *lib);
|
||||
|
||||
-/* Iterate through the libraries of PROC. See each_process for
|
||||
- * detailed description of the iteration interface. */
|
||||
+/* Iterate through the libraries of PROC. See callback.h for notes on
|
||||
+ * iteration interfaces. */
|
||||
struct library *proc_each_library(struct Process *proc, struct library *start,
|
||||
enum callback_status (*cb)(struct Process *p,
|
||||
struct library *l,
|
||||
@@ -242,8 +221,8 @@ int proc_add_breakpoint(struct Process *proc, struct breakpoint *bp);
|
||||
* does not find BP in PROC, it's hard error guarded by assertion. */
|
||||
void proc_remove_breakpoint(struct Process *proc, struct breakpoint *bp);
|
||||
|
||||
-/* Iterate through the libraries of PROC. See each_process for
|
||||
- * detailed description of the iteration interface. */
|
||||
+/* Iterate through the breakpoints of PROC. See callback.h for notes
|
||||
+ * on iteration interfaces. */
|
||||
void *proc_each_breakpoint(struct Process *proc, void *start,
|
||||
enum callback_status (*cb)(struct Process *proc,
|
||||
struct breakpoint *bp,
|
||||
diff --git a/sysdeps/linux-gnu/x86/arch.h b/sysdeps/linux-gnu/x86/arch.h
|
||||
index 77a09d7..329cfba 100644
|
||||
--- a/sysdeps/linux-gnu/x86/arch.h
|
||||
+++ b/sysdeps/linux-gnu/x86/arch.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ltrace.
|
||||
- * Copyright (C) 2011 Petr Machata
|
||||
+ * Copyright (C) 2011, 2012 Petr Machata
|
||||
* Copyright (C) 2006 Ian Wienand
|
||||
* Copyright (C) 2004 Juan Cespedes
|
||||
*
|
||||
@@ -34,7 +34,3 @@
|
||||
#endif
|
||||
#define LT_ELFCLASS2 ELFCLASS32
|
||||
#define LT_ELF_MACHINE2 EM_386
|
||||
-
|
||||
-/* __NR_fork, __NR_clone, __NR_clone2, __NR_vfork and __NR_execve
|
||||
- from asm-i386/unistd.h. */
|
||||
-#define FORK_EXEC_SYSCALLS , { 2, 120, -1, 190, 11 }
|
||||
diff --git a/testsuite/ltrace.main/parameters.c b/testsuite/ltrace.main/parameters.c
|
||||
index 158fdd7..44d54b2 100644
|
||||
--- a/testsuite/ltrace.main/parameters.c
|
||||
+++ b/testsuite/ltrace.main/parameters.c
|
||||
@@ -190,7 +190,7 @@ main ()
|
||||
"%c %d %g %d %g %c %d "
|
||||
"%hd %d %c %g %g %g "
|
||||
"%ld %g %g %g %g",
|
||||
- 1, 2, 3, 4.0, '5', 6, 7.0,
|
||||
+ 1, 2, 3L, 4.0, '5', 6, 7.0,
|
||||
'8', 9, 10.0, 11, 12.0, 'A', 14,
|
||||
(short)15, 16, 'B', 18.0, 19.0, 20.0,
|
||||
21L, 22.0, 23.0, 24.0, 25.0);
|
||||
diff --git a/vect.c b/vect.c
|
||||
index f2e58b2..7dae847 100644
|
||||
--- a/vect.c
|
||||
+++ b/vect.c
|
||||
@@ -134,3 +134,25 @@ vect_destroy(struct vect *vec, void (*dtor)(void *emt, void *data), void *data)
|
||||
}
|
||||
free(vec->data);
|
||||
}
|
||||
+
|
||||
+void *
|
||||
+vect_each(struct vect *vec, void *start_after,
|
||||
+ enum callback_status (*cb)(void *, void *), void *data)
|
||||
+{
|
||||
+ size_t i = start_after == NULL ? 0
|
||||
+ : ((start_after - vec->data) / vec->elt_size) + 1;
|
||||
+
|
||||
+ for (; i < vec->size; ++i) {
|
||||
+ void *slt = slot(vec, i);
|
||||
+ switch ((*cb)(slt, data)) {
|
||||
+ case CBS_FAIL:
|
||||
+ /* XXX handle me */
|
||||
+ case CBS_STOP:
|
||||
+ return slt;
|
||||
+ case CBS_CONT:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
diff --git a/vect.h b/vect.h
|
||||
index 50401bb..c07235f 100644
|
||||
--- a/vect.h
|
||||
+++ b/vect.h
|
||||
@@ -22,6 +22,9 @@
|
||||
#define VECT_H
|
||||
|
||||
#include <stddef.h>
|
||||
+#include <assert.h>
|
||||
+
|
||||
+#include "callback.h"
|
||||
|
||||
/* Vector is an array that can grow as needed to accommodate the data
|
||||
* that it needs to hold. ELT_SIZE is also used as an elementary
|
||||
@@ -122,4 +125,22 @@ void vect_destroy(struct vect *vec,
|
||||
DATA); \
|
||||
} while (0)
|
||||
|
||||
+/* Iterate through vector VEC. See callback.h for notes on iteration
|
||||
+ * interfaces. */
|
||||
+void *vect_each(struct vect *vec, void *start_after,
|
||||
+ enum callback_status (*cb)(void *, void *), void *data);
|
||||
+
|
||||
+#define VECT_EACH(VECP, ELT_TYPE, START_AFTER, CB, DATA) \
|
||||
+ /* xxx GCC-ism necessary to get in the safety latches. */ \
|
||||
+ ({ \
|
||||
+ assert((VECP)->elt_size == sizeof(ELT_TYPE)); \
|
||||
+ /* Check that CB is typed properly. */ \
|
||||
+ enum callback_status (*_cb)(ELT_TYPE *, void *) = CB; \
|
||||
+ ELT_TYPE *start_after = (START_AFTER); \
|
||||
+ (ELT_TYPE *)vect_each((VECP), start_after, \
|
||||
+ (enum callback_status \
|
||||
+ (*)(void *, void *))_cb, \
|
||||
+ DATA); \
|
||||
+ })
|
||||
+
|
||||
#endif /* VECT_H */
|
||||
1293
ltrace-0.6.0-dash-l.patch
Normal file
1293
ltrace-0.6.0-dash-l.patch
Normal file
File diff suppressed because it is too large
Load Diff
30
ltrace-0.6.0-syscall-time.patch
Normal file
30
ltrace-0.6.0-syscall-time.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 6aa01523f249f9763ccd71db9f46969a6e5d8cfd Mon Sep 17 00:00:00 2001
|
||||
From: Paul Buerger <pbuerger@avetec.org>
|
||||
Date: Wed, 12 Sep 2012 10:58:52 -0400
|
||||
Subject: [PATCH] reported time in system call was too large
|
||||
|
||||
when -S and -T are specified and if the system call spans
|
||||
a second boundary, the reported time in the system call
|
||||
was too large by precisely 2 seconds
|
||||
|
||||
Signed-off-by: Paul Buerger <pbuerger@avetec.org>
|
||||
---
|
||||
handle_event.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/handle_event.c b/handle_event.c
|
||||
index 1720cb3..384e868 100644
|
||||
--- a/handle_event.c
|
||||
+++ b/handle_event.c
|
||||
@@ -522,7 +522,7 @@ calc_time_spent(Process *proc) {
|
||||
if (tv.tv_usec >= elem->time_spent.tv_usec) {
|
||||
diff.tv_usec = tv.tv_usec - elem->time_spent.tv_usec;
|
||||
} else {
|
||||
- diff.tv_sec++;
|
||||
+ diff.tv_sec--;
|
||||
diff.tv_usec = 1000000 + tv.tv_usec - elem->time_spent.tv_usec;
|
||||
}
|
||||
current_time_spent = diff;
|
||||
--
|
||||
1.7.6.5
|
||||
|
||||
88
ltrace-0.6.0-x86_64-flatten.patch
Normal file
88
ltrace-0.6.0-x86_64-flatten.patch
Normal file
@ -0,0 +1,88 @@
|
||||
From 78ed40f161c102a10c6033c28ad9a80e5ffe9550 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Machata <pmachata@redhat.com>
|
||||
Date: Sat, 22 Sep 2012 18:19:24 +0200
|
||||
Subject: [PATCH] Fix passing struct(float,struct(float,float)) on x86_64
|
||||
|
||||
The problem was that we assumed that structure elements never overlap
|
||||
eightbyte boundary. This assumption is violated by the above layout,
|
||||
where the first two floats should be passed in %xmm0 together.
|
||||
|
||||
This case is covered by the Itanium HFA tests func_hfa_f3 and func_hfa_f4.
|
||||
---
|
||||
ChangeLog | 4 +++
|
||||
sysdeps/linux-gnu/x86/fetch.c | 46 ++++++++++++++++++++++++++++++++++++----
|
||||
2 files changed, 45 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/sysdeps/linux-gnu/x86/fetch.c b/sysdeps/linux-gnu/x86/fetch.c
|
||||
index 8df900e..cca1638 100644
|
||||
--- a/sysdeps/linux-gnu/x86/fetch.c
|
||||
+++ b/sysdeps/linux-gnu/x86/fetch.c
|
||||
@@ -411,12 +411,34 @@ get_array_field(struct arg_type_info *info, size_t emt)
|
||||
return info->u.array_info.elt_type;
|
||||
}
|
||||
|
||||
+static int
|
||||
+flatten_structure(struct arg_type_info *flattened, struct arg_type_info *info)
|
||||
+{
|
||||
+ size_t i;
|
||||
+ for (i = 0; i < type_struct_size(info); ++i) {
|
||||
+ struct arg_type_info *field = type_struct_get(info, i);
|
||||
+ assert(field != NULL);
|
||||
+ switch (field->type) {
|
||||
+ case ARGTYPE_STRUCT:
|
||||
+ if (flatten_structure(flattened, field) < 0)
|
||||
+ return -1;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ if (type_struct_add(flattened, field, 0) < 0)
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static ssize_t
|
||||
classify(struct Process *proc, struct fetch_context *context,
|
||||
struct arg_type_info *info, struct value *valuep, enum arg_class classes[],
|
||||
size_t sz, size_t eightbytes)
|
||||
{
|
||||
switch (info->type) {
|
||||
+ struct arg_type_info flattened;
|
||||
case ARGTYPE_VOID:
|
||||
return 0;
|
||||
|
||||
@@ -458,11 +480,25 @@ classify(struct Process *proc, struct fetch_context *context,
|
||||
get_array_field);
|
||||
|
||||
case ARGTYPE_STRUCT:
|
||||
- /* N.B. "big" structs are dealt with in the
|
||||
- * caller. */
|
||||
- return classify_eightbytes(proc, context, info, valuep, classes,
|
||||
- type_struct_size(info),
|
||||
- eightbytes, type_struct_get);
|
||||
+ /* N.B. "big" structs are dealt with in the caller.
|
||||
+ *
|
||||
+ * First, we need to flatten the structure. In
|
||||
+ * struct(float,struct(float,float)), first two floats
|
||||
+ * both belong to the same eightbyte. */
|
||||
+ type_init_struct(&flattened);
|
||||
+
|
||||
+ ssize_t ret;
|
||||
+ if (flatten_structure(&flattened, info) < 0) {
|
||||
+ ret = -1;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ ret = classify_eightbytes(proc, context, &flattened,
|
||||
+ valuep, classes,
|
||||
+ type_struct_size(&flattened),
|
||||
+ eightbytes, type_struct_get);
|
||||
+ done:
|
||||
+ type_destroy(&flattened);
|
||||
+ return ret;
|
||||
}
|
||||
abort();
|
||||
}
|
||||
--
|
||||
1.7.6.5
|
||||
|
||||
24
ltrace.spec
24
ltrace.spec
@ -1,7 +1,7 @@
|
||||
Summary: Tracks runtime library calls from dynamically linked executables
|
||||
Name: ltrace
|
||||
Version: 0.6.0
|
||||
Release: 18%{?dist}
|
||||
Release: 19%{?dist}
|
||||
URL: http://ltrace.alioth.debian.org/
|
||||
License: GPLv2+
|
||||
Group: Development/Debuggers
|
||||
@ -37,6 +37,11 @@ Patch21: ltrace-0.6.0-demangle.patch
|
||||
Patch22: ltrace-0.6.0-abi.patch
|
||||
Patch23: ltrace-0.6.0-abi-s390.patch
|
||||
Patch24: ltrace-0.6.0-ppc-flteqv.patch
|
||||
Patch25: ltrace-0.6.0-cleanups.patch
|
||||
Patch26: ltrace-0.6.0-syscall-time.patch
|
||||
Patch27: ltrace-0.6.0-abi-ia64.patch
|
||||
Patch28: ltrace-0.6.0-x86_64-flatten.patch
|
||||
Patch29: ltrace-0.6.0-dash-l.patch
|
||||
|
||||
%description
|
||||
Ltrace is a debugging program which runs a specified command until the
|
||||
@ -72,6 +77,11 @@ execution of processes.
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
%patch27 -p1
|
||||
%patch28 -p1
|
||||
%patch29 -p1
|
||||
|
||||
%build
|
||||
# This ugly hack is necessary to build and link files for correct
|
||||
@ -99,6 +109,18 @@ echo ====================TESTING END=====================
|
||||
%config(noreplace) %{_sysconfdir}/ltrace.conf
|
||||
|
||||
%changelog
|
||||
* Mon Oct 1 2012 Petr Machata <pmachata@redhat.com> - 0.6.0-19
|
||||
- Upstream patch for ia64 parameter passing
|
||||
(ltrace-0.6.0-abi-ia64.patch)
|
||||
- Upstream fix for a bug in computation of time spent in a syscall
|
||||
(ltrace-0.6.0-syscall-time.patch)
|
||||
- Upstream fix for a bug in passing struct(float,struct(float,float))
|
||||
on x86_64 (ltrace-0.6.0-x86_64-flatten.patch)
|
||||
- Upstream patch for support of -l option (ltrace-0.6.0-dash-l.patch)
|
||||
- Several more upstream patches with random cleanups. Those were
|
||||
brought to Fedora to make porting of other patches easier.
|
||||
(ltrace-0.6.0-cleanups.patch)
|
||||
|
||||
* Thu Aug 30 2012 Petr Machata <pmachata@redhat.com> - 0.6.0-18
|
||||
- PPC64 passes floating point equivalent structures in registers
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user