Package init
This commit is contained in:
parent
30d3bb0b5a
commit
ddc1daa205
12
bugfix-0001-ltrace-0.7.91-aarch64_be-compile-support.patch
Normal file
12
bugfix-0001-ltrace-0.7.91-aarch64_be-compile-support.patch
Normal file
@ -0,0 +1,12 @@
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 6853a0b..78faeed 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -41,6 +41,7 @@AC_SUBST(HOST_OS)
|
||||
|
||||
case "${host_cpu}" in
|
||||
arm*|sa110) HOST_CPU="arm" ;;
|
||||
+ aarch64_be) HOST_CPU="aarch64" ;;
|
||||
cris*) HOST_CPU="cris" ;;
|
||||
mips*) HOST_CPU="mips" ;;
|
||||
powerpc|powerpc64) HOST_CPU="ppc" ;;
|
||||
@ -0,0 +1,20 @@
|
||||
diff --git a/sysdeps/linux-gnu/arm/trace.c b/sysdeps/linux-gnu/arm/trace.c
|
||||
index f974d1f..8526bf1 100644
|
||||
--- a/sysdeps/linux-gnu/arm/trace.c
|
||||
+++ b/sysdeps/linux-gnu/arm/trace.c
|
||||
@@ -77,6 +77,15 @@ syscall_p(struct process *proc, int status, int *sysnum)
|
||||
unsigned insn = ptrace(PTRACE_PEEKTEXT, proc->pid,
|
||||
(void *)pc, 0);
|
||||
|
||||
+#if defined(__ARMEB__) && defined(__ARM_ARCH_7A__)
|
||||
+ /* We running big endian arm on ARMv7: instructions are
|
||||
+ * in little endian form so we need to byteswap it. Note
|
||||
+ * on older ARM like V5 Xscale code is in big endian form
|
||||
+ * byte swap is not needed in this case. I.e be8 vs be32.
|
||||
+ */
|
||||
+ insn = __builtin_bswap32(insn);
|
||||
+#endif /* __ARMEB__ && __ARM_ARCH_7A__ */
|
||||
+
|
||||
if (insn == 0xef000000 || insn == 0x0f000000
|
||||
|| (insn & 0xffff0000) == 0xdf000000) {
|
||||
/* EABI syscall */
|
||||
141
bugfix-for-use-after-free-about-soname.patch
Normal file
141
bugfix-for-use-after-free-about-soname.patch
Normal file
@ -0,0 +1,141 @@
|
||||
From 8eccd30f5d3ae0be17f2a75116600f5fca9c76db Mon Sep 17 00:00:00 2001
|
||||
From: root <root@localhost.localdomain>
|
||||
Date: Sat, 4 May 2019 16:51:52 +0800
|
||||
Subject: [PATCH] bugfix for use after free about soname
|
||||
|
||||
==18904==ERROR: AddressSanitizer: heap-use-after-free on address 0xffffa0d00313 at pc 0xffffa3d1bc70 bp 0xffffe9c118d0 sp 0xffffe9c11948
|
||||
READ of size 5 at 0xffffa0d00313 thread T0
|
||||
#0 0xffffa3d1bc6f (/usr/lib64/libasan.so.4+0x50c6f)
|
||||
#1 0xaaaae94e1d67 in library_get_prototype /root/rpmbuild/BUILD/ltrace-0.7.91/output.c:198
|
||||
#2 0xaaaae94e2f8f in lookup_symbol_prototype /root/rpmbuild/BUILD/ltrace-0.7.91/output.c:243
|
||||
#3 0xaaaae94e383b in lookup_symbol_prototype /root/rpmbuild/BUILD/ltrace-0.7.91/output.c:703
|
||||
#4 0xaaaae94e383b in output_right /root/rpmbuild/BUILD/ltrace-0.7.91/output.c:644
|
||||
#5 0xaaaae94e08d3 in output_right_tos /root/rpmbuild/BUILD/ltrace-0.7.91/handle_event.c:665
|
||||
#6 0xaaaae94e1a4f in handle_breakpoint /root/rpmbuild/BUILD/ltrace-0.7.91/handle_event.c:703
|
||||
#7 0xaaaae94e1a4f in handle_event /root/rpmbuild/BUILD/ltrace-0.7.91/handle_event.c:200
|
||||
#8 0xaaaae94ce237 in ltrace_main /root/rpmbuild/BUILD/ltrace-0.7.91/libltrace.c:174
|
||||
#9 0xaaaae94cdd1f in main /root/rpmbuild/BUILD/ltrace-0.7.91/main.c:55
|
||||
#10 0xffffa38ecadf in __libc_start_main (/lib64/libc.so.6+0x20adf)
|
||||
#11 0xaaaae94cdd5f (/ltrace+0x9d5f)
|
||||
|
||||
0xffffa0d00313 is located 3 bytes inside of 8-byte region [0xffffa0d00310,0xffffa0d00318)
|
||||
freed by thread T0 here:
|
||||
#0 0xffffa3d9b6c3 in free (/usr/lib64/libasan.so.4+0xd06c3)
|
||||
#1 0xaaaae94d101f in private_process_destroy /root/rpmbuild/BUILD/ltrace-0.7.91/proc.c:273
|
||||
#2 0xaaaae94d10ab in remove_process /root/rpmbuild/BUILD/ltrace-0.7.91/proc.c:753
|
||||
#3 0xaaaae94e0d73 in handle_exit_signal /root/rpmbuild/BUILD/ltrace-0.7.91/handle_event.c:521
|
||||
#4 0xaaaae94e0d73 in handle_event /root/rpmbuild/BUILD/ltrace-0.7.91/handle_event.c:142
|
||||
#5 0xaaaae94ce237 in ltrace_main /root/rpmbuild/BUILD/ltrace-0.7.91/libltrace.c:174
|
||||
#6 0xaaaae94cdd1f in main /root/rpmbuild/BUILD/ltrace-0.7.91/main.c:55
|
||||
#7 0xffffa38ecadf in __libc_start_main (/lib64/libc.so.6+0x20adf)
|
||||
#8 0xaaaae94cdd5f (/ltrace+0x9d5f)
|
||||
|
||||
previously allocated by thread T0 here:
|
||||
#0 0xffffa3d3e34f in strdup (/usr/lib64/libasan.so.4+0x7334f)
|
||||
#1 0xaaaae94cfb2b in process_bare_init /root/rpmbuild/BUILD/ltrace-0.7.91/proc.c:128
|
||||
#2 0xaaaae94cfcbf in process_init /root/rpmbuild/BUILD/ltrace-0.7.91/proc.c:214
|
||||
#3 0xaaaae94cfe17 in open_program /root/rpmbuild/BUILD/ltrace-0.7.91/proc.c:330
|
||||
#4 0xaaaae94ce09f in ltrace_init /root/rpmbuild/BUILD/ltrace-0.7.91/libltrace.c:125
|
||||
#5 0xaaaae94cdd1b in main /root/rpmbuild/BUILD/ltrace-0.7.91/main.c:47
|
||||
#6 0xffffa38ecadf in __libc_start_main (/lib64/libc.so.6+0x20adf)
|
||||
#7 0xaaaae94cdd5f (/ltrace+0x9d5f)
|
||||
|
||||
SUMMARY: AddressSanitizer: heap-use-after-free (/usr/lib64/libasan.so.4+0x50c6f)
|
||||
Shadow bytes around the buggy address:
|
||||
0x200ff41a0010: fa fa fd fa fa fa fd fa fa fa fd fa fa fa 00 00
|
||||
0x200ff41a0020: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00
|
||||
0x200ff41a0030: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00
|
||||
0x200ff41a0040: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00
|
||||
0x200ff41a0050: fa fa 00 00 fa fa fd fa fa fa fd fa fa fa fd fd
|
||||
=>0x200ff41a0060: fa fa[fd]fa fa fa 00 07 fa fa 06 fa fa fa 05 fa
|
||||
0x200ff41a0070: fa fa 00 00 fa fa 05 fa fa fa 00 00 fa fa 00 00
|
||||
0x200ff41a0080: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 01 fa
|
||||
0x200ff41a0090: fa fa 00 00 fa fa 00 00 fa fa 01 fa fa fa 00 00
|
||||
0x200ff41a00a0: fa fa 04 fa fa fa 04 fa fa fa 00 fa fa fa fd fd
|
||||
0x200ff41a00b0: fa fa 04 fa fa fa 04 fa fa fa 00 fa fa fa 04 fa
|
||||
Shadow byte legend (one shadow byte represents 8 application bytes):
|
||||
Addressable: 00
|
||||
Partially addressable: 01 02 03 04 05 06 07
|
||||
Heap left redzone: fa
|
||||
Freed heap region: fd
|
||||
Stack left redzone: f1
|
||||
Stack mid redzone: f2
|
||||
Stack right redzone: f3
|
||||
Stack after return: f5
|
||||
Stack use after scope: f8
|
||||
Global redzone: f9
|
||||
Global init order: f6
|
||||
Poisoned by user: f7
|
||||
Container overflow: fc
|
||||
Array cookie: ac
|
||||
Intra object redzone: bb
|
||||
ASan internal: fe
|
||||
Left alloca redzone: ca
|
||||
Right alloca redzone: cb
|
||||
=================================================================
|
||||
==18904==ERROR: AddressSanitizer: heap-use-after-free on address 0xffffa0d00313 at pc 0xffffa3d3fbe4 bp 0xffffe9c118c0 sp 0xffffe9c11938
|
||||
READ of size 5 at 0xffffa0d00313 thread T0
|
||||
#0 0xffffa3d3fbe3 (/usr/lib64/libasan.so.4+0x74be3)
|
||||
#1 0xaaaae94e1db3 in memcpy /usr/include/bits/string_fortified.h:34
|
||||
#2 0xaaaae94e1db3 in library_get_prototype /root/rpmbuild/BUILD/ltrace-0.7.91/output.c:200
|
||||
#3 0xaaaae94e2f8f in lookup_symbol_prototype /root/rpmbuild/BUILD/ltrace-0.7.91/output.c:243
|
||||
#4 0xaaaae94e383b in lookup_symbol_prototype /root/rpmbuild/BUILD/ltrace-0.7.91/output.c:703
|
||||
#5 0xaaaae94e383b in output_right /root/rpmbuild/BUILD/ltrace-0.7.91/output.c:644
|
||||
#6 0xaaaae94e08d3 in output_right_tos /root/rpmbuild/BUILD/ltrace-0.7.91/handle_event.c:665
|
||||
#7 0xaaaae94e1a4f in handle_breakpoint /root/rpmbuild/BUILD/ltrace-0.7.91/handle_event.c:703
|
||||
#8 0xaaaae94e1a4f in handle_event /root/rpmbuild/BUILD/ltrace-0.7.91/handle_event.c:200
|
||||
#9 0xaaaae94ce237 in ltrace_main /root/rpmbuild/BUILD/ltrace-0.7.91/libltrace.c:174
|
||||
#10 0xaaaae94cdd1f in main /root/rpmbuild/BUILD/ltrace-0.7.91/main.c:55
|
||||
#11 0xffffa38ecadf in __libc_start_main (/lib64/libc.so.6+0x20adf)
|
||||
#12 0xaaaae94cdd5f (/ltrace+0x9d5f)
|
||||
|
||||
0xffffa0d00313 is located 3 bytes inside of 8-byte region [0xffffa0d00310,0xffffa0d00318)
|
||||
freed by thread T0 here:
|
||||
#0 0xffffa3d9b6c3 in free (/usr/lib64/libasan.so.4+0xd06c3)
|
||||
#1 0xaaaae94d101f in private_process_destroy /root/rpmbuild/BUILD/ltrace-0.7.91/proc.c:273
|
||||
#2 0xaaaae94d10ab in remove_process /root/rpmbuild/BUILD/ltrace-0.7.91/proc.c:753
|
||||
#3 0xaaaae94e0d73 in handle_exit_signal /root/rpmbuild/BUILD/ltrace-0.7.91/handle_event.c:521
|
||||
#4 0xaaaae94e0d73 in handle_event /root/rpmbuild/BUILD/ltrace-0.7.91/handle_event.c:142
|
||||
#5 0xaaaae94ce237 in ltrace_main /root/rpmbuild/BUILD/ltrace-0.7.91/libltrace.c:174
|
||||
#6 0xaaaae94cdd1f in main /root/rpmbuild/BUILD/ltrace-0.7.91/main.c:55
|
||||
#7 0xffffa38ecadf in __libc_start_main (/lib64/libc.so.6+0x20adf)
|
||||
#8 0xaaaae94cdd5f (/ltrace+0x9d5f)
|
||||
|
||||
previously allocated by thread T0 here:
|
||||
#0 0xffffa3d3e34f in strdup (/usr/lib64/libasan.so.4+0x7334f)
|
||||
#1 0xaaaae94cfb2b in process_bare_init /root/rpmbuild/BUILD/ltrace-0.7.91/proc.c:128
|
||||
#2 0xaaaae94cfcbf in process_init /root/rpmbuild/BUILD/ltrace-0.7.91/proc.c:214
|
||||
#3 0xaaaae94cfe17 in open_program /root/rpmbuild/BUILD/ltrace-0.7.91/proc.c:330
|
||||
#4 0xaaaae94ce09f in ltrace_init /root/rpmbuild/BUILD/ltrace-0.7.91/libltrace.c:125
|
||||
#5 0xaaaae94cdd1b in main /root/rpmbuild/BUILD/ltrace-0.7.91/main.c:47
|
||||
#6 0xffffa38ecadf in __libc_start_main (/lib64/libc.so.6+0x20adf)
|
||||
#7 0xaaaae94cdd5f (/ltrace+0x9d5f)
|
||||
|
||||
SUMMARY: AddressSanitizer: heap-use-after-free (/usr/lib64/libasan.so.4+0x74be3)
|
||||
---
|
||||
ltrace-elf.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ltrace-elf.c b/ltrace-elf.c
|
||||
index f638342..286790a 100644
|
||||
--- a/ltrace-elf.c
|
||||
+++ b/ltrace-elf.c
|
||||
@@ -1214,12 +1214,14 @@ read_module(struct library *lib, struct process *proc,
|
||||
goto fail;
|
||||
library_set_soname(lib, soname, 1);
|
||||
} else {
|
||||
+ char *soname_str = NULL;
|
||||
const char *soname = rindex(lib->pathname, '/');
|
||||
if (soname != NULL)
|
||||
soname += 1;
|
||||
else
|
||||
soname = lib->pathname;
|
||||
- library_set_soname(lib, soname, 0);
|
||||
+ soname_str = strdup(soname);
|
||||
+ library_set_soname(lib, soname_str, 1);
|
||||
}
|
||||
|
||||
/* XXX The double cast should be removed when
|
||||
--
|
||||
2.19.1
|
||||
|
||||
20
ltrace-0.7.2-e_machine.patch
Normal file
20
ltrace-0.7.2-e_machine.patch
Normal file
@ -0,0 +1,20 @@
|
||||
diff -up ltrace-0.7.2/proc.c\~ ltrace-0.7.2/proc.c
|
||||
--- ltrace-0.7.2/proc.c~ 2014-02-13 12:16:33.000000000 +0100
|
||||
+++ ltrace-0.7.2/proc.c 2014-02-13 15:44:25.000000000 +0100
|
||||
@@ -194,9 +197,11 @@ process_init(struct process *proc, const
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if (proc->leader != proc)
|
||||
- return 0;
|
||||
- if (process_init_main(proc) < 0) {
|
||||
+ if (proc->leader != proc) {
|
||||
+ proc->e_machine = proc->leader->e_machine;
|
||||
+ proc->e_class = proc->leader->e_class;
|
||||
+ get_arch_dep(proc);
|
||||
+ } else if (process_init_main(proc) < 0) {
|
||||
process_bare_destroy(proc, 0);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
Diff finished. Thu Feb 13 15:50:21 2014
|
||||
37
ltrace-0.7.91-aarch64-params.patch
Normal file
37
ltrace-0.7.91-aarch64-params.patch
Normal file
@ -0,0 +1,37 @@
|
||||
diff -rup a/sysdeps/linux-gnu/aarch64/fetch.c b/sysdeps/linux-gnu/aarch64/fetch.c
|
||||
--- a/sysdeps/linux-gnu/aarch64/fetch.c 2018-07-05 16:06:10.066626252 -0400
|
||||
+++ b/sysdeps/linux-gnu/aarch64/fetch.c 2018-07-05 16:17:17.659748481 -0400
|
||||
@@ -308,12 +308,9 @@ arch_fetch_arg_init(enum tof type, struc
|
||||
struct fetch_script how = pass_arg(context, proc, ret_info);
|
||||
if (how.c == CVT_ERR)
|
||||
goto fail;
|
||||
- if (how.c == CVT_NOP && how.f == FETCH_STACK) {
|
||||
+ if (how.c == CVT_BYREF && how.f == FETCH_GPR) {
|
||||
/* XXX double cast. */
|
||||
context->x8 = (arch_addr_t) (uintptr_t) context->gregs.regs[8];
|
||||
- /* See the comment above about the assert. */
|
||||
- assert(! "Unexpected: first argument passed on stack.");
|
||||
- abort();
|
||||
}
|
||||
|
||||
return context;
|
||||
diff -rup a/testsuite/ltrace.main/system_call_params.exp b/testsuite/ltrace.main/system_call_params.exp
|
||||
--- a/testsuite/ltrace.main/system_call_params.exp 2018-07-05 16:06:10.516624926 -0400
|
||||
+++ b/testsuite/ltrace.main/system_call_params.exp 2018-07-05 16:58:01.549830643 -0400
|
||||
@@ -61,13 +61,13 @@ set conf [ltraceNamedSource "$dir/syscal
|
||||
# doesn't list readdir, that would be taken from somelib.conf with a
|
||||
# wrong prototype.
|
||||
|
||||
-ltraceMatch1 [ltraceRun -L -S -F $conf -- $bin] {^open@SYS\("/some/path"} == 0
|
||||
+ltraceMatch1 [ltraceRun -L -S -F $conf -- $bin] {^open@SYS\("/some/path", 0\)} == 0
|
||||
|
||||
# On the other hand, if -F somedir/ is given, we want to accept
|
||||
# syscalls.conf found there.
|
||||
|
||||
ltraceMatch [ltraceRun -L -S -F $dir -- $bin] {
|
||||
- {{^open@SYS\("/some/path"} == 1}
|
||||
+ {{^open@SYS\("/some/path", 0\)} == 1}
|
||||
{{^write@SYS\(1, "something", 10\)} == 1}
|
||||
{{^mount@SYS\("source", "target", "filesystemtype"} == 1}
|
||||
}
|
||||
Only in b/testsuite/ltrace.main: system_call_params.exp~
|
||||
2416
ltrace-0.7.91-aarch64.patch
Normal file
2416
ltrace-0.7.91-aarch64.patch
Normal file
File diff suppressed because it is too large
Load Diff
834
ltrace-0.7.91-account_execl.patch
Normal file
834
ltrace-0.7.91-account_execl.patch
Normal file
@ -0,0 +1,834 @@
|
||||
From 0cf4ab66e9927e101a51dd9fa9adc6c8dc56b5e7 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Machata <pmachata@redhat.com>
|
||||
Date: Thu, 21 Nov 2013 20:25:53 +0100
|
||||
Subject: [PATCH] Consider exec and exit events an end of outstanding calls
|
||||
|
||||
- This cleans up a lot of stuff. The actual substance is addition of
|
||||
account_current_callstack in handle_event.c (which however uses
|
||||
those cleaned-up interfaces).
|
||||
|
||||
- trace-exec.exp was extended to check that the exec syscall can be
|
||||
seen in -c output. That's one of the symptoms of what this fixes.
|
||||
---
|
||||
Makefile.am | 8 +-
|
||||
common.h | 2 -
|
||||
forward.h | 1 +
|
||||
handle_event.c | 225 ++++++++++++++++++++-------------
|
||||
libltrace.c | 5 +-
|
||||
options.h | 8 +-
|
||||
output.c | 86 +++----------
|
||||
output.h | 5 +-
|
||||
proc.h | 2 +-
|
||||
summary.c | 89 +++++++++++++-
|
||||
summary.h | 35 +++++
|
||||
testsuite/ltrace.minor/trace-exec.exp | 16 ++-
|
||||
12 files changed, 299 insertions(+), 183 deletions(-)
|
||||
create mode 100644 summary.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index d711aec..efcf18a 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -54,10 +54,10 @@ ltrace_LDADD = \
|
||||
|
||||
noinst_HEADERS = bits.h backend.h breakpoint.h common.h debug.h \
|
||||
defs.h demangle.h dict.h forward.h ltrace-elf.h ltrace.h \
|
||||
- options.h output.h proc.h read_config_file.h library.h \
|
||||
- filter.h glob.h vect.h type.h value.h value_dict.h callback.h \
|
||||
- expr.h fetch.h vect.h param.h printf.h zero.h lens.h \
|
||||
- lens_default.h lens_enum.h memstream.h prototype.h
|
||||
+ options.h output.h proc.h read_config_file.h summary.h \
|
||||
+ library.h filter.h glob.h vect.h type.h value.h value_dict.h \
|
||||
+ callback.h expr.h fetch.h vect.h param.h printf.h zero.h \
|
||||
+ lens.h lens_default.h lens_enum.h memstream.h prototype.h
|
||||
|
||||
dist_man1_MANS = ltrace.1
|
||||
dist_man5_MANS = ltrace.conf.5
|
||||
diff --git a/common.h b/common.h
|
||||
index a53c5db..7259ba4 100644
|
||||
--- a/common.h
|
||||
+++ b/common.h
|
||||
@@ -54,8 +54,6 @@ extern void handle_event(Event * event);
|
||||
|
||||
extern pid_t execute_program(const char * command, char ** argv);
|
||||
|
||||
-extern void show_summary(void);
|
||||
-
|
||||
struct breakpoint;
|
||||
struct library_symbol;
|
||||
|
||||
diff --git a/forward.h b/forward.h
|
||||
index 8641213..58d8f05 100644
|
||||
--- a/forward.h
|
||||
+++ b/forward.h
|
||||
@@ -34,6 +34,7 @@ struct param_enum;
|
||||
struct process;
|
||||
struct protolib;
|
||||
struct prototype;
|
||||
+struct timedelta;
|
||||
struct value;
|
||||
struct value_dict;
|
||||
struct vect;
|
||||
diff --git a/handle_event.c b/handle_event.c
|
||||
index 9ed62a2..6fa7e98 100644
|
||||
--- a/handle_event.c
|
||||
+++ b/handle_event.c
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
-#include <sys/time.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "backend.h"
|
||||
@@ -41,8 +40,9 @@
|
||||
#include "fetch.h"
|
||||
#include "library.h"
|
||||
#include "proc.h"
|
||||
-#include "value_dict.h"
|
||||
#include "prototype.h"
|
||||
+#include "summary.h"
|
||||
+#include "value_dict.h"
|
||||
|
||||
static void handle_signal(Event *event);
|
||||
static void handle_exit(Event *event);
|
||||
@@ -419,32 +419,11 @@ handle_signal(Event *event) {
|
||||
continue_after_signal(event->proc->pid, event->e_un.signum);
|
||||
}
|
||||
|
||||
-static void
|
||||
-handle_exit(Event *event) {
|
||||
- debug(DEBUG_FUNCTION, "handle_exit(pid=%d, status=%d)", event->proc->pid, event->e_un.ret_val);
|
||||
- if (event->proc->state != STATE_IGNORED) {
|
||||
- output_line(event->proc, "+++ exited (status %d) +++",
|
||||
- event->e_un.ret_val);
|
||||
- }
|
||||
- remove_process(event->proc);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-handle_exit_signal(Event *event) {
|
||||
- debug(DEBUG_FUNCTION, "handle_exit_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum);
|
||||
- if (event->proc->state != STATE_IGNORED) {
|
||||
- output_line(event->proc, "+++ killed by %s +++",
|
||||
- shortsignal(event->proc, event->e_un.signum));
|
||||
- }
|
||||
- remove_process(event->proc);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-output_syscall(struct process *proc, const char *name, enum tof tof,
|
||||
- void (*output)(enum tof, struct process *,
|
||||
- struct library_symbol *))
|
||||
+static int
|
||||
+init_syscall_symbol(struct library_symbol *libsym, const char *name)
|
||||
{
|
||||
static struct library syscall_lib;
|
||||
+
|
||||
if (syscall_lib.protolib == NULL) {
|
||||
struct protolib *protolib
|
||||
= protolib_cache_load(&g_protocache, "syscalls", 0, 1);
|
||||
@@ -475,10 +454,91 @@ output_syscall(struct process *proc, const char *name, enum tof tof,
|
||||
syscall_lib.protolib = protolib;
|
||||
}
|
||||
|
||||
+ if (library_symbol_init(libsym, 0, name, 0, LS_TOPLT_NONE) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ libsym->lib = &syscall_lib;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Account the unfinished functions on the call stack. */
|
||||
+static void
|
||||
+account_current_callstack(struct process *proc)
|
||||
+{
|
||||
+ if (! options.summary)
|
||||
+ return;
|
||||
+
|
||||
+ struct timedelta spent[proc->callstack_depth];
|
||||
+
|
||||
+ size_t i;
|
||||
+ for (i = 0; i < proc->callstack_depth; ++i) {
|
||||
+ struct callstack_element *elem = &proc->callstack[i];
|
||||
+ spent[i] = calc_time_spent(elem->enter_time);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < proc->callstack_depth; ++i) {
|
||||
+ struct callstack_element *elem = &proc->callstack[i];
|
||||
+ struct library_symbol syscall, *libsym = NULL;
|
||||
+ if (elem->is_syscall) {
|
||||
+ const char *name = sysname(proc, elem->c_un.syscall);
|
||||
+ if (init_syscall_symbol(&syscall, name) >= 0)
|
||||
+ libsym = &syscall;
|
||||
+
|
||||
+ } else {
|
||||
+ libsym = elem->c_un.libfunc;
|
||||
+ }
|
||||
+
|
||||
+ if (libsym != NULL) {
|
||||
+ summary_account_call(libsym, spent[i]);
|
||||
+
|
||||
+ if (elem->is_syscall)
|
||||
+ library_symbol_destroy(&syscall);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+handle_exit(Event *event) {
|
||||
+ debug(DEBUG_FUNCTION, "handle_exit(pid=%d, status=%d)", event->proc->pid, event->e_un.ret_val);
|
||||
+ if (event->proc->state != STATE_IGNORED) {
|
||||
+ output_line(event->proc, "+++ exited (status %d) +++",
|
||||
+ event->e_un.ret_val);
|
||||
+ }
|
||||
+
|
||||
+ account_current_callstack(event->proc);
|
||||
+ remove_process(event->proc);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+handle_exit_signal(Event *event) {
|
||||
+ debug(DEBUG_FUNCTION, "handle_exit_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum);
|
||||
+ if (event->proc->state != STATE_IGNORED) {
|
||||
+ output_line(event->proc, "+++ killed by %s +++",
|
||||
+ shortsignal(event->proc, event->e_un.signum));
|
||||
+ }
|
||||
+
|
||||
+ account_current_callstack(event->proc);
|
||||
+ remove_process(event->proc);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+output_syscall(struct process *proc, const char *name, enum tof tof,
|
||||
+ bool left, struct timedelta *spent)
|
||||
+{
|
||||
+ if (left)
|
||||
+ assert(spent == NULL);
|
||||
+
|
||||
struct library_symbol syscall;
|
||||
- if (library_symbol_init(&syscall, 0, name, 0, LS_TOPLT_NONE) >= 0) {
|
||||
- syscall.lib = &syscall_lib;
|
||||
- (*output)(tof, proc, &syscall);
|
||||
+ if (init_syscall_symbol(&syscall, name) >= 0) {
|
||||
+ if (left) {
|
||||
+ if (! options.summary)
|
||||
+ output_left(tof, proc, &syscall);
|
||||
+ } else if (options.summary) {
|
||||
+ summary_account_call(&syscall, *spent);
|
||||
+ } else {
|
||||
+ output_right(tof, proc, &syscall, spent);
|
||||
+ }
|
||||
+
|
||||
library_symbol_destroy(&syscall);
|
||||
}
|
||||
}
|
||||
@@ -486,17 +546,19 @@ output_syscall(struct process *proc, const char *name, enum tof tof,
|
||||
static void
|
||||
output_syscall_left(struct process *proc, const char *name)
|
||||
{
|
||||
- output_syscall(proc, name, LT_TOF_SYSCALL, &output_left);
|
||||
+ output_syscall(proc, name, LT_TOF_SYSCALL, true, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
-output_syscall_right(struct process *proc, const char *name)
|
||||
+output_syscall_right(struct process *proc, const char *name,
|
||||
+ struct timedelta *spent)
|
||||
{
|
||||
- output_syscall(proc, name, LT_TOF_SYSCALLR, &output_right);
|
||||
+ output_syscall(proc, name, LT_TOF_SYSCALLR, false, spent);
|
||||
}
|
||||
|
||||
static void
|
||||
-handle_syscall(Event *event) {
|
||||
+handle_syscall(Event *event)
|
||||
+{
|
||||
debug(DEBUG_FUNCTION, "handle_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
|
||||
if (event->proc->state != STATE_IGNORED) {
|
||||
callstack_push_syscall(event->proc, event->e_un.sysnum);
|
||||
@@ -526,6 +588,8 @@ handle_exec(Event *event)
|
||||
}
|
||||
output_line(proc, "--- Called exec() ---");
|
||||
|
||||
+ account_current_callstack(proc);
|
||||
+
|
||||
if (process_exec(proc) < 0) {
|
||||
fprintf(stderr,
|
||||
"couldn't reinitialize process %d after exec\n", pid);
|
||||
@@ -549,74 +613,58 @@ handle_arch_syscall(Event *event) {
|
||||
continue_process(event->proc->pid);
|
||||
}
|
||||
|
||||
-struct timeval current_time_spent;
|
||||
-
|
||||
static void
|
||||
-calc_time_spent(struct process *proc)
|
||||
+handle_x_sysret(Event *event, char *(*name_cb)(struct process *, int))
|
||||
{
|
||||
- struct timeval tv;
|
||||
- struct timezone tz;
|
||||
- struct timeval diff;
|
||||
- struct callstack_element *elem;
|
||||
-
|
||||
- debug(DEBUG_FUNCTION, "calc_time_spent(pid=%d)", proc->pid);
|
||||
- elem = &proc->callstack[proc->callstack_depth - 1];
|
||||
-
|
||||
- gettimeofday(&tv, &tz);
|
||||
+ debug(DEBUG_FUNCTION, "handle_x_sysret(pid=%d, sysnum=%d)",
|
||||
+ event->proc->pid, event->e_un.sysnum);
|
||||
|
||||
- diff.tv_sec = tv.tv_sec - elem->time_spent.tv_sec;
|
||||
- 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_usec = 1000000 + tv.tv_usec - elem->time_spent.tv_usec;
|
||||
- }
|
||||
- current_time_spent = diff;
|
||||
-}
|
||||
+ unsigned d = event->proc->callstack_depth;
|
||||
+ assert(d > 0);
|
||||
+ struct callstack_element *elem = &event->proc->callstack[d - 1];
|
||||
+ assert(elem->is_syscall);
|
||||
|
||||
-static void
|
||||
-handle_sysret(Event *event) {
|
||||
- debug(DEBUG_FUNCTION, "handle_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
|
||||
if (event->proc->state != STATE_IGNORED) {
|
||||
- if (opt_T || options.summary) {
|
||||
- calc_time_spent(event->proc);
|
||||
- }
|
||||
+ struct timedelta spent = calc_time_spent(elem->enter_time);
|
||||
if (options.syscalls)
|
||||
output_syscall_right(event->proc,
|
||||
- sysname(event->proc,
|
||||
- event->e_un.sysnum));
|
||||
+ name_cb(event->proc,
|
||||
+ event->e_un.sysnum),
|
||||
+ &spent);
|
||||
|
||||
- assert(event->proc->callstack_depth > 0);
|
||||
- unsigned d = event->proc->callstack_depth - 1;
|
||||
- assert(event->proc->callstack[d].is_syscall);
|
||||
callstack_pop(event->proc);
|
||||
}
|
||||
continue_after_syscall(event->proc, event->e_un.sysnum, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
-handle_arch_sysret(Event *event) {
|
||||
- debug(DEBUG_FUNCTION, "handle_arch_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
|
||||
- if (event->proc->state != STATE_IGNORED) {
|
||||
- if (opt_T || options.summary) {
|
||||
- calc_time_spent(event->proc);
|
||||
- }
|
||||
- if (options.syscalls)
|
||||
- output_syscall_right(event->proc,
|
||||
- arch_sysname(event->proc,
|
||||
- event->e_un.sysnum));
|
||||
- callstack_pop(event->proc);
|
||||
- }
|
||||
- continue_process(event->proc->pid);
|
||||
+handle_sysret(Event *event)
|
||||
+{
|
||||
+ handle_x_sysret(event, &sysname);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+handle_arch_sysret(Event *event)
|
||||
+{
|
||||
+ handle_x_sysret(event, &arch_sysname);
|
||||
}
|
||||
|
||||
static void
|
||||
output_right_tos(struct process *proc)
|
||||
{
|
||||
size_t d = proc->callstack_depth;
|
||||
+ assert(d > 0);
|
||||
struct callstack_element *elem = &proc->callstack[d - 1];
|
||||
- if (proc->state != STATE_IGNORED)
|
||||
- output_right(LT_TOF_FUNCTIONR, proc, elem->c_un.libfunc);
|
||||
+ assert(! elem->is_syscall);
|
||||
+
|
||||
+ if (proc->state != STATE_IGNORED) {
|
||||
+ struct timedelta spent = calc_time_spent(elem->enter_time);
|
||||
+ if (options.summary)
|
||||
+ summary_account_call(elem->c_un.libfunc, spent);
|
||||
+ else
|
||||
+ output_right(LT_TOF_FUNCTIONR, proc, elem->c_un.libfunc,
|
||||
+ &spent);
|
||||
+ }
|
||||
}
|
||||
|
||||
#ifndef ARCH_HAVE_SYMBOL_RET
|
||||
@@ -645,14 +693,8 @@ handle_breakpoint(Event *event)
|
||||
|
||||
for (i = event->proc->callstack_depth - 1; i >= 0; i--) {
|
||||
if (brk_addr == event->proc->callstack[i].return_addr) {
|
||||
- for (j = event->proc->callstack_depth - 1; j > i; j--) {
|
||||
+ for (j = event->proc->callstack_depth - 1; j > i; j--)
|
||||
callstack_pop(event->proc);
|
||||
- }
|
||||
- if (event->proc->state != STATE_IGNORED) {
|
||||
- if (opt_T || options.summary) {
|
||||
- calc_time_spent(event->proc);
|
||||
- }
|
||||
- }
|
||||
|
||||
struct library_symbol *libsym =
|
||||
event->proc->callstack[i].c_un.libfunc;
|
||||
@@ -705,11 +747,14 @@ handle_breakpoint(Event *event)
|
||||
/* breakpoint_on_hit may delete its own breakpoint, so we have
|
||||
* to look it up again. */
|
||||
if ((sbp = address2bpstruct(leader, brk_addr)) != NULL) {
|
||||
+
|
||||
if (event->proc->state != STATE_IGNORED
|
||||
&& sbp->libsym != NULL) {
|
||||
event->proc->stack_pointer = get_stack_pointer(event->proc);
|
||||
callstack_push_symfunc(event->proc, sbp);
|
||||
- output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym);
|
||||
+ if (! options.summary)
|
||||
+ output_left(LT_TOF_FUNCTION, event->proc,
|
||||
+ sbp->libsym);
|
||||
}
|
||||
|
||||
breakpoint_on_continue(sbp, event->proc);
|
||||
@@ -743,7 +788,7 @@ callstack_push_syscall(struct process *proc, int sysnum)
|
||||
proc->callstack_depth++;
|
||||
if (opt_T || options.summary) {
|
||||
struct timezone tz;
|
||||
- gettimeofday(&elem->time_spent, &tz);
|
||||
+ gettimeofday(&elem->enter_time, &tz);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -781,7 +826,7 @@ callstack_push_symfunc(struct process *proc, struct breakpoint *bp)
|
||||
|
||||
if (opt_T || options.summary) {
|
||||
struct timezone tz;
|
||||
- gettimeofday(&elem->time_spent, &tz);
|
||||
+ gettimeofday(&elem->enter_time, &tz);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/libltrace.c b/libltrace.c
|
||||
index 2d910a1..0112c9f 100644
|
||||
--- a/libltrace.c
|
||||
+++ b/libltrace.c
|
||||
@@ -32,11 +32,12 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#include "backend.h"
|
||||
#include "common.h"
|
||||
#include "proc.h"
|
||||
-#include "read_config_file.h"
|
||||
-#include "backend.h"
|
||||
#include "prototype.h"
|
||||
+#include "read_config_file.h"
|
||||
+#include "summary.h"
|
||||
|
||||
char *command = NULL;
|
||||
|
||||
diff --git a/options.h b/options.h
|
||||
index 6c28ed9..d0df3a7 100644
|
||||
--- a/options.h
|
||||
+++ b/options.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ltrace.
|
||||
- * Copyright (C) 2012 Petr Machata, Red Hat Inc.
|
||||
+ * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc.
|
||||
* Copyright (C) 2009,2010 Joe Damato
|
||||
* Copyright (C) 1998,2002,2008 Juan Cespedes
|
||||
* Copyright (C) 2006 Ian Wienand
|
||||
@@ -103,12 +103,6 @@ int parse_colon_separated_list(const char *paths, struct vect *vec);
|
||||
/* Vector of struct opt_F_t. */
|
||||
extern struct vect opt_F;
|
||||
|
||||
-struct opt_c_struct {
|
||||
- int count;
|
||||
- struct timeval tv;
|
||||
-};
|
||||
-extern struct dict *dict_opt_c;
|
||||
-
|
||||
extern char **process_options(int argc, char **argv);
|
||||
|
||||
#endif /* _OPTIONS_H_ */
|
||||
diff --git a/output.c b/output.c
|
||||
index edf4522..82b6a5e 100644
|
||||
--- a/output.c
|
||||
+++ b/output.c
|
||||
@@ -44,16 +44,12 @@
|
||||
#include "param.h"
|
||||
#include "proc.h"
|
||||
#include "prototype.h"
|
||||
+#include "summary.h"
|
||||
#include "type.h"
|
||||
#include "value.h"
|
||||
#include "value_dict.h"
|
||||
|
||||
-/* TODO FIXME XXX: include in common.h: */
|
||||
-extern struct timeval current_time_spent;
|
||||
-
|
||||
-struct dict *dict_opt_c = NULL;
|
||||
-
|
||||
-static struct process *current_proc = 0;
|
||||
+static struct process *current_proc = NULL;
|
||||
static size_t current_depth = 0;
|
||||
static int current_column = 0;
|
||||
|
||||
@@ -498,9 +494,8 @@ void
|
||||
output_left(enum tof type, struct process *proc,
|
||||
struct library_symbol *libsym)
|
||||
{
|
||||
- if (options.summary) {
|
||||
- return;
|
||||
- }
|
||||
+ assert(! options.summary);
|
||||
+
|
||||
if (current_proc) {
|
||||
fprintf(options.output, " <unfinished ...>\n");
|
||||
current_column = 0;
|
||||
@@ -572,70 +567,21 @@ output_left(enum tof type, struct process *proc,
|
||||
stel->out.need_delim = need_delim;
|
||||
}
|
||||
|
||||
-static void
|
||||
-free_stringp_cb(const char **stringp, void *data)
|
||||
-{
|
||||
- free((char *)*stringp);
|
||||
-}
|
||||
-
|
||||
void
|
||||
-output_right(enum tof type, struct process *proc, struct library_symbol *libsym)
|
||||
+output_right(enum tof type, struct process *proc, struct library_symbol *libsym,
|
||||
+ struct timedelta *spent)
|
||||
{
|
||||
+ assert(! options.summary);
|
||||
+
|
||||
struct prototype *func = lookup_symbol_prototype(proc, libsym);
|
||||
if (func == NULL)
|
||||
return;
|
||||
|
||||
-again:
|
||||
- if (options.summary) {
|
||||
- if (dict_opt_c == NULL) {
|
||||
- dict_opt_c = malloc(sizeof(*dict_opt_c));
|
||||
- if (dict_opt_c == NULL) {
|
||||
- oom:
|
||||
- fprintf(stderr,
|
||||
- "Can't allocate memory for "
|
||||
- "keeping track of -c.\n");
|
||||
- free(dict_opt_c);
|
||||
- options.summary = 0;
|
||||
- goto again;
|
||||
- }
|
||||
- DICT_INIT(dict_opt_c, char *, struct opt_c_struct,
|
||||
- dict_hash_string, dict_eq_string, NULL);
|
||||
- }
|
||||
-
|
||||
- struct opt_c_struct *st
|
||||
- = DICT_FIND_REF(dict_opt_c, &libsym->name,
|
||||
- struct opt_c_struct);
|
||||
- if (st == NULL) {
|
||||
- const char *na = strdup(libsym->name);
|
||||
- struct opt_c_struct new_st = {.count = 0, .tv = {0, 0}};
|
||||
- if (na == NULL
|
||||
- || DICT_INSERT(dict_opt_c, &na, &new_st) < 0) {
|
||||
- free((char *)na);
|
||||
- DICT_DESTROY(dict_opt_c, const char *,
|
||||
- struct opt_c_struct,
|
||||
- free_stringp_cb, NULL, NULL);
|
||||
- goto oom;
|
||||
- }
|
||||
- st = DICT_FIND_REF(dict_opt_c, &libsym->name,
|
||||
- struct opt_c_struct);
|
||||
- assert(st != NULL);
|
||||
- }
|
||||
-
|
||||
- if (st->tv.tv_usec + current_time_spent.tv_usec > 1000000) {
|
||||
- st->tv.tv_usec += current_time_spent.tv_usec - 1000000;
|
||||
- st->tv.tv_sec++;
|
||||
- } else {
|
||||
- st->tv.tv_usec += current_time_spent.tv_usec;
|
||||
- }
|
||||
- st->count++;
|
||||
- st->tv.tv_sec += current_time_spent.tv_sec;
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if (current_proc && (current_proc != proc ||
|
||||
- current_depth != proc->callstack_depth)) {
|
||||
+ if (current_proc != NULL
|
||||
+ && (current_proc != proc
|
||||
+ || current_depth != proc->callstack_depth)) {
|
||||
fprintf(options.output, " <unfinished ...>\n");
|
||||
- current_proc = 0;
|
||||
+ current_proc = NULL;
|
||||
}
|
||||
if (current_proc != proc) {
|
||||
begin_of_line(proc, type == LT_TOF_FUNCTIONR, 1);
|
||||
@@ -689,10 +635,12 @@ again:
|
||||
value_destroy(&retval);
|
||||
|
||||
if (opt_T) {
|
||||
+ assert(spent != NULL);
|
||||
fprintf(options.output, " <%lu.%06d>",
|
||||
- (unsigned long)current_time_spent.tv_sec,
|
||||
- (int)current_time_spent.tv_usec);
|
||||
+ (unsigned long) spent->tm.tv_sec,
|
||||
+ (int) spent->tm.tv_usec);
|
||||
}
|
||||
+
|
||||
fprintf(options.output, "\n");
|
||||
|
||||
#if defined(HAVE_LIBUNWIND)
|
||||
@@ -746,7 +694,7 @@ again:
|
||||
}
|
||||
#endif /* defined(HAVE_LIBUNWIND) */
|
||||
|
||||
- current_proc = 0;
|
||||
+ current_proc = NULL;
|
||||
current_column = 0;
|
||||
}
|
||||
|
||||
diff --git a/output.h b/output.h
|
||||
index b9f0518..2e74d61 100644
|
||||
--- a/output.h
|
||||
+++ b/output.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ltrace.
|
||||
- * Copyright (C) 2011, 2012 Petr Machata, Red Hat Inc.
|
||||
+ * Copyright (C) 2011, 2012, 2013 Petr Machata, Red Hat Inc.
|
||||
* Copyright (C) 2009 Juan Cespedes
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -28,7 +28,8 @@ void output_line(struct process *proc, const char *fmt, ...);
|
||||
void output_left(enum tof type, struct process *proc,
|
||||
struct library_symbol *libsym);
|
||||
void output_right(enum tof type, struct process *proc,
|
||||
- struct library_symbol *libsym);
|
||||
+ struct library_symbol *libsym,
|
||||
+ struct timedelta *spent);
|
||||
|
||||
/* This function is for emitting lists of comma-separated strings.
|
||||
*
|
||||
diff --git a/proc.h b/proc.h
|
||||
index e8032fa..64f8fe2 100644
|
||||
--- a/proc.h
|
||||
+++ b/proc.h
|
||||
@@ -66,7 +66,7 @@ struct callstack_element {
|
||||
} c_un;
|
||||
int is_syscall;
|
||||
arch_addr_t return_addr;
|
||||
- struct timeval time_spent;
|
||||
+ struct timeval enter_time;
|
||||
struct fetch_context *fetch_context;
|
||||
struct value_dict *arguments;
|
||||
struct output_state out;
|
||||
diff --git a/summary.c b/summary.c
|
||||
index 9e22086..9103f71 100644
|
||||
--- a/summary.c
|
||||
+++ b/summary.c
|
||||
@@ -22,11 +22,15 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
+#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
-#include <sys/time.h>
|
||||
+#include <string.h>
|
||||
|
||||
-#include "common.h"
|
||||
+#include "summary.h"
|
||||
+#include "dict.h"
|
||||
+#include "library.h"
|
||||
+#include "options.h"
|
||||
|
||||
struct entry_st {
|
||||
const char *name;
|
||||
@@ -40,6 +44,32 @@ struct fill_struct_data {
|
||||
unsigned long tot_usecs;
|
||||
};
|
||||
|
||||
+struct opt_c_struct {
|
||||
+ int count;
|
||||
+ struct timeval tv;
|
||||
+};
|
||||
+
|
||||
+static struct dict *dict_opt_c;
|
||||
+
|
||||
+struct timedelta
|
||||
+calc_time_spent(struct timeval start)
|
||||
+{
|
||||
+ struct timeval tv;
|
||||
+ gettimeofday(&tv, NULL);
|
||||
+
|
||||
+ struct timeval diff;
|
||||
+ diff.tv_sec = tv.tv_sec - start.tv_sec;
|
||||
+ if (tv.tv_usec >= start.tv_usec) {
|
||||
+ diff.tv_usec = tv.tv_usec - start.tv_usec;
|
||||
+ } else {
|
||||
+ diff.tv_sec--;
|
||||
+ diff.tv_usec = 1000000 + tv.tv_usec - start.tv_usec;
|
||||
+ }
|
||||
+
|
||||
+ struct timedelta ret = { diff };
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static enum callback_status
|
||||
fill_struct(const char **namep, struct opt_c_struct *st, void *u)
|
||||
{
|
||||
@@ -114,3 +144,58 @@ show_summary(void)
|
||||
|
||||
vect_destroy(&cdata.entries, NULL, NULL);
|
||||
}
|
||||
+
|
||||
+static void
|
||||
+free_stringp_cb(const char **stringp, void *data)
|
||||
+{
|
||||
+ free((char *)*stringp);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+summary_account_call(struct library_symbol *libsym, struct timedelta spent)
|
||||
+{
|
||||
+ assert(options.summary);
|
||||
+
|
||||
+ if (dict_opt_c == NULL) {
|
||||
+ dict_opt_c = malloc(sizeof(*dict_opt_c));
|
||||
+ if (dict_opt_c == NULL) {
|
||||
+ oom:
|
||||
+ fprintf(stderr,
|
||||
+ "Can't allocate memory for "
|
||||
+ "keeping track of -c.\n");
|
||||
+ free(dict_opt_c);
|
||||
+ options.summary = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ DICT_INIT(dict_opt_c, char *, struct opt_c_struct,
|
||||
+ dict_hash_string, dict_eq_string, NULL);
|
||||
+ }
|
||||
+
|
||||
+ struct opt_c_struct *st = DICT_FIND_REF(dict_opt_c, &libsym->name,
|
||||
+ struct opt_c_struct);
|
||||
+ if (st == NULL) {
|
||||
+ const char *na = strdup(libsym->name);
|
||||
+ struct opt_c_struct new_st = {.count = 0, .tv = {0, 0}};
|
||||
+ if (na == NULL
|
||||
+ || DICT_INSERT(dict_opt_c, &na, &new_st) < 0) {
|
||||
+ free((char *) na);
|
||||
+ DICT_DESTROY(dict_opt_c, const char *,
|
||||
+ struct opt_c_struct,
|
||||
+ free_stringp_cb, NULL, NULL);
|
||||
+ goto oom;
|
||||
+ }
|
||||
+ st = DICT_FIND_REF(dict_opt_c, &libsym->name,
|
||||
+ struct opt_c_struct);
|
||||
+ assert(st != NULL);
|
||||
+ }
|
||||
+
|
||||
+ if (st->tv.tv_usec + spent.tm.tv_usec > 1000000) {
|
||||
+ st->tv.tv_usec += spent.tm.tv_usec - 1000000;
|
||||
+ st->tv.tv_sec++;
|
||||
+ } else {
|
||||
+ st->tv.tv_usec += spent.tm.tv_usec;
|
||||
+ }
|
||||
+ st->count++;
|
||||
+ st->tv.tv_sec += spent.tm.tv_sec;
|
||||
+ return;
|
||||
+}
|
||||
diff --git a/summary.h b/summary.h
|
||||
new file mode 100644
|
||||
index 0000000..f680ef9
|
||||
--- /dev/null
|
||||
+++ b/summary.h
|
||||
@@ -0,0 +1,35 @@
|
||||
+/*
|
||||
+ * This file is part of ltrace.
|
||||
+ * Copyright (C) 2013 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 _SUMMARY_H_
|
||||
+#define _SUMMARY_H_
|
||||
+
|
||||
+#include "forward.h"
|
||||
+
|
||||
+struct timedelta {
|
||||
+ struct timeval tm;
|
||||
+};
|
||||
+
|
||||
+struct timedelta calc_time_spent(struct timeval start);
|
||||
+void summary_account_call(struct library_symbol *libsym,
|
||||
+ struct timedelta spent);
|
||||
+void show_summary(void);
|
||||
+
|
||||
+#endif /* _SUMMARY_H_ */
|
||||
diff --git a/testsuite/ltrace.minor/trace-exec.exp b/testsuite/ltrace.minor/trace-exec.exp
|
||||
index 7a953de..57260f8 100644
|
||||
--- a/testsuite/ltrace.minor/trace-exec.exp
|
||||
+++ b/testsuite/ltrace.minor/trace-exec.exp
|
||||
@@ -1,5 +1,5 @@
|
||||
# This file is part of ltrace.
|
||||
-# Copyright (C) 2012 Petr Machata, Red Hat Inc.
|
||||
+# Copyright (C) 2012, 2013 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
|
||||
@@ -16,22 +16,30 @@
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
# 02110-1301 USA
|
||||
|
||||
-ltraceMatch [ltraceRun -xmain -- [ltraceCompile {} [ltraceSource c {
|
||||
+set bin1 [ltraceCompile {} [ltraceSource c {
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
int main(int argc, char ** argv) {
|
||||
execl(argv[1], argv[1], NULL);
|
||||
abort();
|
||||
}
|
||||
-}]] [ltraceCompile {} [ltraceSource c {
|
||||
+}]]
|
||||
+
|
||||
+set bin2 [ltraceCompile {} [ltraceSource c {
|
||||
#include <stdio.h>
|
||||
int main(void) {
|
||||
return puts("Hello, World.");
|
||||
}
|
||||
-}]]] {
|
||||
+}]]
|
||||
+
|
||||
+ltraceMatch [ltraceRun -xmain -- $bin1 $bin2] {
|
||||
{{^execl\(} == 1}
|
||||
{{^puts\(.*\) .*= 14} == 1}
|
||||
{{^main\(} == 2}
|
||||
}
|
||||
|
||||
+ltraceMatch [ltraceRun -c -- $bin1 $bin2] {
|
||||
+ {{exec} > 0}
|
||||
+}
|
||||
+
|
||||
ltraceDone
|
||||
--
|
||||
1.7.6.5
|
||||
|
||||
36
ltrace-0.7.91-cant_open.patch
Normal file
36
ltrace-0.7.91-cant_open.patch
Normal file
@ -0,0 +1,36 @@
|
||||
diff -urp ltrace-0.7.91/libltrace.c master/libltrace.c
|
||||
--- ltrace-0.7.91/libltrace.c 2014-01-14 16:31:37.696174464 +0100
|
||||
+++ master/libltrace.c 2013-11-21 14:06:38.623701688 +0100
|
||||
@@ -113,9 +117,13 @@ ltrace_init(int argc, char **argv) {
|
||||
if (command) {
|
||||
/* Check that the binary ABI is supported before
|
||||
* calling execute_program. */
|
||||
- struct ltelf lte;
|
||||
- ltelf_init(<e, command);
|
||||
- ltelf_destroy(<e);
|
||||
+ {
|
||||
+ struct ltelf lte;
|
||||
+ if (ltelf_init(<e, command) == 0)
|
||||
+ ltelf_destroy(<e);
|
||||
+ else
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
|
||||
pid_t pid = execute_program(command, argv);
|
||||
struct process *proc = open_program(command, pid);
|
||||
diff -urp ltrace-0.7.91/ltrace-elf.c master/ltrace-elf.c
|
||||
--- ltrace-0.7.91/ltrace-elf.c 2014-01-14 16:31:37.688174420 +0100
|
||||
+++ master/ltrace-elf.c 2013-11-22 18:17:11.767721609 +0100
|
||||
@@ -361,8 +361,11 @@ ltelf_init(struct ltelf *lte, const char
|
||||
{
|
||||
memset(lte, 0, sizeof *lte);
|
||||
lte->fd = open(filename, O_RDONLY);
|
||||
- if (lte->fd == -1)
|
||||
+ if (lte->fd == -1) {
|
||||
+ fprintf(stderr, "Can't open %s: %s\n", filename,
|
||||
+ strerror(errno));
|
||||
return 1;
|
||||
+ }
|
||||
|
||||
elf_version(EV_CURRENT);
|
||||
|
||||
45
ltrace-0.7.91-man.patch
Normal file
45
ltrace-0.7.91-man.patch
Normal file
@ -0,0 +1,45 @@
|
||||
diff -up ltrace-0.7.91/options.c\~ ltrace-0.7.91/options.c
|
||||
--- ltrace-0.7.91/options.c~ 2013-10-22 11:54:21.000000000 +0200
|
||||
+++ ltrace-0.7.91/options.c 2014-01-13 15:38:51.362221740 +0100
|
||||
@@ -128,6 +128,8 @@ usage_debug(void) {
|
||||
"\n"
|
||||
"Debugging options are mixed using bitwise-or.\n"
|
||||
"Note that the meanings and values are subject to change.\n"
|
||||
+ "Also note that these values are used inconsistently in ltrace, and the\n"
|
||||
+ "only debuglevel that you can rely on is -D77 that will show everything.\n"
|
||||
);
|
||||
}
|
||||
|
||||
diff -up ltrace-0.7.91/ltrace.1\~ ltrace-0.7.91/ltrace.1
|
||||
--- ltrace-0.7.91/ltrace.1~ 2013-10-23 17:44:13.000000000 +0200
|
||||
+++ ltrace-0.7.91/ltrace.1 2014-01-13 15:51:24.236730677 +0100
|
||||
@@ -1,5 +1,5 @@
|
||||
.\" -*-nroff-*-
|
||||
-.\" Copyright (c) 2012, 2013 Petr Machata, Red Hat Inc.
|
||||
+.\" Copyright (c) 2012,2013,2014 Petr Machata, Red Hat Inc.
|
||||
.\" Copyright (c) 1997-2005 Juan Cespedes <cespedes@debian.org>
|
||||
.\"
|
||||
.\" This program is free software; you can redistribute it and/or
|
||||
@@ -118,9 +118,9 @@ Besides removing any initial underscore
|
||||
this makes C++ function names readable.
|
||||
.IP "\-D, \-\-debug \fRmask\fI"
|
||||
Show debugging output of \fBltrace\fR itself. \fImask\fR is a number
|
||||
-with internal meaning that's not really well defined at all.
|
||||
-\fImask\fR of 77 shows all debug messages, which is what you usually
|
||||
-need.
|
||||
+describing which debug messages should be displayed. Use the option
|
||||
+\-Dh to see what can be used, but note that currently the only
|
||||
+reliable debugmask is 77, which shows all debug messages.
|
||||
.IP "\-e \fIfilter"
|
||||
A qualifying expression which modifies which library calls to trace.
|
||||
The format of the filter expression is described in the section
|
||||
@@ -156,7 +156,8 @@ dependency ordering. If you want to mak
|
||||
library are actually called, use \fB-x @\fIlibrary_pattern\fR instead.
|
||||
.IP \-L
|
||||
When no -e option is given, don't assume the default action of
|
||||
-\fB@MAIN\fR.
|
||||
+\fB@MAIN\fR. In practice this means that library calls will not be
|
||||
+traced.
|
||||
.IP "\-n, \-\-indent \fInr"
|
||||
Indent trace output by \fInr\fR spaces for each level of call
|
||||
nesting. Using this option makes the program flow visualization easy
|
||||
175
ltrace-0.7.91-multithread-no-f-1.patch
Normal file
175
ltrace-0.7.91-multithread-no-f-1.patch
Normal file
@ -0,0 +1,175 @@
|
||||
From 4724bd5a4a19db117a1d280b9d1a3508fd4e03fa Mon Sep 17 00:00:00 2001
|
||||
From: Petr Machata <pmachata@redhat.com>
|
||||
Date: Wed, 8 Apr 2015 07:11:52 -0400
|
||||
Subject: [PATCH 1/2] Convert main-threaded test case to new style
|
||||
|
||||
---
|
||||
testsuite/ltrace.main/Makefile.am | 4 +-
|
||||
testsuite/ltrace.main/main-threaded.c | 30 ----------
|
||||
testsuite/ltrace.main/main-threaded.exp | 103 ++++++++++++++++++++------------
|
||||
3 files changed, 66 insertions(+), 71 deletions(-)
|
||||
delete mode 100644 testsuite/ltrace.main/main-threaded.c
|
||||
|
||||
diff --git a/testsuite/ltrace.main/Makefile.am b/testsuite/ltrace.main/Makefile.am
|
||||
index 23ab8ab..06ad613 100644
|
||||
--- a/testsuite/ltrace.main/Makefile.am
|
||||
+++ b/testsuite/ltrace.main/Makefile.am
|
||||
@@ -1,4 +1,4 @@
|
||||
-# Copyright (C) 1992 - 2001, 2012, 2013 Free Software Foundation, Inc.
|
||||
+# Copyright (C) 1992 - 2001, 2012, 2013, 2015 Free Software Foundation, 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
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
EXTRA_DIST = branch_func.c branch_func.exp filters.exp hello-vfork.c \
|
||||
hello-vfork.exp main.c main.exp main-internal.exp main-lib.c \
|
||||
- main-threaded.c main-threaded.exp main-vfork.c main-vfork.exp \
|
||||
+ main-threaded.exp main-vfork.c main-vfork.exp \
|
||||
parameters.c parameters.conf parameters.exp parameters-lib.c \
|
||||
parameters2.exp parameters3.exp signals.c signals.exp \
|
||||
system_calls.c system_calls.exp system_call_params.exp
|
||||
diff --git a/testsuite/ltrace.main/main-threaded.c b/testsuite/ltrace.main/main-threaded.c
|
||||
deleted file mode 100644
|
||||
index 2992d1e..0000000
|
||||
--- a/testsuite/ltrace.main/main-threaded.c
|
||||
+++ /dev/null
|
||||
@@ -1,29 +0,0 @@
|
||||
-#include <pthread.h>
|
||||
-
|
||||
-extern void print (char *);
|
||||
-
|
||||
-#define PRINT_LOOP 10
|
||||
-
|
||||
-void *
|
||||
-th_main (void *arg)
|
||||
-{
|
||||
- int i;
|
||||
- for (i=0; i<PRINT_LOOP; i++)
|
||||
- print (arg);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-main ()
|
||||
-{
|
||||
- pthread_t thread1;
|
||||
- pthread_t thread2;
|
||||
- pthread_t thread3;
|
||||
- pthread_create (&thread1, NULL, th_main, "aaa");
|
||||
- pthread_create (&thread2, NULL, th_main, "bbb");
|
||||
- pthread_create (&thread3, NULL, th_main, "ccc");
|
||||
- pthread_join (thread1, NULL);
|
||||
- pthread_join (thread2, NULL);
|
||||
- pthread_join (thread3, NULL);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
diff --git a/testsuite/ltrace.main/main-threaded.exp b/testsuite/ltrace.main/main-threaded.exp
|
||||
index 4d5f478..cead82d 100644
|
||||
--- a/testsuite/ltrace.main/main-threaded.exp
|
||||
+++ b/testsuite/ltrace.main/main-threaded.exp
|
||||
@@ -1,39 +1,64 @@
|
||||
-# This file was written by Yao Qi <qiyao@cn.ibm.com>.
|
||||
+# This file is part of ltrace.
|
||||
+# Copyright (C) 2011, 2015 Petr Machata, Red Hat Inc.
|
||||
+# Copyright (C) 2006 Yao Qi <qiyao@cn.ibm.com>.
|
||||
+#
|
||||
+# 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
|
||||
+
|
||||
+set libprint [ltraceCompile libprint.so [ltraceSource c {
|
||||
+ #include<stdio.h>
|
||||
+
|
||||
+ void
|
||||
+ print(char* s)
|
||||
+ {
|
||||
+ printf("%s\n",s);
|
||||
+ }
|
||||
+}]]
|
||||
+
|
||||
+set bin [ltraceCompile {} $libprint -lpthread [ltraceSource c {
|
||||
+ #include <pthread.h>
|
||||
+
|
||||
+ extern void print (char *);
|
||||
+
|
||||
+ #define PRINT_LOOP 10
|
||||
+
|
||||
+ void *
|
||||
+ th_main (void *arg)
|
||||
+ {
|
||||
+ int i;
|
||||
+ for (i=0; i<PRINT_LOOP; i++)
|
||||
+ print (arg);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ int
|
||||
+ main (void)
|
||||
+ {
|
||||
+ pthread_t thread1;
|
||||
+ pthread_t thread2;
|
||||
+ pthread_t thread3;
|
||||
+ pthread_create (&thread1, NULL, th_main, "aaa");
|
||||
+ pthread_create (&thread2, NULL, th_main, "bbb");
|
||||
+ pthread_create (&thread3, NULL, th_main, "ccc");
|
||||
+ pthread_join (thread1, NULL);
|
||||
+ pthread_join (thread2, NULL);
|
||||
+ pthread_join (thread3, NULL);
|
||||
+ return 0;
|
||||
+ }
|
||||
+}]]
|
||||
|
||||
-set testfile "main-threaded"
|
||||
-set srcfile ${testfile}.c
|
||||
-set binfile ${testfile}
|
||||
-set libfile "main-lib"
|
||||
-set libsrc $srcdir/$subdir/$libfile.c
|
||||
-set lib_sl $objdir/$subdir/lib$testfile.so
|
||||
-
|
||||
-
|
||||
-if [get_compiler_info $binfile] {
|
||||
- return -1
|
||||
-}
|
||||
-
|
||||
-verbose "compiling source file now....."
|
||||
-if { [ltrace_compile_shlib $libsrc $lib_sl debug ] != ""
|
||||
- || [ltrace_compile $srcdir/$subdir/$srcfile $objdir/$subdir/$binfile executable [list debug shlib=$lib_sl ldflags=-pthread] ] != ""} {
|
||||
- send_user "Testcase compile failed, so all tests in this file will automatically fail.\n"
|
||||
-}
|
||||
-
|
||||
-# set options for ltrace.
|
||||
-ltrace_options "-l" "lib$testfile.so" "-f"
|
||||
-
|
||||
-# Run PUT for ltarce.
|
||||
-set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile]
|
||||
-
|
||||
-# Check the output of this program.
|
||||
-verbose "ltrace runtest output: $exec_output\n"
|
||||
-if [regexp {ELF from incompatible architecture} $exec_output] {
|
||||
- fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!"
|
||||
- return
|
||||
-} elseif [ regexp {Couldn't get .hash data} $exec_output ] {
|
||||
- fail "Couldn't get .hash data!"
|
||||
- return
|
||||
-}
|
||||
-
|
||||
-# Verify the output by checking numbers of print in main-threaded.ltrace.
|
||||
-set pattern "print"
|
||||
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 30
|
||||
+ltraceMatch1 [ltraceRun -f -l libprint.so -- $bin] {print\(} == 30
|
||||
+
|
||||
+ltraceDone
|
||||
Only in ltrace.main: main-threaded.exp~
|
||||
Only in ltrace.main: .main-threaded.exp.~undo-tree~
|
||||
50
ltrace-0.7.91-multithread-no-f-2.patch
Normal file
50
ltrace-0.7.91-multithread-no-f-2.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 72ee29639c55b5942bc07c8ed0013005f8fc5a97 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Machata <pmachata@redhat.com>
|
||||
Date: Wed, 8 Apr 2015 07:14:10 -0400
|
||||
Subject: [PATCH 2/2] Fix tracing multi-threaded processes without -f
|
||||
|
||||
- In handle_syscall, we avoid touching stack of ignored processes.
|
||||
But in handle_sysret, we require a sysret-like stack entry even
|
||||
for ignored processes, even though we then go ahead to not act
|
||||
on that stack entry. Instead, for ignored processes, avoid looking
|
||||
at stack trace at all.
|
||||
---
|
||||
handle_event.c | 10 +++++-----
|
||||
testsuite/ltrace.main/main-threaded.exp | 1 +
|
||||
2 files changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/handle_event.c b/handle_event.c
|
||||
index 6fa7e98..c2550ad 100644
|
||||
--- a/handle_event.c
|
||||
+++ b/handle_event.c
|
||||
@@ -619,12 +619,12 @@ handle_x_sysret(Event *event, char *(*name_cb)(struct process *, int))
|
||||
debug(DEBUG_FUNCTION, "handle_x_sysret(pid=%d, sysnum=%d)",
|
||||
event->proc->pid, event->e_un.sysnum);
|
||||
|
||||
- unsigned d = event->proc->callstack_depth;
|
||||
- assert(d > 0);
|
||||
- struct callstack_element *elem = &event->proc->callstack[d - 1];
|
||||
- assert(elem->is_syscall);
|
||||
-
|
||||
if (event->proc->state != STATE_IGNORED) {
|
||||
+ unsigned d = event->proc->callstack_depth;
|
||||
+ assert(d > 0);
|
||||
+ struct callstack_element *elem = &event->proc->callstack[d - 1];
|
||||
+ assert(elem->is_syscall);
|
||||
+
|
||||
struct timedelta spent = calc_time_spent(elem->enter_time);
|
||||
if (options.syscalls)
|
||||
output_syscall_right(event->proc,
|
||||
diff --git a/testsuite/ltrace.main/main-threaded.exp b/testsuite/ltrace.main/main-threaded.exp
|
||||
index cead82d..aca7afd 100644
|
||||
--- a/testsuite/ltrace.main/main-threaded.exp
|
||||
+++ b/testsuite/ltrace.main/main-threaded.exp
|
||||
@@ -60,5 +60,6 @@ set bin [ltraceCompile {} $libprint -lpthread [ltraceSource c {
|
||||
}]]
|
||||
|
||||
ltraceMatch1 [ltraceRun -f -l libprint.so -- $bin] {print\(} == 30
|
||||
+ltraceMatch1 [ltraceRun -L -- $bin] exited == 1
|
||||
|
||||
ltraceDone
|
||||
--
|
||||
2.1.0
|
||||
144
ltrace-0.7.91-parser-ws_after_id.patch
Normal file
144
ltrace-0.7.91-parser-ws_after_id.patch
Normal file
@ -0,0 +1,144 @@
|
||||
From 2e9f9f1f5d0fb223b109429b9c904504b7f638e2 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Machata <pmachata@redhat.com>
|
||||
Date: Fri, 8 Aug 2014 16:53:41 +0200
|
||||
Subject: [PATCH] In config files, allow whitespace between identifier and
|
||||
opening paren
|
||||
|
||||
---
|
||||
read_config_file.c | 61 ++++++--------------------------
|
||||
testsuite/ltrace.main/parameters2.exp | 14 +++++++-
|
||||
2 files changed, 25 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/read_config_file.c b/read_config_file.c
|
||||
index ea3ab88..05ff283 100644
|
||||
--- a/read_config_file.c
|
||||
+++ b/read_config_file.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ltrace.
|
||||
- * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
|
||||
+ * Copyright (C) 2011,2012,2013,2014 Petr Machata, Red Hat Inc.
|
||||
* Copyright (C) 1998,1999,2003,2007,2008,2009 Juan Cespedes
|
||||
* Copyright (C) 2006 Ian Wienand
|
||||
* Copyright (C) 2006 Steve Fink
|
||||
@@ -168,38 +168,6 @@ parse_ident(struct locus *loc, char **str)
|
||||
return xstrndup(ident, *str - ident);
|
||||
}
|
||||
|
||||
-/*
|
||||
- Returns position in string at the left parenthesis which starts the
|
||||
- function's argument signature. Returns NULL on error.
|
||||
-*/
|
||||
-static char *
|
||||
-start_of_arg_sig(char *str) {
|
||||
- char *pos;
|
||||
- int stacked = 0;
|
||||
-
|
||||
- if (!strlen(str))
|
||||
- return NULL;
|
||||
-
|
||||
- pos = &str[strlen(str)];
|
||||
- do {
|
||||
- pos--;
|
||||
- if (pos < str)
|
||||
- return NULL;
|
||||
- while ((pos > str) && (*pos != ')') && (*pos != '('))
|
||||
- pos--;
|
||||
-
|
||||
- if (*pos == ')')
|
||||
- stacked++;
|
||||
- else if (*pos == '(')
|
||||
- stacked--;
|
||||
- else
|
||||
- return NULL;
|
||||
-
|
||||
- } while (stacked > 0);
|
||||
-
|
||||
- return (stacked == 0) ? pos : NULL;
|
||||
-}
|
||||
-
|
||||
static int
|
||||
parse_int(struct locus *loc, char **str, long *ret)
|
||||
{
|
||||
@@ -1110,7 +1078,6 @@ static int
|
||||
process_line(struct protolib *plib, struct locus *loc, char *buf)
|
||||
{
|
||||
char *str = buf;
|
||||
- char *tmp;
|
||||
|
||||
debug(3, "Reading line %d of `%s'", loc->line_no, loc->filename);
|
||||
eat_spaces(&str);
|
||||
@@ -1148,22 +1115,13 @@ process_line(struct protolib *plib, struct locus *loc, char *buf)
|
||||
debug(4, " return_type = %d", fun.return_info->type);
|
||||
|
||||
eat_spaces(&str);
|
||||
- tmp = start_of_arg_sig(str);
|
||||
- if (tmp == NULL) {
|
||||
- report_error(loc->filename, loc->line_no, "syntax error");
|
||||
+ proto_name = parse_ident(loc, &str);
|
||||
+ if (proto_name == NULL)
|
||||
goto err;
|
||||
- }
|
||||
- *tmp = '\0';
|
||||
|
||||
- proto_name = strdup(str);
|
||||
- if (proto_name == NULL) {
|
||||
- oom:
|
||||
- report_error(loc->filename, loc->line_no,
|
||||
- "%s", strerror(errno));
|
||||
+ eat_spaces(&str);
|
||||
+ if (parse_char(loc, &str, '(') < 0)
|
||||
goto err;
|
||||
- }
|
||||
-
|
||||
- str = tmp + 1;
|
||||
debug(3, " name = %s", proto_name);
|
||||
|
||||
struct param *extra_param = NULL;
|
||||
@@ -1177,8 +1135,13 @@ process_line(struct protolib *plib, struct locus *loc, char *buf)
|
||||
if (have_stop == 0) {
|
||||
struct param param;
|
||||
param_init_stop(¶m);
|
||||
- if (prototype_push_param(&fun, ¶m) < 0)
|
||||
- goto oom;
|
||||
+ if (prototype_push_param(&fun, ¶m) < 0) {
|
||||
+ oom:
|
||||
+ report_error(loc->filename,
|
||||
+ loc->line_no,
|
||||
+ "%s", strerror(errno));
|
||||
+ goto err;
|
||||
+ }
|
||||
have_stop = 1;
|
||||
}
|
||||
str++;
|
||||
diff --git a/testsuite/ltrace.main/parameters2.exp b/testsuite/ltrace.main/parameters2.exp
|
||||
index 6318fc5..9850079 100644
|
||||
--- a/testsuite/ltrace.main/parameters2.exp
|
||||
+++ b/testsuite/ltrace.main/parameters2.exp
|
||||
@@ -1,5 +1,5 @@
|
||||
# This file is part of ltrace.
|
||||
-# Copyright (C) 2012, 2013 Petr Machata, Red Hat Inc.
|
||||
+# Copyright (C) 2012, 2013, 2014 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
|
||||
@@ -259,4 +259,16 @@ ltraceMatch1 [ltraceLibTest {
|
||||
somefunc();
|
||||
}] {somefunc\(\) *= nil} == 1
|
||||
|
||||
+# Test that spaces in function name make no difference.
|
||||
+
|
||||
+ltraceMatch1 [ltraceLibTest {
|
||||
+ void somefunc ();
|
||||
+} {
|
||||
+ void somefunc(void);
|
||||
+} {
|
||||
+ void somefunc(void) {}
|
||||
+} {
|
||||
+ somefunc();
|
||||
+}] {somefunc\(\)} == 1
|
||||
+
|
||||
ltraceDone
|
||||
--
|
||||
1.7.6.5
|
||||
|
||||
96
ltrace-0.7.91-tautology.patch
Normal file
96
ltrace-0.7.91-tautology.patch
Normal file
@ -0,0 +1,96 @@
|
||||
diff -r -U3 -p ltrace-0.7.91.orig/filter.c ltrace-0.7.91.dj/filter.c
|
||||
--- ltrace-0.7.91.orig/filter.c 2012-12-16 20:53:44.000000000 -0500
|
||||
+++ ltrace-0.7.91.dj/filter.c 2016-06-17 19:07:23.678490985 -0400
|
||||
@@ -79,7 +79,7 @@ filter_lib_matcher_name_init(struct filt
|
||||
{
|
||||
switch (type) {
|
||||
case FLM_MAIN:
|
||||
- assert(type != type);
|
||||
+ //assert(type != type);
|
||||
abort();
|
||||
|
||||
case FLM_SONAME:
|
||||
@@ -137,7 +137,7 @@ matcher_matches_library(struct filter_li
|
||||
case FLM_MAIN:
|
||||
return lib->type == LT_LIBTYPE_MAIN;
|
||||
}
|
||||
- assert(matcher->type != matcher->type);
|
||||
+ //assert(matcher->type != matcher->type);
|
||||
abort();
|
||||
}
|
||||
|
||||
Only in ltrace-0.7.91.dj/: filter.c~
|
||||
diff -r -U3 -p ltrace-0.7.91.orig/sysdeps/linux-gnu/proc.c ltrace-0.7.91.dj/sysdeps/linux-gnu/proc.c
|
||||
--- ltrace-0.7.91.orig/sysdeps/linux-gnu/proc.c 2013-10-11 15:27:11.000000000 -0400
|
||||
+++ ltrace-0.7.91.dj/sysdeps/linux-gnu/proc.c 2016-06-17 18:59:42.333774042 -0400
|
||||
@@ -242,9 +242,10 @@ process_tasks(pid_t pid, pid_t **ret_tas
|
||||
size_t alloc = 0;
|
||||
|
||||
while (1) {
|
||||
- struct dirent entry;
|
||||
struct dirent *result;
|
||||
- if (readdir_r(d, &entry, &result) != 0) {
|
||||
+ errno = 0;
|
||||
+ result = readdir(d);
|
||||
+ if (result == NULL && errno != 0) {
|
||||
fail:
|
||||
free(tasks);
|
||||
closedir(d);
|
||||
Only in ltrace-0.7.91.dj/sysdeps/linux-gnu: proc.c~
|
||||
diff -r -U3 -p ltrace-0.7.91.orig/sysdeps/linux-gnu/x86/fetch.c ltrace-0.7.91.dj/sysdeps/linux-gnu/x86/fetch.c
|
||||
--- ltrace-0.7.91.orig/sysdeps/linux-gnu/x86/fetch.c 2013-10-24 08:33:35.000000000 -0400
|
||||
+++ ltrace-0.7.91.dj/sysdeps/linux-gnu/x86/fetch.c 2016-06-17 18:52:33.962842191 -0400
|
||||
@@ -523,7 +523,7 @@ classify(struct process *proc, struct fe
|
||||
|
||||
default:
|
||||
/* Unsupported type. */
|
||||
- assert(info->type != info->type);
|
||||
+ //assert(info->type != info->type);
|
||||
abort();
|
||||
}
|
||||
abort();
|
||||
Only in ltrace-0.7.91.dj/sysdeps/linux-gnu/x86: fetch.c~
|
||||
diff -r -U3 -p ltrace-0.7.91.orig/sysdeps/linux-gnu/x86/trace.c ltrace-0.7.91.dj/sysdeps/linux-gnu/x86/trace.c
|
||||
--- ltrace-0.7.91.orig/sysdeps/linux-gnu/x86/trace.c 2012-12-16 20:53:45.000000000 -0500
|
||||
+++ ltrace-0.7.91.dj/sysdeps/linux-gnu/x86/trace.c 2016-06-17 18:52:16.699844065 -0400
|
||||
@@ -145,7 +145,7 @@ arch_type_sizeof(struct process *proc, s
|
||||
return (size_t)-2;
|
||||
|
||||
default:
|
||||
- assert(info->type != info->type);
|
||||
+ //assert(info->type != info->type);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@@ -158,7 +158,7 @@ arch_type_alignof(struct process *proc,
|
||||
|
||||
switch (info->type) {
|
||||
default:
|
||||
- assert(info->type != info->type);
|
||||
+ //assert(info->type != info->type);
|
||||
abort();
|
||||
break;
|
||||
|
||||
Only in ltrace-0.7.91.dj/sysdeps/linux-gnu/x86: trace.c~
|
||||
diff -r -U3 -p ltrace-0.7.91.orig/value.c ltrace-0.7.91.dj/value.c
|
||||
--- ltrace-0.7.91.orig/value.c 2013-10-10 08:43:55.000000000 -0400
|
||||
+++ ltrace-0.7.91.dj/value.c 2016-06-17 19:11:43.441047589 -0400
|
||||
@@ -363,7 +363,7 @@ value_set_word(struct value *value, long
|
||||
u.u64 = word;
|
||||
break;
|
||||
default:
|
||||
- assert(sz != sz);
|
||||
+ //assert(sz != sz);
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -414,7 +414,7 @@ value_extract_word(struct value *value,
|
||||
*retp = (long)u.u64;
|
||||
return 0;
|
||||
default:
|
||||
- assert(sz != sz);
|
||||
+ //assert(sz != sz);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
Only in ltrace-0.7.91.dj/: value.c~
|
||||
48
ltrace-0.7.91-testsuite-includes-2.patch
Normal file
48
ltrace-0.7.91-testsuite-includes-2.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 57dbe34ea7aa54b97e11406e1cfb2e427a68779e Mon Sep 17 00:00:00 2001
|
||||
From: Petr Machata <pmachata@redhat.com>
|
||||
Date: Wed, 8 Apr 2015 16:04:13 +0200
|
||||
Subject: [PATCH] Fix warnings in compilation of test-suite cases
|
||||
|
||||
---
|
||||
testsuite/ltrace.main/signals.c | 5 +++--
|
||||
testsuite/ltrace.minor/wchar.exp | 3 ++-
|
||||
testsuite/ltrace.torture/signals.c | 5 +++--
|
||||
3 files changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/testsuite/ltrace.main/signals.c b/testsuite/ltrace.main/signals.c
|
||||
index a02e795..ab23fc7 100644
|
||||
--- a/testsuite/ltrace.main/signals.c
|
||||
+++ b/testsuite/ltrace.main/signals.c
|
||||
@@ -2,9 +2,10 @@
|
||||
Objectives : Verify that ltrace can trace user defined signal.
|
||||
This file was written by Yao Qi <qiyao@cn.ibm.com>. */
|
||||
|
||||
-#include<stdio.h>
|
||||
-#include<signal.h>
|
||||
+#include <stdio.h>
|
||||
+#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
#define LOOP 7
|
||||
|
||||
diff --git a/testsuite/ltrace.torture/signals.c b/testsuite/ltrace.torture/signals.c
|
||||
index b786c81..c66416e 100644
|
||||
--- a/testsuite/ltrace.torture/signals.c
|
||||
+++ b/testsuite/ltrace.torture/signals.c
|
||||
@@ -2,9 +2,10 @@
|
||||
Objectives : Verify that ltrace can trace user defined signal.
|
||||
This file was written by Yao Qi <qiyao@cn.ibm.com>. */
|
||||
|
||||
-#include<stdio.h>
|
||||
-#include<signal.h>
|
||||
+#include <stdio.h>
|
||||
+#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
#define LOOP 20
|
||||
|
||||
--
|
||||
2.3.5
|
||||
|
||||
216
ltrace-0.7.91-testsuite-includes.patch
Normal file
216
ltrace-0.7.91-testsuite-includes.patch
Normal file
@ -0,0 +1,216 @@
|
||||
From 694d19ff14017926454771cbb63a22355b72f1bf Mon Sep 17 00:00:00 2001
|
||||
From: Faraz Shahbazker <faraz.shahbazker@imgtec.com>
|
||||
Date: Tue, 3 Feb 2015 13:07:55 -0800
|
||||
Subject: [PATCH] Fix missing includes and return statements in test sources
|
||||
|
||||
Fix warnings while compiling test cases by adding missing #includes and
|
||||
return statements. Missing arguments provided for functions wait()/wcswidth()
|
||||
---
|
||||
testsuite/ltrace.main/filters.exp | 1 +
|
||||
testsuite/ltrace.main/main-internal.exp | 4 +++-
|
||||
testsuite/ltrace.main/main-threaded.c | 1 +
|
||||
testsuite/ltrace.main/parameters.c | 1 +
|
||||
testsuite/ltrace.main/parameters2.exp | 2 +-
|
||||
testsuite/ltrace.main/parameters3.exp | 2 ++
|
||||
testsuite/ltrace.main/system_call_params.exp | 4 ++++
|
||||
testsuite/ltrace.minor/attach-process.exp | 1 +
|
||||
testsuite/ltrace.minor/libdl-simple.c | 2 ++
|
||||
testsuite/ltrace.minor/time-record.c | 1 +
|
||||
testsuite/ltrace.minor/trace-clone.c | 2 ++
|
||||
testsuite/ltrace.minor/trace-fork.c | 4 +++-
|
||||
testsuite/ltrace.minor/wchar.exp | 3 ++-
|
||||
testsuite/ltrace.torture/vfork-thread.c | 1 +
|
||||
14 files changed, 25 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/testsuite/ltrace.main/filters.exp b/testsuite/ltrace.main/filters.exp
|
||||
index 988346f..f7f4140 100644
|
||||
--- a/testsuite/ltrace.main/filters.exp
|
||||
+++ b/testsuite/ltrace.main/filters.exp
|
||||
@@ -22,6 +22,7 @@ set libfilt1 [ltraceCompile libfilt1.so [ltraceSource c {
|
||||
}]]
|
||||
|
||||
set libfilt2 [ltraceCompile libfilt2.so [ltraceSource c {
|
||||
+ #include <stdio.h>
|
||||
void func2(void) { puts("func2"); }
|
||||
}]]
|
||||
|
||||
diff --git a/testsuite/ltrace.main/main-internal.exp b/testsuite/ltrace.main/main-internal.exp
|
||||
index 0ca5e14..112c69b 100644
|
||||
--- a/testsuite/ltrace.main/main-internal.exp
|
||||
+++ b/testsuite/ltrace.main/main-internal.exp
|
||||
@@ -19,11 +19,13 @@
|
||||
set bin [ltraceCompile {} [ltraceSource c {
|
||||
__attribute__((noinline)) void this(void) {}
|
||||
__attribute__((noinline)) void that(void) {}
|
||||
- int main(int i) {
|
||||
+ int main() {
|
||||
+ int i;
|
||||
for (i = 0; i < 12; ++i) {
|
||||
this();
|
||||
that();
|
||||
}
|
||||
+ return 0;
|
||||
}
|
||||
}]]
|
||||
|
||||
diff --git a/testsuite/ltrace.main/parameters.c b/testsuite/ltrace.main/parameters.c
|
||||
index a3d8bb5..aa862b9 100644
|
||||
--- a/testsuite/ltrace.main/parameters.c
|
||||
+++ b/testsuite/ltrace.main/parameters.c
|
||||
@@ -17,6 +17,7 @@ void func_intptr_ret(int *i);
|
||||
int func_strlen(char*);
|
||||
void func_strfixed(char*);
|
||||
void func_ppp(int***);
|
||||
+void func_string(char*);
|
||||
void func_stringp(char**);
|
||||
void func_short(short, short);
|
||||
void func_ushort(unsigned short, unsigned short);
|
||||
diff --git a/testsuite/ltrace.main/parameters2.exp b/testsuite/ltrace.main/parameters2.exp
|
||||
index 9850079..1c7b3b4 100644
|
||||
--- a/testsuite/ltrace.main/parameters2.exp
|
||||
+++ b/testsuite/ltrace.main/parameters2.exp
|
||||
@@ -17,7 +17,7 @@
|
||||
# 02110-1301 USA
|
||||
|
||||
set trivial [ltraceCompile {} [ltraceSource c {
|
||||
- int main(void) {}
|
||||
+ int main(void) {return 0;}
|
||||
}]]
|
||||
|
||||
ltraceMatch1 [ltraceRun -L -F [ltraceSource conf {
|
||||
diff --git a/testsuite/ltrace.main/parameters3.exp b/testsuite/ltrace.main/parameters3.exp
|
||||
index 693c219..f6d9116 100644
|
||||
--- a/testsuite/ltrace.main/parameters3.exp
|
||||
+++ b/testsuite/ltrace.main/parameters3.exp
|
||||
@@ -29,8 +29,10 @@ set liba [ltraceCompile liba.so [ltraceSource c {
|
||||
}]]
|
||||
|
||||
set bin [ltraceCompile {} $liba [ltraceSource c {
|
||||
+ extern void fun(void);
|
||||
int main(void) {
|
||||
fun();
|
||||
+ return 0;
|
||||
}
|
||||
}]]
|
||||
|
||||
diff --git a/testsuite/ltrace.main/system_call_params.exp b/testsuite/ltrace.main/system_call_params.exp
|
||||
index 2ccf840..f3a55d2 100644
|
||||
--- a/testsuite/ltrace.main/system_call_params.exp
|
||||
+++ b/testsuite/ltrace.main/system_call_params.exp
|
||||
@@ -17,12 +17,15 @@
|
||||
# 02110-1301 USA
|
||||
|
||||
set bin [ltraceCompile {} [ltraceSource c {
|
||||
+ #ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
+ #endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h> /* For SYS_xxx definitions */
|
||||
+ #include <sys/mount.h>
|
||||
|
||||
#ifndef SYS_open
|
||||
# if defined(__aarch64__)
|
||||
@@ -38,6 +41,7 @@ set bin [ltraceCompile {} [ltraceSource c {
|
||||
syscall(SYS_open, "/some/path", O_RDONLY);
|
||||
write(1, "something", 10);
|
||||
mount("source", "target", "filesystemtype", 0, 0);
|
||||
+ return 0;
|
||||
}
|
||||
}]]
|
||||
|
||||
diff --git a/testsuite/ltrace.minor/attach-process.exp b/testsuite/ltrace.minor/attach-process.exp
|
||||
index 2c7d20c..c050f21 100644
|
||||
--- a/testsuite/ltrace.minor/attach-process.exp
|
||||
+++ b/testsuite/ltrace.minor/attach-process.exp
|
||||
@@ -21,6 +21,7 @@ set bin [ltraceCompile {} [ltraceSource c {
|
||||
int main(void) {
|
||||
sleep(5);
|
||||
sleep(1);
|
||||
+ return 0;
|
||||
}
|
||||
}]]
|
||||
|
||||
diff --git a/testsuite/ltrace.minor/libdl-simple.c b/testsuite/ltrace.minor/libdl-simple.c
|
||||
index 0bef5cf..b1be002 100644
|
||||
--- a/testsuite/ltrace.minor/libdl-simple.c
|
||||
+++ b/testsuite/ltrace.minor/libdl-simple.c
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
+#include <string.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
void *handle;
|
||||
@@ -21,4 +22,5 @@ int main(int argc, char **argv) {
|
||||
|
||||
printf("%d\n", test(5));
|
||||
dlclose(handle);
|
||||
+ return 0;
|
||||
}
|
||||
diff --git a/testsuite/ltrace.minor/time-record.c b/testsuite/ltrace.minor/time-record.c
|
||||
index a66b838..7d5e5e3 100644
|
||||
--- a/testsuite/ltrace.minor/time-record.c
|
||||
+++ b/testsuite/ltrace.minor/time-record.c
|
||||
@@ -5,6 +5,7 @@
|
||||
This file was written by Yao Qi <qiyao@cn.ibm.com>. */
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
#define SLEEP_COUNT 2
|
||||
#define NANOSLEEP_COUNT 50
|
||||
diff --git a/testsuite/ltrace.minor/trace-clone.c b/testsuite/ltrace.minor/trace-clone.c
|
||||
index ded930c..6aab235 100644
|
||||
--- a/testsuite/ltrace.minor/trace-clone.c
|
||||
+++ b/testsuite/ltrace.minor/trace-clone.c
|
||||
@@ -3,7 +3,9 @@
|
||||
clone called.
|
||||
|
||||
This file was written by Yao Qi <qiyao@cn.ibm.com>. */
|
||||
+#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
+#endif
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
diff --git a/testsuite/ltrace.minor/trace-fork.c b/testsuite/ltrace.minor/trace-fork.c
|
||||
index c5f0c71..9611184 100644
|
||||
--- a/testsuite/ltrace.minor/trace-fork.c
|
||||
+++ b/testsuite/ltrace.minor/trace-fork.c
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/wait.h>
|
||||
|
||||
void
|
||||
child ()
|
||||
@@ -27,7 +29,7 @@ main ()
|
||||
else
|
||||
{
|
||||
printf("My child pid is %d\n",pid);
|
||||
- wait();
|
||||
+ wait(NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
diff --git a/testsuite/ltrace.torture/vfork-thread.c b/testsuite/ltrace.torture/vfork-thread.c
|
||||
index f909bd3..4c118a6 100644
|
||||
--- a/testsuite/ltrace.torture/vfork-thread.c
|
||||
+++ b/testsuite/ltrace.torture/vfork-thread.c
|
||||
@@ -13,6 +13,7 @@ routine (void *data)
|
||||
puts ("bleble");
|
||||
sleep (1);
|
||||
}
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
2.1.0
|
||||
|
||||
422
ltrace-0.7.91-unwind-elfutils.patch
Normal file
422
ltrace-0.7.91-unwind-elfutils.patch
Normal file
@ -0,0 +1,422 @@
|
||||
Common subdirectories: ltrace-0.7.91/config and ltrace-0.7.91-pm/config
|
||||
diff -u ltrace-0.7.91/configure.ac ltrace-0.7.91-pm/configure.ac
|
||||
--- ltrace-0.7.91/configure.ac 2015-01-09 00:38:17.977190726 +0100
|
||||
+++ ltrace-0.7.91-pm/configure.ac 2015-01-09 00:37:40.261910548 +0100
|
||||
@@ -128,6 +128,51 @@
|
||||
AC_CHECK_HEADERS(selinux/selinux.h)
|
||||
AC_CHECK_LIB(selinux, security_get_boolean_active)
|
||||
|
||||
+dnl Whether (and which) elfutils libdw.so to use for unwinding.
|
||||
+AC_ARG_WITH(elfutils,
|
||||
+ AS_HELP_STRING([--with-elfutils], [Use elfutils libdwfl unwinding support]),
|
||||
+ [case "${withval}" in
|
||||
+ (yes|no) enable_elfutils=$withval;;
|
||||
+ (*) enable_elfutils=yes
|
||||
+ AM_CPPFLAGS="${AM_CPPFLAGS} -I${withval}/include"
|
||||
+ AM_LDFLAGS="${AM_LDFLAGS} -L${withval}/lib"
|
||||
+ elfutils_LD_LIBRARY_PATH="${withval}/lib:${withval}/lib/elfutils"
|
||||
+ ;;
|
||||
+esac],[enable_elfutils=maybe])
|
||||
+
|
||||
+dnl Check whether we have the elfutils libdwfl.h header installed.
|
||||
+saved_CPPFLAGS="${CPPFLAGS}"
|
||||
+CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}"
|
||||
+AC_CHECK_HEADERS([elfutils/libdwfl.h],[have_libdwfl_h=yes])
|
||||
+CPPFLAGS="${saved_CPPFLAGS}"
|
||||
+
|
||||
+dnl And whether libdw.so provides the unwinding functions.
|
||||
+saved_LDFLAGS="${LDFLAGS}"
|
||||
+LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}"
|
||||
+AC_CHECK_LIB([dw], [dwfl_getthread_frames], [have_libdw_dwfl_frames=yes])
|
||||
+LDFLAGS="${saved_LDFLAGS}"
|
||||
+
|
||||
+AC_MSG_CHECKING([whether to use elfutils libdwfl unwinding support])
|
||||
+case "${enable_elfutils}" in
|
||||
+(yes|maybe)
|
||||
+ if test x$have_libdwfl_h = xyes -a x$have_libdw_dwfl_frames = xyes; then
|
||||
+ enable_elfutils=yes
|
||||
+ elif test $enable_elfutils = maybe; then
|
||||
+ enable_elfutils=no
|
||||
+ else
|
||||
+ AC_MSG_RESULT([$enable_elfutils])
|
||||
+ AC_MSG_ERROR([Missing elfutils/libdwfl.h or dwfl_getthread_frames not in libdw.so])
|
||||
+ fi
|
||||
+ ;;
|
||||
+(*) ;;
|
||||
+esac
|
||||
+AC_MSG_RESULT([$enable_elfutils])
|
||||
+
|
||||
+if test x"$enable_elfutils" = xyes; then
|
||||
+ libdw_LIBS=-ldw
|
||||
+ AC_SUBST(libdw_LIBS)
|
||||
+ AC_DEFINE([HAVE_LIBDW], [1], [we have elfutils libdw])
|
||||
+fi
|
||||
|
||||
# HAVE_LIBUNWIND
|
||||
AC_ARG_WITH(libunwind,
|
||||
@@ -193,6 +238,13 @@
|
||||
LDFLAGS="${saved_LDFLAGS}"
|
||||
fi
|
||||
|
||||
+if test x"$enable_elfutils" = xyes -a x"$enable_libunwind" = xyes; then
|
||||
+ AC_MSG_ERROR([Cannot enable both --with-libunwind and --with-elfutils])
|
||||
+fi
|
||||
+
|
||||
+if test x"$enable_elfutils" = xyes -o x"$enable_libunwind" = xyes; then
|
||||
+ AC_DEFINE([HAVE_UNWINDER], [1], [we have an unwinder available])
|
||||
+fi
|
||||
|
||||
saved_CPPFLAGS="${CPPFLAGS}"
|
||||
saved_LDFLAGS="${LDFLAGS}"
|
||||
@@ -340,6 +392,7 @@
|
||||
AC_SUBST(AM_CFLAGS)
|
||||
AC_SUBST(AM_LDFLAGS)
|
||||
AC_SUBST(libelf_LD_LIBRARY_PATH)
|
||||
+AC_SUBST(elfutils_LD_LIBRARY_PATH)
|
||||
AC_SUBST(libunwind_LD_LIBRARY_PATH)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Common subdirectories: ltrace-0.7.91/debian and ltrace-0.7.91-pm/debian
|
||||
Common subdirectories: ltrace-0.7.91/etc and ltrace-0.7.91-pm/etc
|
||||
diff -u ltrace-0.7.91/ltrace.1 ltrace-0.7.91-pm/ltrace.1
|
||||
--- ltrace-0.7.91/ltrace.1 2015-01-09 00:38:17.975190764 +0100
|
||||
+++ ltrace-0.7.91-pm/ltrace.1 2015-01-09 00:37:40.261910548 +0100
|
||||
@@ -196,7 +196,8 @@
|
||||
correct execution of setuid and/or setgid binaries.
|
||||
.IP "\-w, --where \fInr"
|
||||
Show backtrace of \fInr\fR stack frames for each traced function. This
|
||||
-option enabled only if libunwind support was enabled at compile time.
|
||||
+option enabled only if elfutils or libunwind support was enabled at compile
|
||||
+time.
|
||||
.IP "\-x \fIfilter"
|
||||
A qualifying expression which modifies which symbol table entry points
|
||||
to trace. The format of the filter expression is described in the
|
||||
Only in ltrace-0.7.91-pm/: ltrace.1.orig
|
||||
diff -u ltrace-0.7.91/Makefile.am ltrace-0.7.91-pm/Makefile.am
|
||||
--- ltrace-0.7.91/Makefile.am 2015-01-09 00:38:17.965190955 +0100
|
||||
+++ ltrace-0.7.91-pm/Makefile.am 2015-01-09 00:37:40.260910568 +0100
|
||||
@@ -40,6 +40,7 @@
|
||||
$(liberty_LIBS) \
|
||||
$(libsupcxx_LIBS) \
|
||||
$(libstdcxx_LIBS) \
|
||||
+ $(libdw_LIBS) \
|
||||
$(libunwind_LIBS) \
|
||||
sysdeps/libos.la
|
||||
|
||||
diff -u ltrace-0.7.91/options.c ltrace-0.7.91-pm/options.c
|
||||
--- ltrace-0.7.91/options.c 2015-01-09 00:38:17.974190783 +0100
|
||||
+++ ltrace-0.7.91-pm/options.c 2015-01-09 00:37:40.261910548 +0100
|
||||
@@ -107,9 +107,9 @@
|
||||
" -T show the time spent inside each call.\n"
|
||||
" -u USERNAME run command with the userid, groupid of username.\n"
|
||||
" -V, --version output version information and exit.\n"
|
||||
-#if defined(HAVE_LIBUNWIND)
|
||||
+#if defined(HAVE_UNWINDER)
|
||||
" -w, --where=NR print backtrace showing NR stack frames at most.\n"
|
||||
-#endif /* defined(HAVE_LIBUNWIND) */
|
||||
+#endif /* defined(HAVE_UNWINDER) */
|
||||
" -x FILTER modify which static functions to trace.\n"
|
||||
"\nReport bugs to ltrace-devel@lists.alioth.debian.org\n",
|
||||
progname);
|
||||
@@ -519,9 +519,9 @@
|
||||
progname = argv[0];
|
||||
options.output = stderr;
|
||||
options.no_signals = 0;
|
||||
-#if defined(HAVE_LIBUNWIND)
|
||||
+#if defined(HAVE_UNWINDER)
|
||||
options.bt_depth = -1;
|
||||
-#endif /* defined(HAVE_LIBUNWIND) */
|
||||
+#endif /* defined(HAVE_UNWINDER) */
|
||||
|
||||
guess_cols();
|
||||
|
||||
@@ -545,9 +545,9 @@
|
||||
{"output", 1, 0, 'o'},
|
||||
{"version", 0, 0, 'V'},
|
||||
{"no-signals", 0, 0, 'b'},
|
||||
-# if defined(HAVE_LIBUNWIND)
|
||||
+# if defined(HAVE_UNWINDER)
|
||||
{"where", 1, 0, 'w'},
|
||||
-# endif /* defined(HAVE_LIBUNWIND) */
|
||||
+# endif /* defined(HAVE_UNWINDER) */
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
@@ -556,7 +556,7 @@
|
||||
#ifdef USE_DEMANGLE
|
||||
"C"
|
||||
#endif
|
||||
-#if defined(HAVE_LIBUNWIND)
|
||||
+#if defined(HAVE_UNWINDER)
|
||||
"w:"
|
||||
#endif
|
||||
"cfhiLrStTVba:A:D:e:F:l:n:o:p:s:u:x:X:";
|
||||
@@ -681,11 +681,11 @@
|
||||
"There is NO WARRANTY, to the extent permitted by law.\n");
|
||||
exit(0);
|
||||
break;
|
||||
-#if defined(HAVE_LIBUNWIND)
|
||||
+#if defined(HAVE_UNWINDER)
|
||||
case 'w':
|
||||
options.bt_depth = parse_int(optarg, 'w', 1, 0);
|
||||
break;
|
||||
-#endif /* defined(HAVE_LIBUNWIND) */
|
||||
+#endif /* defined(HAVE_UNWINDER) */
|
||||
|
||||
case 'x':
|
||||
parse_filter_chain(optarg, &options.static_filter);
|
||||
Only in ltrace-0.7.91-pm/: options.c.orig
|
||||
diff -u ltrace-0.7.91/options.h ltrace-0.7.91-pm/options.h
|
||||
--- ltrace-0.7.91/options.h 2015-01-09 00:38:17.966190936 +0100
|
||||
+++ ltrace-0.7.91-pm/options.h 2015-01-09 00:37:40.261910548 +0100
|
||||
@@ -44,9 +44,9 @@
|
||||
size_t strlen; /* default maximum # of bytes printed in strings */
|
||||
int follow; /* trace child processes */
|
||||
int no_signals; /* don't print signals */
|
||||
-#if defined(HAVE_LIBUNWIND)
|
||||
+#if defined(HAVE_UNWINDER)
|
||||
int bt_depth; /* how may levels of stack frames to show */
|
||||
-#endif /* defined(HAVE_LIBUNWIND) */
|
||||
+#endif /* defined(HAVE_UNWINDER) */
|
||||
struct filter *plt_filter;
|
||||
struct filter *static_filter;
|
||||
|
||||
diff -u ltrace-0.7.91/output.c ltrace-0.7.91-pm/output.c
|
||||
--- ltrace-0.7.91/output.c 2015-01-09 00:38:17.966190936 +0100
|
||||
+++ ltrace-0.7.91-pm/output.c 2015-01-09 00:37:40.261910548 +0100
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
+#include <inttypes.h>
|
||||
|
||||
#include "output.h"
|
||||
#include "demangle.h"
|
||||
@@ -567,6 +568,73 @@
|
||||
stel->out.need_delim = need_delim;
|
||||
}
|
||||
|
||||
+#if defined(HAVE_LIBDW)
|
||||
+/* Prints information about one frame of a thread. Called by
|
||||
+ dwfl_getthread_frames in output_right. Returns 1 when done (max
|
||||
+ number of frames reached). Returns -1 on error. Returns 0 on
|
||||
+ success (if there are more frames in the thread, call us again). */
|
||||
+static int
|
||||
+frame_callback (Dwfl_Frame *state, void *arg)
|
||||
+{
|
||||
+ Dwarf_Addr pc;
|
||||
+ bool isactivation;
|
||||
+
|
||||
+ int *frames = (int *) arg;
|
||||
+
|
||||
+ if (!dwfl_frame_pc(state, &pc, &isactivation))
|
||||
+ return -1;
|
||||
+
|
||||
+ if (!isactivation)
|
||||
+ pc--;
|
||||
+
|
||||
+ Dwfl *dwfl = dwfl_thread_dwfl(dwfl_frame_thread(state));
|
||||
+ Dwfl_Module *mod = dwfl_addrmodule(dwfl, pc);
|
||||
+ const char *modname = NULL;
|
||||
+ const char *symname = NULL;
|
||||
+ GElf_Off off = 0;
|
||||
+ if (mod != NULL) {
|
||||
+ GElf_Sym sym;
|
||||
+ modname = dwfl_module_info(mod, NULL, NULL, NULL, NULL,
|
||||
+ NULL, NULL, NULL);
|
||||
+ symname = dwfl_module_addrinfo(mod, pc, &off, &sym,
|
||||
+ NULL, NULL, NULL);
|
||||
+ }
|
||||
+
|
||||
+ /* This mimics the output produced by libunwind below. */
|
||||
+ fprintf(options.output, " > %s(%s+0x%" PRIx64 ") [%" PRIx64 "]\n",
|
||||
+ modname, symname, off, pc);
|
||||
+
|
||||
+ /* See if we can extract the source line too and print it on
|
||||
+ the next line if we can find it. */
|
||||
+ if (mod != NULL) {
|
||||
+ Dwfl_Line *l = dwfl_module_getsrc(mod, pc);
|
||||
+ if (l != NULL) {
|
||||
+ int line, col;
|
||||
+ line = col = -1;
|
||||
+ const char *src = dwfl_lineinfo(l, NULL, &line, &col,
|
||||
+ NULL, NULL);
|
||||
+ if (src != NULL) {
|
||||
+ fprintf(options.output, "\t%s", src);
|
||||
+ if (line > 0) {
|
||||
+ fprintf(options.output, ":%d", line);
|
||||
+ if (col > 0)
|
||||
+ fprintf(options.output,
|
||||
+ ":%d", col);
|
||||
+ }
|
||||
+ fprintf(options.output, "\n");
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Max number of frames to print reached? */
|
||||
+ if ((*frames)-- == 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* defined(HAVE_LIBDW) */
|
||||
+
|
||||
void
|
||||
output_right(enum tof type, struct process *proc, struct library_symbol *libsym,
|
||||
struct timedelta *spent)
|
||||
@@ -694,6 +762,24 @@
|
||||
}
|
||||
#endif /* defined(HAVE_LIBUNWIND) */
|
||||
|
||||
+#if defined(HAVE_LIBDW)
|
||||
+ if (options.bt_depth > 0 && proc->leader->dwfl != NULL) {
|
||||
+ int frames = options.bt_depth;
|
||||
+ if (dwfl_getthread_frames(proc->leader->dwfl, proc->pid,
|
||||
+ frame_callback, &frames) < 0) {
|
||||
+ // Only print an error if we couldn't show anything.
|
||||
+ // Otherwise just show there might be more...
|
||||
+ if (frames == options.bt_depth)
|
||||
+ fprintf(stderr,
|
||||
+ "dwfl_getthread_frames tid %d: %s\n",
|
||||
+ proc->pid, dwfl_errmsg(-1));
|
||||
+ else
|
||||
+ fprintf(options.output, " > [...]\n");
|
||||
+ }
|
||||
+ fprintf(options.output, "\n");
|
||||
+ }
|
||||
+#endif /* defined(HAVE_LIBDW) */
|
||||
+
|
||||
current_proc = NULL;
|
||||
current_column = 0;
|
||||
}
|
||||
Only in ltrace-0.7.91-pm/: output.c.orig
|
||||
diff -u ltrace-0.7.91/proc.c ltrace-0.7.91-pm/proc.c
|
||||
--- ltrace-0.7.91/proc.c 2015-01-09 00:38:17.981190650 +0100
|
||||
+++ ltrace-0.7.91-pm/proc.c 2015-01-09 00:37:40.261910548 +0100
|
||||
@@ -111,6 +111,11 @@
|
||||
if (proc->unwind_as != NULL)
|
||||
unw_destroy_addr_space(proc->unwind_as);
|
||||
#endif /* defined(HAVE_LIBUNWIND) */
|
||||
+
|
||||
+#if defined(HAVE_LIBDW)
|
||||
+ if (proc->dwfl != NULL)
|
||||
+ dwfl_end(proc->dwfl);
|
||||
+#endif /* defined(HAVE_LIBDW) */
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -172,6 +177,10 @@
|
||||
}
|
||||
#endif /* defined(HAVE_LIBUNWIND) */
|
||||
|
||||
+#if defined(HAVE_LIBDW)
|
||||
+ proc->dwfl = NULL; /* Initialize for leader only on first library. */
|
||||
+#endif /* defined(HAVE_LIBDW) */
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -887,6 +896,59 @@
|
||||
debug(DEBUG_PROCESS, "added library %s@%p (%s) to %d",
|
||||
lib->soname, lib->base, lib->pathname, proc->pid);
|
||||
|
||||
+#if defined(HAVE_LIBDW)
|
||||
+ if (options.bt_depth > 0) {
|
||||
+ /* Setup module tracking for libdwfl unwinding. */
|
||||
+ struct process *leader = proc->leader;
|
||||
+ Dwfl *dwfl = leader->dwfl;
|
||||
+ if (dwfl == NULL) {
|
||||
+ static const Dwfl_Callbacks proc_callbacks = {
|
||||
+ .find_elf = dwfl_linux_proc_find_elf,
|
||||
+ .find_debuginfo = dwfl_standard_find_debuginfo
|
||||
+ };
|
||||
+ dwfl = dwfl_begin(&proc_callbacks);
|
||||
+ if (dwfl == NULL)
|
||||
+ fprintf(stderr,
|
||||
+ "Couldn't initialize libdwfl unwinding "
|
||||
+ "for process %d: %s\n", leader->pid,
|
||||
+ dwfl_errmsg (-1));
|
||||
+ }
|
||||
+
|
||||
+ if (dwfl != NULL) {
|
||||
+ dwfl_report_begin_add(dwfl);
|
||||
+ if (dwfl_report_elf(dwfl, lib->soname,
|
||||
+ lib->pathname, -1,
|
||||
+ (GElf_Addr) lib->base,
|
||||
+ false) == NULL)
|
||||
+ fprintf(stderr,
|
||||
+ "dwfl_report_elf %s@%p (%s) %d: %s\n",
|
||||
+ lib->soname, lib->base, lib->pathname,
|
||||
+ proc->pid, dwfl_errmsg (-1));
|
||||
+ dwfl_report_end(dwfl, NULL, NULL);
|
||||
+
|
||||
+ if (leader->dwfl == NULL) {
|
||||
+ int r = dwfl_linux_proc_attach(dwfl,
|
||||
+ leader->pid,
|
||||
+ true);
|
||||
+ if (r == 0)
|
||||
+ leader->dwfl = dwfl;
|
||||
+ else {
|
||||
+ const char *msg;
|
||||
+ dwfl_end(dwfl);
|
||||
+ if (r < 0)
|
||||
+ msg = dwfl_errmsg(-1);
|
||||
+ else
|
||||
+ msg = strerror(r);
|
||||
+ fprintf(stderr, "Couldn't initialize "
|
||||
+ "libdwfl unwinding for "
|
||||
+ "process %d: %s\n",
|
||||
+ leader->pid, msg);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* defined(HAVE_LIBDW) */
|
||||
+
|
||||
/* Insert breakpoints for all active (non-latent) symbols. */
|
||||
struct library_symbol *libsym = NULL;
|
||||
while ((libsym = library_each_symbol(lib, libsym,
|
||||
diff -u ltrace-0.7.91/proc.c.orig ltrace-0.7.91-pm/proc.c.orig
|
||||
--- ltrace-0.7.91/proc.h 2015-01-09 00:38:17.966190936 +0100
|
||||
+++ ltrace-0.7.91-pm/proc.h 2015-01-09 00:37:40.261910548 +0100
|
||||
@@ -28,6 +28,10 @@
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
+#if defined(HAVE_LIBDW)
|
||||
+# include <elfutils/libdwfl.h>
|
||||
+#endif
|
||||
+
|
||||
#if defined(HAVE_LIBUNWIND)
|
||||
# include <libunwind.h>
|
||||
#endif /* defined(HAVE_LIBUNWIND) */
|
||||
@@ -113,6 +117,11 @@
|
||||
short e_machine;
|
||||
char e_class;
|
||||
|
||||
+#if defined(HAVE_LIBDW)
|
||||
+ /* Unwind info for leader, NULL for non-leader procs. */
|
||||
+ Dwfl *dwfl;
|
||||
+#endif /* defined(HAVE_LIBDW) */
|
||||
+
|
||||
#if defined(HAVE_LIBUNWIND)
|
||||
/* libunwind address space */
|
||||
unw_addr_space_t unwind_as;
|
||||
Only in ltrace-0.7.91-pm/: proc.h.orig
|
||||
Common subdirectories: ltrace-0.7.91/sysdeps and ltrace-0.7.91-pm/sysdeps
|
||||
Common subdirectories: ltrace-0.7.91/testsuite and ltrace-0.7.91-pm/testsuite
|
||||
diff -up ltrace-0.7.91/proc.c\~ ltrace-0.7.91/proc.c
|
||||
--- ltrace-0.7.91/proc.c~ 2015-01-09 01:55:38.289864078 +0100
|
||||
+++ ltrace-0.7.91/proc.c 2015-01-09 01:56:29.818881935 +0100
|
||||
@@ -918,7 +918,8 @@ proc_add_library(struct process *proc, s
|
||||
dwfl_report_begin_add(dwfl);
|
||||
if (dwfl_report_elf(dwfl, lib->soname,
|
||||
lib->pathname, -1,
|
||||
- (GElf_Addr) lib->base,
|
||||
+ /* XXX double cast */
|
||||
+ (GElf_Addr) (uintptr_t) lib->base,
|
||||
false) == NULL)
|
||||
fprintf(stderr,
|
||||
"dwfl_report_elf %s@%p (%s) %d: %s\n",
|
||||
101
ltrace-0.7.91-x86-plt_map.patch
Normal file
101
ltrace-0.7.91-x86-plt_map.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From fba95ad936f1d8c1052259bae811f1fc07f9a215 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Machata <pmachata@redhat.com>
|
||||
Date: Thu, 30 Oct 2014 01:48:17 +0100
|
||||
Subject: [PATCH] Initialize the PLT slot map correctly on x86 and x86_64
|
||||
|
||||
The PLT slot map translates relocation numbers to PLT slot numbers,
|
||||
but was actually initialized in the opposite direction. Fix the way
|
||||
it's initialized. This bug can be seen on glibc in particular:
|
||||
|
||||
$ ltrace -e free ls
|
||||
libc.so.6->free(0x5) = <void>
|
||||
libc.so.6->free(0x78) = <void>
|
||||
libc.so.6->free(0xc) = <void>
|
||||
libc.so.6->free(0x308) = <void>
|
||||
|
||||
Note the nonsense values passed to free. The problem is that these
|
||||
are not free calls at all, but malloc calls that are assigned to wrong
|
||||
PLT slots due to above bug.
|
||||
---
|
||||
sysdeps/linux-gnu/x86/plt.c | 38 +++++++++++++++++++++-----------------
|
||||
1 file changed, 21 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/sysdeps/linux-gnu/x86/plt.c b/sysdeps/linux-gnu/x86/plt.c
|
||||
index c860af6..97f6c3e 100644
|
||||
--- a/sysdeps/linux-gnu/x86/plt.c
|
||||
+++ b/sysdeps/linux-gnu/x86/plt.c
|
||||
@@ -77,6 +77,18 @@ arch_elf_init(struct ltelf *lte, struct library *lib)
|
||||
{
|
||||
VECT_INIT(<e->arch.plt_map, unsigned int);
|
||||
|
||||
+ if (vect_reserve(<e->arch.plt_map, vect_size(<e->plt_relocs)) < 0) {
|
||||
+ fail:
|
||||
+ arch_elf_destroy(lte);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ unsigned int i, sz = vect_size(<e->plt_relocs);
|
||||
+ for (i = 0; i < sz; ++i)
|
||||
+ vect_pushback (<e->arch.plt_map, &i);
|
||||
+ }
|
||||
+
|
||||
/* IRELATIVE slots may make the whole situation a fair deal
|
||||
* more complex. On x86{,_64}, the PLT slots are not
|
||||
* presented in the order of the corresponding relocations,
|
||||
@@ -114,43 +126,35 @@ arch_elf_init(struct ltelf *lte, struct library *lib)
|
||||
/* Here we scan the PLT table and initialize a map of
|
||||
* relocation->slot number in lte->arch.plt_map. */
|
||||
|
||||
- size_t i;
|
||||
- for (i = 0; i < vect_size(<e->plt_relocs); ++i) {
|
||||
+ unsigned int i, sz = vect_size(<e->plt_relocs);
|
||||
+ for (i = 0; i < sz; ++i) {
|
||||
|
||||
GElf_Addr offset = x86_plt_offset(i);
|
||||
- uint32_t reloc_arg = 0;
|
||||
|
||||
uint8_t byte;
|
||||
if (elf_read_next_u8(lte->plt_data, &offset, &byte) < 0
|
||||
|| byte != 0xff
|
||||
|| elf_read_next_u8(lte->plt_data, &offset, &byte) < 0
|
||||
|| (byte != 0xa3 && byte != 0x25))
|
||||
- goto next;
|
||||
+ continue;
|
||||
|
||||
/* Skip immediate argument in the instruction. */
|
||||
offset += 4;
|
||||
|
||||
+ uint32_t reloc_arg;
|
||||
if (elf_read_next_u8(lte->plt_data, &offset, &byte) < 0
|
||||
|| byte != 0x68
|
||||
|| elf_read_next_u32(lte->plt_data,
|
||||
- &offset, &reloc_arg) < 0) {
|
||||
- reloc_arg = 0;
|
||||
- goto next;
|
||||
- }
|
||||
+ &offset, &reloc_arg) < 0)
|
||||
+ continue;
|
||||
|
||||
if (lte->ehdr.e_machine == EM_386) {
|
||||
- if (reloc_arg % 8 != 0) {
|
||||
- reloc_arg = 0;
|
||||
- goto next;
|
||||
- }
|
||||
+ if (reloc_arg % 8 != 0)
|
||||
+ continue;
|
||||
reloc_arg /= 8;
|
||||
}
|
||||
|
||||
- next:
|
||||
- if (VECT_PUSHBACK(<e->arch.plt_map, &reloc_arg) < 0) {
|
||||
- arch_elf_destroy(lte);
|
||||
- return -1;
|
||||
- }
|
||||
+ *VECT_ELEMENT(<e->arch.plt_map, unsigned int, reloc_arg) = i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
--
|
||||
2.1.0
|
||||
|
||||
32
ltrace-0.7.91-x86-unused_label.patch
Normal file
32
ltrace-0.7.91-x86-unused_label.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From e16a28f1b6e5a15368f8ed98dc29a6da714dc5fa Mon Sep 17 00:00:00 2001
|
||||
From: Petr Machata <pmachata@redhat.com>
|
||||
Date: Tue, 9 Dec 2014 17:44:30 +0100
|
||||
Subject: [PATCH] Drop unused label in x86 backend
|
||||
|
||||
---
|
||||
sysdeps/linux-gnu/x86/plt.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sysdeps/linux-gnu/x86/plt.c b/sysdeps/linux-gnu/x86/plt.c
|
||||
index 97f6c3e..44ea260 100644
|
||||
--- a/sysdeps/linux-gnu/x86/plt.c
|
||||
+++ b/sysdeps/linux-gnu/x86/plt.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ltrace.
|
||||
- * Copyright (C) 2013 Petr Machata, Red Hat Inc.
|
||||
+ * Copyright (C) 2013,2014 Petr Machata, Red Hat Inc.
|
||||
* Copyright (C) 2004,2008,2009 Juan Cespedes
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -78,7 +78,6 @@ arch_elf_init(struct ltelf *lte, struct library *lib)
|
||||
VECT_INIT(<e->arch.plt_map, unsigned int);
|
||||
|
||||
if (vect_reserve(<e->arch.plt_map, vect_size(<e->plt_relocs)) < 0) {
|
||||
- fail:
|
||||
arch_elf_destroy(lte);
|
||||
return -1;
|
||||
}
|
||||
--
|
||||
2.1.0
|
||||
|
||||
156
ltrace-0.7.91-x86_64-irelative.patch
Normal file
156
ltrace-0.7.91-x86_64-irelative.patch
Normal file
@ -0,0 +1,156 @@
|
||||
@@ -, +, @@
|
||||
relocation
|
||||
- In general they are. But IRELATIVE relocations are sorted to come
|
||||
last, and PLT entries are not sorted accordingly.
|
||||
---
|
||||
sysdeps/linux-gnu/x86/arch.h | 11 +++++
|
||||
sysdeps/linux-gnu/x86/plt.c | 101 +++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 111 insertions(+), 1 deletions(-)
|
||||
--- a/sysdeps/linux-gnu/x86/arch.h
|
||||
+++ a/sysdeps/linux-gnu/x86/arch.h
|
||||
@@ -19,6 +19,10 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
+#ifndef LTRACE_X86_ARCH_H
|
||||
+#define LTRACE_X86_ARCH_H
|
||||
+
|
||||
+#include "vect.h"
|
||||
|
||||
#define BREAKPOINT_VALUE {0xcc}
|
||||
#define BREAKPOINT_LENGTH 1
|
||||
@@ -30,9 +34,16 @@
|
||||
|
||||
#define ARCH_HAVE_ADD_PLT_ENTRY
|
||||
|
||||
+#define ARCH_HAVE_LTELF_DATA
|
||||
+struct arch_ltelf_data {
|
||||
+ struct vect plt_map;
|
||||
+};
|
||||
+
|
||||
#ifdef __x86_64__
|
||||
#define LT_ELFCLASS ELFCLASS64
|
||||
#define LT_ELF_MACHINE EM_X86_64
|
||||
#endif
|
||||
#define LT_ELFCLASS2 ELFCLASS32
|
||||
#define LT_ELF_MACHINE2 EM_386
|
||||
+
|
||||
+#endif /* LTRACE_X86_ARCH_H */
|
||||
--- a/sysdeps/linux-gnu/x86/plt.c
|
||||
+++ a/sysdeps/linux-gnu/x86/plt.c
|
||||
@@ -27,10 +27,19 @@
|
||||
#include "library.h"
|
||||
#include "trace.h"
|
||||
|
||||
+static GElf_Addr
|
||||
+x86_plt_offset(uint32_t i)
|
||||
+{
|
||||
+ /* Skip the first PLT entry, which contains a stub to call the
|
||||
+ * resolver. */
|
||||
+ return (i + 1) * 16;
|
||||
+}
|
||||
+
|
||||
GElf_Addr
|
||||
arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela)
|
||||
{
|
||||
- return lte->plt_addr + (ndx + 1) * 16;
|
||||
+ uint32_t i = *VECT_ELEMENT(<e->arch.plt_map, uint32_t, ndx);
|
||||
+ return x86_plt_offset(i) + lte->plt_addr;
|
||||
}
|
||||
|
||||
void *
|
||||
@@ -62,3 +71,93 @@ arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
|
||||
|
||||
return PLT_DEFAULT;
|
||||
}
|
||||
+
|
||||
+int
|
||||
+arch_elf_init(struct ltelf *lte, struct library *lib)
|
||||
+{
|
||||
+ VECT_INIT(<e->arch.plt_map, unsigned int);
|
||||
+
|
||||
+ /* IRELATIVE slots may make the whole situation a fair deal
|
||||
+ * more complex. On x86{,_64}, the PLT slots are not
|
||||
+ * presented in the order of the corresponding relocations,
|
||||
+ * but in the order it which these symbols are in the symbol
|
||||
+ * table. That's static symbol table, which may be stripped
|
||||
+ * off, not dynsym--that doesn't contain IFUNC symbols at all.
|
||||
+ * So we have to decode each PLT entry to figure out what
|
||||
+ * entry it corresponds to. We need to interpret the PLT
|
||||
+ * table to figure this out.
|
||||
+ *
|
||||
+ * On i386, the PLT entry format is as follows:
|
||||
+ *
|
||||
+ * 8048300: ff 25 0c a0 04 08 jmp *0x804a00c
|
||||
+ * 8048306: 68 20 00 00 00 push $0x20
|
||||
+ * 804830b: e9 e0 ff ff ff jmp 80482f0 <_init+0x30>
|
||||
+ *
|
||||
+ * For PIE binaries it is the following:
|
||||
+ *
|
||||
+ * 410: ff a3 10 00 00 00 jmp *0x10(%ebx)
|
||||
+ * 416: 68 00 00 00 00 push $0x0
|
||||
+ * 41b: e9 d0 ff ff ff jmp 3f0 <_init+0x30>
|
||||
+ *
|
||||
+ * On x86_64, it is:
|
||||
+ *
|
||||
+ * 400420: ff 25 f2 0b 20 00 jmpq *0x200bf2(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
|
||||
+ * 400426: 68 00 00 00 00 pushq $0x0
|
||||
+ * 40042b: e9 e0 ff ff ff jmpq 400410 <_init+0x18>
|
||||
+ *
|
||||
+ * On i386, the argument to push is an offset of relocation to
|
||||
+ * use. The first PLT slot has an offset of 0x0, the second
|
||||
+ * 0x8, etc. On x86_64, it's directly the index that we are
|
||||
+ * looking for.
|
||||
+ */
|
||||
+
|
||||
+ /* Here we scan the PLT table and initialize a map of
|
||||
+ * relocation->slot number in lte->arch.plt_map. */
|
||||
+
|
||||
+ size_t i;
|
||||
+ for (i = 0; i < vect_size(<e->plt_relocs); ++i) {
|
||||
+
|
||||
+ GElf_Addr offset = x86_plt_offset(i);
|
||||
+ uint32_t reloc_arg = 0;
|
||||
+
|
||||
+ uint8_t byte;
|
||||
+ if (elf_read_next_u8(lte->plt_data, &offset, &byte) < 0
|
||||
+ || byte != 0xff
|
||||
+ || elf_read_next_u8(lte->plt_data, &offset, &byte) < 0
|
||||
+ || (byte != 0xa3 && byte != 0x25))
|
||||
+ goto next;
|
||||
+
|
||||
+ /* Skip immediate argument in the instruction. */
|
||||
+ offset += 4;
|
||||
+
|
||||
+ if (elf_read_next_u8(lte->plt_data, &offset, &byte) < 0
|
||||
+ || byte != 0x68
|
||||
+ || elf_read_next_u32(lte->plt_data,
|
||||
+ &offset, &reloc_arg) < 0) {
|
||||
+ reloc_arg = 0;
|
||||
+ goto next;
|
||||
+ }
|
||||
+
|
||||
+ if (lte->ehdr.e_machine == EM_386) {
|
||||
+ if (reloc_arg % 8 != 0) {
|
||||
+ reloc_arg = 0;
|
||||
+ goto next;
|
||||
+ }
|
||||
+ reloc_arg /= 8;
|
||||
+ }
|
||||
+
|
||||
+ next:
|
||||
+ if (VECT_PUSHBACK(<e->arch.plt_map, &reloc_arg) < 0) {
|
||||
+ arch_elf_destroy(lte);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+arch_elf_destroy(struct ltelf *lte)
|
||||
+{
|
||||
+ VECT_DESTROY(<e->arch.plt_map, uint32_t, NULL, NULL);
|
||||
+}
|
||||
--
|
||||
BIN
ltrace-0.7.91.tar.gz
Normal file
BIN
ltrace-0.7.91.tar.gz
Normal file
Binary file not shown.
77
ltrace.spec
Normal file
77
ltrace.spec
Normal file
@ -0,0 +1,77 @@
|
||||
name: ltrace
|
||||
Version: 0.7.91
|
||||
Release: 29
|
||||
Summary: Trace the Library and System Calls a Program Makes
|
||||
|
||||
License: GPLv2+
|
||||
URL: https://gitlab.com/cespedes/ltrace
|
||||
Source0: http://repository.timesys.com/buildsources/l/ltrace/ltrace-0.7.91/ltrace-0.7.91.tar.gz
|
||||
|
||||
Patch0001: ltrace-0.7.91-account_execl.patch
|
||||
Patch0002: ltrace-0.7.91-x86_64-irelative.patch
|
||||
Patch0003: ltrace-0.7.91-man.patch
|
||||
Patch0004: ltrace-0.7.91-cant_open.patch
|
||||
Patch0005: ltrace-0.7.91-aarch64.patch
|
||||
Patch0006: ltrace-0.7.2-e_machine.patch
|
||||
Patch0007: ltrace-0.7.91-parser-ws_after_id.patch
|
||||
Patch0008: ltrace-0.7.91-x86-plt_map.patch
|
||||
Patch0009: ltrace-0.7.91-x86-unused_label.patch
|
||||
Patch0010: ltrace-0.7.91-unwind-elfutils.patch
|
||||
Patch0011: ltrace-0.7.91-multithread-no-f-1.patch
|
||||
Patch0012: ltrace-0.7.91-multithread-no-f-2.patch
|
||||
Patch0013: ltrace-0.7.91-testsuite-includes.patch
|
||||
Patch0014: ltrace-0.7.91-testsuite-includes-2.patch
|
||||
Patch0015: ltrace-0.7.91-tautology.patch
|
||||
Patch0016: ltrace-0.7.91-aarch64-params.patch
|
||||
|
||||
# patch for openEuler
|
||||
Patch9000: bugfix-0001-ltrace-0.7.91-aarch64_be-compile-support.patch
|
||||
Patch9001: bugfix-0001-ltrace-byteswap-instruction-in-arm-be8-mode.patch
|
||||
Patch9002: bugfix-for-use-after-free-about-soname.patch
|
||||
|
||||
BuildRequires: elfutils-devel dejagnu libselinux-devel autoconf automake libtool
|
||||
|
||||
%description
|
||||
Ltrace is a program that runs the specified command until it exits. It
|
||||
intercepts and records the dynamic library calls that are called by the
|
||||
executed process and the signals that are received by that process. It
|
||||
can also intercept and print the system calls executed by the program.
|
||||
|
||||
The program to trace need not be recompiled for this, so you can use
|
||||
ltrace on binaries for which you do not have access to the source.
|
||||
|
||||
This is still a work in progress, so, for example, the tracking to
|
||||
child processes may fail or some things may not work as expected.
|
||||
|
||||
%package help
|
||||
Summary: Help document for the ltrace package
|
||||
|
||||
%description help
|
||||
Help document for the ltrace package.
|
||||
|
||||
%prep
|
||||
%autosetup -n %{name}-%{version} -p1
|
||||
|
||||
%build
|
||||
autoreconf -i
|
||||
%configure --docdir=%{?_pkgdocdir}%{!?_pkgdocdir:%{_docdir}/%{name}-%{version}}
|
||||
%make_build
|
||||
|
||||
%install
|
||||
%make_install bindir=%{_bindir}
|
||||
|
||||
%check
|
||||
timeout 180 make check ||:
|
||||
|
||||
%files
|
||||
%doc NEWS CREDITS INSTALL README TODO COPYING
|
||||
%{_bindir}/ltrace
|
||||
%{_datadir}/ltrace
|
||||
|
||||
%files help
|
||||
%{_mandir}/man1/ltrace.1*
|
||||
%{_mandir}/man5/ltrace.conf.5*
|
||||
|
||||
%changelog
|
||||
* Wed Nov 27 2019 daiqianwen <daiqianwen@huawei.com> - 0.7.91-29
|
||||
- Package init.
|
||||
Loading…
x
Reference in New Issue
Block a user