tbricks / tbstack Goto Github PK
View Code? Open in Web Editor NEWFast stack trace utility
License: Other
Fast stack trace utility
License: Other
-------------------------------------------------------------------------------- DESCRIPTION tbstack -- fast stack trace utility. A primary design goal is to minimize performance impact on a process to make it possible to run it in low-latency systems. It is achieved by copying contents of stack regions when the process is frozen and unwinding stack when the process continues working. The idea was inspired by perf tool. The program uses POSIX, Linux API, and libunwind. -------------------------------------------------------------------------------- COMPATIBILITY This utility is intended for use with Linux on ARM, x86, and x86_64. Libraries: libelf, libunwind. It is recommended to get the latest version of libunwind. -------------------------------------------------------------------------------- INSTALLATION The build system is autotools: $ ./autogen.sh # Only required if building from git $ ./configure $ make # make install Configure options are available: $ ./configure --disable-ptrace $ make DESTDIR=/opt/tbstack DESTDIR tbstack binary will be installed there --disable-ptrace disable support for libunwind-ptrace -------------------------------------------------------------------------------- USAGE usage: tbstack <pid> tbstack <pid>/<tid1>,...,<tidn> tbstack <pid>/RS options: --help show this --ignore-deleted try to open shared objects marked as deleted --use-waitpid-timeout set alarm to interrupt waitpid --proc-mem prefer reading /proc/pid/mem. default flavor is process_vm_readv --ptrace use libunwind-ptrace interface (slower) --show-rsp show %rsp in second column --show-state show thread states --stack-size <size> maximum stack size to copy (default is current RLIMIT_STACK) --stop-timeout timeout for waiting the process to freeze, in milliseconds. default value is 1000 --verbose verbose error messages --version output version information and exit -------------------------------------------------------------------------------- HOW IT WORKS Binaries in mainstream Linux distributions are built with frame pointers omitted, so stack unwinding becomes more complex than just traversing a linked list. In order to move to the next frame we have to find corresponding frame description entry (FDE) in .eh_frame ELF section. It imples at least two binary searches: for a binary or shared object containing the code, and the FDE. One of solutions is examining process memory by ptrace and resolving next frame addresses while the process is stopped. Libunwind-ptrace implements such approach. Tbstack supports this interface as a flavor which can be enabled by --ptrace command line argument. In order to minimize performance impact tbstack uses another approach. At first it examines process' memory layout reading /proc/pid/maps. When the process is frozen (PTRACE_ATTACH to the main thread + SIGSTOP to start freezing other threads) it copies all threads' general-purpose registers and contents of stack from %rsp to end of memory region or up to maximum stack size if specified with --stack-size argument. System call proc_vm_readv is used. If it is not supported, the program falls back to reading /proc/pid/mem. The process continues execution. The collected data is enough to trace stacks. It is arranged in structures snapshot and mem_map and can be accessed through callback routines passed to libunwind by unw_create_addr_space (see http://www.nongnu.org/libunwind/man/unw_create_addr_space(3).html).
tbstack was working fine for a while, but then I started to get output that did not contain a backtrace:
segfault signal in version a14c0abc:
attach: Operation not permitted
detach: No such process
----------------------- summary --------------------------
time the process was frozen: 0ms 41us
sleep count: 0
total bytes copied: 0x0 (0K)
I was able to get tbstack working again by issuing the following commands (note: setuid root can pose a security risk):
chown 0:0 tbstack
chmod 4755 tbstack
Is there a way to resolve this without setuid root?
Ubuntu 16.04 LTS, kernel 4.15.0-106-generic, tbstack 1.0
Hi guys,
> ./configure --help | grep ptrace
--disable-ptrace Disable libunwind ptrace (default enabled)
> ./configure --disable-ptrace
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking how to create a pax tar archive... gnutar
checking whether make supports nested variables... (cached) yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking minix/config.h usability... no
checking minix/config.h presence... no
checking for minix/config.h... no
checking whether it is safe to define __EXTENSIONS__... yes
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking whether gcc understands -c and -o together... (cached) yes
checking dependency style of gcc... (cached) gcc3
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
checking for library containing elf_begin... -lelf
./configure: line 5359: syntax error near unexpected token `LIBUNWIND,'
./configure: line 5359: ` PKG_CHECK_MODULES(LIBUNWIND, libunwind-ptrace)'
[root@localhost tbstack]# make
gcc -O2 -D_XOPEN_SOURCE -D_GNU_SOURCE -c -o src/unwind.o src/unwind.c
src/unwind.c: In function ‘dw_get_value’:
src/unwind.c:39:16: error: ‘DW_EH_PE_omit’ undeclared (first use in this function)
if (enc == DW_EH_PE_omit) {
^
src/unwind.c:39:16: note: each undeclared identifier is reported only once for each function it appears in
src/unwind.c:44:16: error: ‘DW_EH_PE_absptr’ undeclared (first use in this function)
if (enc == DW_EH_PE_absptr) {
^
src/unwind.c:51:10: error: ‘DW_EH_PE_udata2’ undeclared (first use in this function)
case DW_EH_PE_udata2:
^
src/unwind.c:56:10: error: ‘DW_EH_PE_sdata2’ undeclared (first use in this function)
case DW_EH_PE_sdata2:
^
src/unwind.c:61:10: error: ‘DW_EH_PE_udata4’ undeclared (first use in this function)
case DW_EH_PE_udata4:
^
src/unwind.c:66:10: error: ‘DW_EH_PE_sdata4’ undeclared (first use in this function)
case DW_EH_PE_sdata4:
^
src/unwind.c:71:10: error: ‘DW_EH_PE_udata8’ undeclared (first use in this function)
case DW_EH_PE_udata8:
^
src/unwind.c:76:10: error: ‘DW_EH_PE_sdata8’ undeclared (first use in this function)
case DW_EH_PE_sdata8:
^
src/unwind.c:92:10: error: ‘DW_EH_PE_pcrel’ undeclared (first use in this function)
case DW_EH_PE_pcrel:
^
make: *** [src/unwind.o] Error 1
There are problems on 32-bit OpenSUSE.
If SYS_process_vm_readv
/__NR_process_vm_readv
is not defined, we define it to 310
which seemed to be acceptable solution when target architecture was only x86-64. We should either require fresh kernel headers or add architecture-specific definitions for other architectures.
offset
argument of pread()
has signed type off_t
and has size of 4 bytes on x86. However, large file support is enabled and pread64()
is used actually. It results in integer overflow for higher addresses. We should check _FILE_OFFSET_BITS
or _LARGEFILE64_SOURCE
. @tylerwhall could you please advise? Are systems on x86/arm without large file support widely used in embedded? If not, moving onto off64_t
/pread64()
with additional check in autotools would be enough so far.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.