Commit Graph

33 Commits

Author SHA1 Message Date
Eugene Syromiatnikov
965069d691 unwind.c: fix typo in comment
* unwind.c (unwind_cache_invalidate, unwind_print_stacktrace,
unwind_capture_stacktrace): Replace strack with stack.
2017-11-20 21:39:59 +00:00
2698d1d060 Unexport die_out_of_memory
Print more specific error diagnostics than a generic "Out of memory"
when an error happens outside xmalloc.c.

* defs.h (die_out_of_memory): Remove prototype.
* strace.c (strace_popen, init): Call perror_msg_and_die instead
of die_out_of_memory.
* unwind.c (unwind_tcb_init): Likewise.
* xmalloc.c (die_out_of_memory): Add static qualifier.
2017-06-26 22:41:28 +00:00
184e94ba05 Fix a few spacing style issues
Reported by kernel's checkpatch.pl script.
2017-06-17 22:54:08 +00:00
6c08f7d65c Fix macros encosure in a do/while loop
Enclose macros with multiple statements and macros starting
with "if" statement in a do/while loop.
Do not enclose single statement macros in a do/while loop.

Reported by kernel's checkpatch.pl script.
2017-06-17 21:51:48 +00:00
170281be5b Use __func__ instead of gcc specific __FUNCTION__
Reported by kernel's checkpatch.pl script.
2017-06-17 20:49:09 +00:00
Eugene Syromyatnikov
9d095c7860 Add copyright headers 2017-05-22 17:33:51 +00:00
Eugene Syromyatnikov
032f0667ba unwind.c: remove non-ASCII character from comment 2017-05-22 19:11:06 +02:00
Victor Krapivensky
9d1250b39c unwind.c: fix a possible buffer overflow
Linux does not prevent a user from creating a lot of nested directories
with length of the absolute path of the deepest one exceeding PATH_MAX,
then chdir'ing into it, creating a file there and mmap'ing it. Since the
length of the prefix preceding the pathname in /proc/[pid]/maps is not
necessary 80 (it's 73 on my machine), an overflow is possible.

* unwind.c (build_mmap_cache): Fix a possible buffer overflow.
2017-03-13 15:19:22 +00:00
Sean Stangl
54c7792bfd Fix libunwind segfault when -p is passed before -k
* strace.c (init) [USE_LIBUNWIND]: Call unwind_tcb_init after
unwind_init for all allocated tcb structures if stack trace is enabled.
* unwind.c (unwind_tcb_init): Skip if tcb is already initialized.

Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2016-12-13 20:21:22 +00:00
6c8ef051f7 Consistently use error_msg instead of fprintf(stderr)
* linux/alpha/get_scno.c: Use error_msg.
* linux/arm/get_scno.c: Likewise.
* linux/mips/get_scno.c: Likewise.
* linux/sh/get_scno.c: Likewise.
* linux/x86_64/get_scno.c: Likewise.
* exit.c (sys_exit): Likewise.
* pathtrace.c (pathtrace_select, pathtrace_match): Likewise.
* strace.c (alloctcb, droptcb, detach, startup_attach,
test_ptrace_seize, init, cleanup, print_debug_info,
maybe_allocate_tcb, startup_tcb, trace): Likewise.
* syscall.c (update_personality, trace_syscall_exiting,
get_scno): Likewise.
* unwind.c (DPRINTF): Likewise.
* tests/bexecve.test: Update patterns.
* tests/detach-stopped.test: Likewise.
2015-05-25 23:31:31 +00:00
3e9d71feaa Introduce memory allocation wrappers
Introduce wrappers to the following functions that do memory allocation:
malloc, calloc, realloc, strdup.

This commit is a follow-up to the related discussions in strace-devel ML:
http://sourceforge.net/p/strace/mailman/message/33618180/
http://sourceforge.net/p/strace/mailman/message/33733470/

* defs.h (xmalloc, xcalloc, xreallocarray, xstrdup): New prototypes.
* xmalloc.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* count.c (count_syscall, call_summary_pers): Use xcalloc.
* desc.c (decode_select): Use xmalloc.
* dirent.c (sys_getdents, sys_getdents64): Likewise.
* net.c (sys_recvmmsg): Use xstrdup.
* pathtrace.c (storepath): Use xreallocarray.
(pathtrace_match): Use xmalloc.
* strace.c (die_out_of_memory): Move to xmalloc.c.
(expand_tcbtab): Use xcalloc and xreallocarray.
(startup_child): Use xstrdup.
(init): Use xmalloc, xcalloc, and xstrdup.
* syscall.c (reallocate_qual): Use xreallocarray.
(qualify): Use xstrdup.
* unwind.c (unwind_tcb_init): Use xmalloc.
(build_mmap_cache): Use xcalloc, xreallocarray, and xstrdup.
(get_symbol_name): Use xreallocarray.
(stacktrace_walk, queue_put): Use xmalloc.
* util.c (printstr): Use xmalloc.
* vsprintf.c (strace_vfprintf): Likewise.
2015-05-25 22:25:22 +00:00
Thomas De Schampheleire
22deda33c6 stack trace support: fix check on symbol name presence
The output format of the stack trace is supposed to be different
depending on whether symbol names are available in the build.

However, the check only verified the validity of the pointer, not of the
string pointed to (which could be empty).

This commit fixes the check so that the original output:

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x5e000
 > /lib/libc-2.10.1.so(_IO_file_doallocate+0x8c) [0x68a38]
 > /lib/libc-2.10.1.so(_IO_doallocbuf+0x6c) [0x78574]
 > /lib/libc-2.10.1.so(_IO_file_overflow+0x184) [0x7763c]
 > /lib/libc-2.10.1.so(_IO_file_xsputn+0x88) [0x76aac]
 > /lib/libc-2.10.1.so(_IO_puts+0xc8) [0x6b64c]
 > /bin/busybox(+0x0) [0x62c60]
 > /bin/busybox(+0x0) [0x4940]
 > /bin/busybox(+0x0) [0x499c]
 > /bin/busybox(+0x0) [0x4e08]
 > /lib/libc-2.10.1.so(__libc_init_first+0x30c) [0x1f84c]
 > /lib/libc-2.10.1.so(__libc_start_main+0xd8) [0x1f9f8]

becomes:

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x5e000
 > /lib/libc-2.10.1.so(_IO_file_doallocate+0x8c) [0x68a38]
 > /lib/libc-2.10.1.so(_IO_doallocbuf+0x6c) [0x78574]
 > /lib/libc-2.10.1.so(_IO_file_overflow+0x184) [0x7763c]
 > /lib/libc-2.10.1.so(_IO_file_xsputn+0x88) [0x76aac]
 > /lib/libc-2.10.1.so(_IO_puts+0xc8) [0x6b64c]
 > /bin/busybox() [0x62c60]
 > /bin/busybox() [0x4940]
 > /bin/busybox() [0x499c]
 > /bin/busybox() [0x4e08]
 > /lib/libc-2.10.1.so(__libc_init_first+0x30c) [0x1f84c]
 > /lib/libc-2.10.1.so(__libc_start_main+0xd8) [0x1f9f8]

Signed-off-by: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
Acked-by: Masatake YAMATO <yamato@redhat.com>
2014-11-11 15:48:31 +00:00
73741d2e2e unwind: ignore memory mappings that have no PROT_EXEC bit set
* unwind.c (build_mmap_cache): For each memory mapping being scanned,
save its PROT_EXEC bit and skip the mapping if it is not set.
2014-06-13 15:58:00 +00:00
9a349c7779 unwind: cleanup build_mmap_cache
* unwind.c (build_mmap_cache): Move local variables to the code branch
where they are used.  Check return code of sscanf and strdup.  Do not
treat unusual memory mappings as fatal errors.  Do not skip memory
mappings with path names starting with "[".
2014-06-13 15:56:40 +00:00
2222b928c6 unwind: remove unused field from mmap_cache_t
* unwind.c (mmap_cache_t): Remove "deleted" field.
(build_mmap_cache): Remove initialization of "deleted" field.
2014-06-13 18:20:08 +04:00
52840ede0c unwind: refactor stacktrace_walk
* unwind.c (stacktrace_walk): Move stack frame printing code
to separate function print_stack_frame.
2014-06-12 22:12:31 +00:00
806539c55c unwind: constify binary_filename and symbol_name functions arguments
* unwind.c (call_action_fn, print_call_cb, sprint_call_or_error,
queue_put, queue_put_call): Add const qualifier to binary_filename and
symbol_name arguments.
2014-06-12 22:10:59 +00:00
Luca Clementi
f1d73110a0 unwind: disable stack trace with multiple personalities
* unwind.c (unwind_cache_invalidate, unwind_print_stacktrace,
unwind_capture_stacktrace): Disable stack tracing of non-default
personality processes.
2014-06-11 00:09:55 +00:00
6555711a6e unwind: rename function_off_set to function_offset
* unwind.c (call_action_fn, stacktrace_walk, STACK_ENTRY_SYMBOL_FMT,
print_call_cb, sprint_call_or_error, queue_put, queue_put_call):
Rename function_off_set to function_offset.
2014-06-05 23:00:28 +00:00
c12eb1117c unwind: fix a bug in range updating of binary search
* unwind.c (print_stacktrace): Fix another off-by-one error in binary search.
2014-06-05 21:40:43 +00:00
c903c822ee unwind: use fopen64 instead of fopen
* unwind.c (fopen_for_input): Define to fopen64 iff
[_LARGEFILE64_SOURCE && HAVE_FOPEN64], otherwise define it to fopen.
(build_mmap_cache): Use fopen_for_input instead of fopen.
2014-06-05 15:42:05 +00:00
e411397489 unwind: fix build on 32-bit architectures
Fix compilation warnings in unwind.c on 32-bit architectures.
On some architectures getuid is actually getuid32, so change the test
to use getpid instead of getuid.

* unwind.c (STACK_ENTRY_SYMBOL_FMT): Explicitly cast function_off_set
to unsigned long.
(queue_put_error): Change the 3rd argument's type to unsigned long.
* tests/stack-fcall.c (f1): Use getpid instead of getuid.
* tests/strace-k.test: Likewise.
2014-06-05 15:42:05 +00:00
Masatake YAMATO
a0b4ee7b38 unwind: enable dwarf cache of libunwind
Here is the benchmark of the dwarf cache.

Target program:

    #include <sched.h>
    int main(void)
    {
      unsigned int max = 0x6fff, i;
      for (i = 0; i < max; i++)
	sched_yield();
      return 0;
    }

Command line:

	./strace -o /dev/null -k a.out

With the dwarf cache:

    real	0m12.081s
    user	0m3.858s
    sys 	0m8.194s

Without the dwarf cache:

    real	0m22.326s
    user	0m5.218s
    sys		0m16.952s

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
2014-05-30 22:57:39 +00:00
Masatake YAMATO
b45b7faa1f unwind: report expected backtracing error
When a file mmap'ed to the target process is unlink'ed, backtracing the
stack would fail.  Current implementation reports it as
"backtracing_error".  To avoid confusion, the message is changed to
"expected_backtracing_error".

Here is the reproducer:

  $ cat ./p-deleted.c
  #include <unistd.h>

  int main(int argc, char **argv) {
    return unlink(argv[0]) < 0;
  }

  $ strace -e unlink -k ./p-deleted
  unlink("./p-deleted")                   = 0
   > /usr/lib64/libc-2.18.so(unlink+0x7) [0xe7f17]
   > /home/yamato/var/strace/t_unwind/p-deleted (deleted)(+0x0) [0x575]
   > /usr/lib64/libc-2.18.so(__libc_start_main+0xf5) [0x21d65]
   > backtracing_error [0x7ffff1365590]
  +++ exited with 0 +++

p-deleted is deleted therefore backtracing_error is reported.  This
patch records the deleted marker when making mmap cache and refers the
recorded information in the case "backtracing_error" to switch the
message.

Here is the output of this patch:

  $ strace -e unlink -k ./p-deleted
  unlink("./p-deleted")                   = 0
   > /usr/lib64/libc-2.18.so(unlink+0x7) [0xe7f17]
   > /home/yamato/var/strace/t_unwind/p-deleted (deleted)(+0x0) [0x575]
   > /usr/lib64/libc-2.18.so(__libc_start_main+0xf5) [0x21d65]
   > expected_backtracing_error [0x7ffff1365590]
  +++ exited with 0 +++

This solution is not perfect: if a file is unlink'ed after making the
mmap cache and before unwinding, strace cannot have a chance to record
the deleted marker.

In this version of patch, hardcoded magic number used in comparing "(delete)"
string is replaced with strlen as suggested by Dmitry Levin.

In old version of patch, the deleted entry was thrown away from mmap
cache to avoid to report "backtracing_error".  In this patch I keep it,
and just switch the error message.
Inspired by the review comment from Dmitry Levin.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
2014-05-30 22:57:19 +00:00
Masatake YAMATO
9bc6561588 unwind: implement automatic mmap cache invalidation
A mmap cache belonging to a tcb was updated when a system call which
changed the memory mapping was called.  This implementation was assumed
the mapping was changed only by the tcb.  However, this assumption is
incorrect if the target application is multi-threaded; more than two
tcbs can shared the same memory mapping and a tcb can modify it without
being noticed by the others.

This change introduces a global integer variable mmap_cache_generation,
and mmap_cache_generation field to struct tcb.  The variable
is incremented each time a process enters a syscall that can modify its
memory mapping.  Each tcb records the value of this variable at the
moment if  building its mmap cache.  Every mmap cache associated with
the given tcb can be validated by comparing its mmap_cache_generation
field with the variable mmap_cache_generation.

This implementation is inefficient.  If strace attaches two processes
which don't share the memory mapping, rebuilding mmap cache of a tcb
triggered by another tcb's mmap system call is not necessary.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
2014-05-30 22:56:14 +00:00
Masatake YAMATO
f8e39d7b7a unwind: introduce queue_t for capturing stacktrace
This is the second step for splitting capturing from printing.

New `queue' field is added to tcb.  Captured stacktrace is stored here.
The field is initialized/finalized at unwind_tcb_init/unwind_tcb_fin.

New API function unwind_capture_stacktrace is added.  This function
captures the currest stack using stracktrace_walker and records it in
tcb.  It's printing is delayed to the next call of
unwind_print_stacktrace.

unwind_print_stacktrace is extended.  Now it checks queue field of
the given tcb at the start of function.  If the function finds a
captured stack trace, the latter is printed using stracktrace_walker.

Currently unwind_capture_stacktrace invocations are added directly to
handlers of mmap, munmap, mprotect, and execve.

Here is the difference of output with/without patch:

(without patch)
  execve("./test-fork", ["./test-fork"], [/* 56 vars */]) = 0
   > /usr/lib64/ld-2.18.so(check_one_fd.part.0+0x82) [0x11f0]

(with patch)
  execve("./test-fork", ["./test-fork"], [/* 54 vars */]) = 0
   > /usr/lib64/libc-2.18.so(execve+0x7) [0xbcd27]
   > /home/yamato/var/strace/strace(exec_or_die+0x10c) [0x26ac]
   > /home/yamato/var/strace/strace(startup_child+0x346) [0x134f6]
   > /home/yamato/var/strace/strace(init+0x89f) [0x13dff]
   > /home/yamato/var/strace/strace(main+0xa) [0x26ca]
   > /usr/lib64/libc-2.18.so(__libc_start_main+0xf5) [0x21d65]
   > /home/yamato/var/strace/strace(_start+0x29) [0x2799]

In older version output lines of captured elements were built when
printing.  In this version they are built when capturing the stack.
As result, unneeded dynamic memory allocations are avoided.
Suggested by Luca Clementi.

In older version the combination of snprintf and realloc were used.
In this version they are replaced with asprintf.
Suggested by Dmitry Levin.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
2014-05-30 22:55:08 +00:00
Masatake YAMATO
4e121e5bb4 unwind: introduce own debug macro
* unwind.c (DPRINTF): New macro, to be utilized in debugging cache
management code.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
2014-05-30 22:54:07 +00:00
Masatake YAMATO
2d534daaa6 unwind: introduce stacktrace_walker
In current implementation, the stack trace is captured and printed at
the same time, in trace_syscall_exiting.  This approach cannot
provide user expected information when a system call changes the
memory mapping.  In such cases, the stack trace should be captured on
entering syscall and printed on exiting.

As the initial step for splitting capturing from printing, this change
introduces stacktrace_walker utility function.  It can be used both for
capturing in trace_syscall_entering and printing in
trace_syscall_exiting.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
2014-05-30 22:43:04 +00:00
Masatake YAMATO
6141392856 unwind: give all exported functions "unwind_" prefix
* unwind.c (init_unwind_addr_space): Rename to unwind_init.
(init_libunwind_ui): Rename to unwind_tcb_init.
(free_libunwind_ui): Rename to unwind_tcb_fin.
(delete_mmap_cache): Rename to unwind_cache_invalidate.
(print_stacktrace): Rename to unwind_print_stacktrace.
* defs.h: Update prototypes.
* mem.c: All callers updated.
* process.c: Likewise.
* strace.c: Likewise.
* syscall.c: Likewise.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
2014-05-30 22:40:22 +00:00
Masatake YAMATO
7721499fc7 unwind: delete mmap cache in free_libunwind_ui
free_libunwind_ui is expected to release all unwind related resources
attached to tcp.

* strace.c (droptcb): Move delete_mmap_cache call ...
* unwind.c (free_libunwind_ui): ... to here.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
2014-05-30 22:30:07 +00:00
Masatake YAMATO
b65042fbdb unwind: make alloc_mmap_cache function local
* defs.h (alloc_mmap_cache): Remove.
* unwind.c (alloc_mmap_cache): Add static qualifier.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
2014-05-30 22:28:15 +00:00
Masatake YAMATO
b4a2de8eff unwind: fix a bug in range updating of binary search
* unwind.c (print_stacktrace): Fix off-by-one error in binary search.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Luca Clementi <luca.clementi@gmail.com>
2014-05-30 22:26:42 +00:00
Luca Clementi
327064b637 Add -k option to print stack trace after each syscall
Print the stack trace of the traced process after each system call when
-k option is specified.  It is implemented using libunwind to unwind the
stack and to obtain the function name pointed by the IP.

Based on the code that was originally taken from strace-plus
of Philip J. Guo.

* configure.ac: Add --with-libunwind option.  Check libunwind support.
* Makefile.am: Add libunwind support.
* defs.h (struct tcb) [USE_LIBUNWIND]: Append libunwind specific fields.
[USE_LIBUNWIND] (stack_trace_enabled, alloc_mmap_cache,
delete_mmap_cache, print_stacktrace): New prototypes.
* mem.c (print_mmap, sys_munmap, sys_mprotect): Add libunwind support.
* process.c (sys_execve): Likewise.
* strace.c (usage, alloctcb, droptcb, init): Likewise.
* syscall.c (trace_syscall_exiting): Likewise.
* unwind.c: New file.
* strace.1: Document -k option.
2014-05-30 22:24:31 +00:00