Releases: namhyung/uftrace
uftrace v0.16
From now on, it supports reading symbol and debug information from the
separate debug files which are usually installed with debug packages.
This can be useful when you trace system binaries which may be stripped.
For example, you can only see library calls for such a binary. Let's
trace pwd program which just prints the current directory name.
$ nm /usr/bin/pwd
nm: /usr/bin/pwd: no symbols
$ uftrace pwd
uftrace: /home/namhyung/project/uftrace/cmds/record.c:1677:check_binary
ERROR: Can't find 'mcount' symbol in the '/usr/bin/pwd'.
It seems not to be compiled with -pg or -finstrument-functions flag.
You can rebuild your program with it or use -P option for dynamic tracing.
$ uftrace -P. pwd
/home/namhyung/tmp
# DURATION TID FUNCTION
3.156 us [955818] | getenv();
0.739 us [955818] | strrchr();
488.277 us [955818] | setlocale();
1.372 us [955818] | bindtextdomain();
0.886 us [955818] | textdomain();
0.703 us [955818] | __cxa_atexit();
5.760 us [955818] | getopt_long();
5.014 us [955818] | getcwd();
11.120 us [955818] | puts();
0.597 us [955818] | free();
...
But if you install the debug package, it can see the symbols and enable
the dynamic tracing as well.
$ sudo apt install coreutils-dbgsym
$ uftrace -P. -F main pwd
/home/namhyung/tmp
# DURATION TID FUNCTION
[955863] | main() {
1.779 us [955863] | getenv();
[955863] | set_program_name() {
0.423 us [955863] | strrchr();
0.734 us [955863] | } /* set_program_name */
222.047 us [955863] | setlocale();
1.089 us [955863] | bindtextdomain();
0.461 us [955863] | textdomain();
[955863] | atexit() {
0.604 us [955863] | __cxa_atexit();
0.850 us [955863] | } /* atexit */
0.992 us [955863] | getopt_long();
[955863] | xgetcwd() {
1.337 us [955863] | getcwd();
1.668 us [955863] | } /* xgetcwd */
7.242 us [955863] | puts();
0.312 us [955863] | free();
240.040 us [955863] | } /* main */
The next change is to support octal format argument which is usally used
in the library functions dealing with filesystems. It used to have a
predefined set of mode bits like 0755 and 0644 as an enum data type. But
obviously it cannot support all combination and shows broken numbers for
them. Now it works as expected with octal arguments.
$ uftrace -F .*chmod.* -a -- chmod 747 myfile
# DURATION TID FUNCTION
173.103 us [963584] | fchmodat(-100, "myfile", 0747, 0) = 0;
Also uftrace report
got two new output fields of (relative) standard
deviation for total and self time respectively. It'll be added when one
of --avg-total or --avg-self option is used.
$ uftrace report --avg-total
Total avg Total min Total max Total stdv Function
========== ========== ========== ========== ====================
671.447 us 671.447 us 671.447 us 0.00% setlocale
15.323 us 15.323 us 15.323 us 0.00% puts
8.458 us 8.458 us 8.458 us 0.00% getopt_long
7.044 us 7.044 us 7.044 us 0.00% getcwd
4.116 us 4.116 us 4.116 us 0.00% getenv
1.908 us 1.476 us 2.340 us 22.64% fclose
1.843 us 1.843 us 1.843 us 0.00% bindtextdomain
1.307 us 1.307 us 1.307 us 0.00% __cxa_atexit
1.294 us 1.294 us 1.294 us 0.00% strrchr
1.147 us 1.147 us 1.147 us 0.00% textdomain
0.980 us 0.980 us 0.980 us 0.00% free
0.734 us 0.251 us 1.217 us 65.80% __fpending
0.692 us 0.258 us 1.126 us 62.72% fileno
0.674 us 0.283 us 1.065 us 58.01% fflush
0.440 us 0.167 us 1.109 us 88.12% __freading
There are also more fixes and improvements. Notably it got big improvements
in Python tracing. So it can now trace sizeable projects written in Python
thanks to bug fixes in the debug file handling and symbol management without
affecting GC. Also there's a bug fix for library call tracing.
What's Changed
- build: Add -mno-sse to fix i386 build by @2096779623 in #1878
- build: Fix build failure on RHEL 7 by @shen390s in #1879
- mcount: Fix a compiler warning on PAGE_SIZE by @paranlee in #1882
- fix: #1858 by changing the wrong logic in update_dbg_info by @yihong0618 in #1884
- ci: Fix ci warning on GitHub Acitons by @yihong0618 in #1885
- slide: Add tensorflow and keras tracing example by @honggyukim in #1887
- python: Fix GC isn't working correctly. by @yihong0618 in #1888
- replay: Support a new argument format for octal values by @nadongguri in #1895
- build: Fix compiler warnings by @MichelleJin12 in #1906
- Fix Python SyntaxWarning on invalid escape sequence in the tests scripts by @AmeyaVS in #1907
- utils: Lower the debug level after dwfl_module_getdwarf by @honggyukim in #1911
- wrap: Do not print "dlopen is called for '(null)'" by @honggyukim in #1912
- Support standard deviation(STDDEV) in report output by @ziming-zh in #1913
- dwarf: Close file descriptors in setup_dwarf_info() by @ziming-zh in #1918
- New Release v0.16 by @namhyung in #1921
New Contributors
- @2096779623 made their first contribution in #1878
- @shen390s made their first contribution in #1879
- @nadongguri made their first contribution in #1895
- @AmeyaVS made their first contribution in #1907
- @ziming-zh made their first contribution in #1913
Full Changelog: v0.15...v0.16
uftrace v0.15.2
This is another bug fix release for v0.15 and it should fix build failures with clang on x86. No other functional changes.
The added -mno-sse
caused a problem on i386 and RHEL 7. Fix it by using the same set of options both for check and build. Also change the build script to use -mgeneral-regs-only
before -mno-sse
if available. And drop code that uses floating-point types in the libmcount.so.
New Contributors
- @2096779623 made their first contribution in #1878
- @shen390s made their first contribution in #1879
uftrace v0.15.1
This is a quick release to fix a build issue with clang on x86_64. No new changes and only affects those who build uftrace with clang compiler. See #1877 for details.
Thanks!
uftrace v0.15
This version comes with a new architecture support as well as
many bug fixes and various improvements.
RISC-V Architecture Support
uftrace can trace functions of RV64G binaries compiled by gcc/clang with
appropriate options (-pg
or -finstrument-functions
). Library functions
are also traced and you can see the arguments and return values too.
(There are issues in argument handling, but library functions should be
fine.) However dynamic tracing is not supported yet.
$ uftrace --force -a -t 3us -- uname -m
riscv64
# DURATION TID FUNCTION
263.004 us [138960] | strrchr("uname", '/') = "NULL";
87.751 us [138960] | setlocale(LC_ALL, "") = "NULL";
5.000 us [138960] | bindtextdomain("coreutils", "/usr/share/locale");
4.000 us [138960] | getopt_long(2, 0x3fecdcf328, "asnrvmpio") = 109;
4.000 us [138960] | uname();
8.250 us [138960] | fputs_unlocked();
443.257 us [138960] | __overflow();
3.250 us [138960] | __fpending();
4.500 us [138960] | fclose(&_IO_2_1_stdout_) = 0;
Other Notable Improvements
As libtraceevent is available on recent distros, the kernel tracing uses
the system installed library and drops the old copy in the uftrace source.
This should help resolving possible future kernel issues and reduce the
maintenance burden.
Also some distros build binaries without PLT and it can confuse uftrace
about the library call tracing. It now detects the case by verifying
PLT entries not to miss library calls without it.
What's Changed
- configure: fix error when building out of source by @licy183 in #1737
- doc: Update README.md for user space function tracing by @honggyukim in #1742
- docs: uftrace slides update by @paranlee in #1744
- Refactor the kernel depth option and documentation by @ChoKyuWon in #1759
- tests: fix t151 recv_runcmd test code. by @kang-hyuck in #1765
- dynamic: Refactor patch pattern logic by @clementguidi in #1703
- tests: Changing test case statistics conditions. by @coyotek in #1771
- utils: fix demangle_full to only demangle mangled C++ symbols by @jyf111 in #1780
- doc: Fix --task name in uftrace graph man page by @honggyukim in #1785
- misc: modify manual to build dockerfile by @haileynam in #1783
- doc/ko: Update README in Korean by @mirusu400 in #1760
- tests: fix
gen_port()
to select unbind ports by @mirusu400 in #1769 - dump: Fix Mermaid to work properly by specifying the version of Mermaid by @mirusu400 in #1794
- utils: Fix an issue not finding tracefs on some kernels by @gichoel in #1762
- doc: Fix typo in uftrace.md by @mirusu400 in #1786
- doc/ko: Update CONTRIBUTING.md in Korean by @jigsaw-0 in #1790
- doc/ko: Add missing options in man pages by @jeonghwanin in #1806
- filter: Remove obsolete function add_trigger by @sypark9646 in #1807
- doc: Add = sign for '--depth' option in uftrace-dump.md by @SEOKMIN83 in #1788
- misc: Add wget-pr.sh script by @honggyukim in #1808
- utils: Remove unused function: get_event_name by @SEOKMIN83 in #1817
- mcount-dynamic: Use MAP_FIXED_NOREPLACE for trampoline by @oldiob in #1798
- tests: Change tests/runtest.py to match the pylint code style by @sypark9646 in #1810
- dynamic: Fix -U for -fpatchable-function-entry by @honggyukim in #1799
- libmcount: support no-plt binary by @ChoKyuWon in #1820
- uftrace: fix a memory leak when option parsing failed by @ChoKyuWon in #1823
- arch/riscv64: Add basic mcount tracing support for RISC-V 64bit by @gichoel in #1815
- explicit python3 instead of python2 support by @RobertBerger in #1831
- replay: Revise the logic of setting NEEDS_PAREN to correctly add parentheses by @jyf111 in #1832
- build: Fix build errors due to low kernel version by @MichelleJin12 in #1838
- build: Fix compile warning message by @keepgoingxxx in #1768
- uftrace: Add help message for make by @kangtegong in #1842
- misc: Enhance and rename wget-pr script by @kangtegong in #1844
- mcount: Restore/reset rstack only when the return address is hijacked by @jyf111 in #1841
- README.md: Fix duplicated "with" by @bernhardkaindl in #1668
- doc: Fix typos and improve language in README.md by @bernhardkaindl in #1669
- Fix broken kernel tracing in presence of offline CPUs by @shoffmeister in #1849
- uftrace: Fix dead store warnings found by infer by @paranlee in #1757
- utils: Fix warnings implicit declaration of function 'close' by @paranlee in #1860
- libmcount: Remove UFTRACE_PIPE related code by @honggyukim in #1871
- utils: Fix incorrect header includes by @honggyukim in #1872
- utils: Add DTRAP macro and use it in pr_err by @honggyukim in #1854
- New release v0.15 by @namhyung in #1863
New Contributors
- @licy183 made their first contribution in #1737
- @kang-hyuck made their first contribution in #1765
- @coyotek made their first contribution in #1771
- @jyf111 made their first contribution in #1780
- @haileynam made their first contribution in #1783
- @mirusu400 made their first contribution in #1760
- @gichoel made their first contribution in #1762
- @jigsaw-0 made their first contribution in #1790
- @jeonghwanin made their first contribution in #1806
- @sypark9646 made their first contribution in #1807
- @SEOKMIN83 made their first contribution in #1788
- @oldiob made their first contribution in #1798
- @RobertBerger made their first contribution in #1831
- @keepgoingxxx made their first contribution in #1768
- @shoffmeister made their first contribution in #1849
Full Changelog: v0.14...v0.15
uftrace v0.14
Release note
This release comes with new cool features and bug fixes.
Python tracing support
The first thing is Python language support! Now uftrace can trace python functions and methods like C/C++ functions. Internally, it uses python's sys.setprofile()
and pass the entry/exit info to the libmcount.
For example, it can trace the following python script (it needs to be a standalone executable - it should have #!
line and executable permission).
$ cat abc.py
#! /usr/bin/python3
def a(): b()
def b(): c()
def c(): print("Hello")
if __name__ == '__main__':
a()
$ chmod +x abc.py
Then uftrace can trace the functions like below:
$ uftrace abc.py
Hello
# DURATION TID FUNCTION
[235209] | __main__.<module>() {
[235209] | a() {
[235209] | b() {
[235209] | c() {
10.810 us [235209] | builtins.print();
14.926 us [235209] | } /* c */
16.628 us [235209] | } /* b */
18.867 us [235209] | } /* a */
22.000 us [235209] | } /* __main__.<module> */
Not all features work well with python scripts, but filters by name (-F
and -N
), depth (-D
), time (-t
), location (-L
) would work. However you can use full features for analysis after recording the data.
Runtime control with agent
The next is the improved agent control. The agent listens to a client connection in background when started with -g
option. Then users can connect to it with uftrace live using -p <PID>
option. The should be a process ID of the target, not the uftrace itself.
Say we want to trace my program with a filter at first. Please don't forget to start an agent.
$ uftrace record -g -F ^mycode -- myprog
Later we don't want to use the function filter anymore, and decided to use a time filter instead. Let's change the option for the uftrace record like below:
$ uftrace -p $(pidof myprog) -F ^mycode@clear -t 100us
Note that the above command would not produce any data and just pass the new options to the existing uftrace record session (for myprog).
Android (AOSP) build support
One more big thing is Android build support. While it's not officially supported, you can build uftrace as an external tool. This needed various improvements in terms of portability like abstracting shmem access and better handling of the tmp directory and dynamic linker behaviors.
It has been tested with Android 9+ on AArch64 and x86_64. You probably want to use dynamic tracing due to issues with the Android runtime. Please see INSTALL.md for the details.
Other important changes
The size filter at replay now works as same as record, since the symbol file format was changed to save the symbol size as well.
Symbol demangling on Rust programs was improved to handle trait names in a more compact way. The new demangling scheme (v0) is not supported yet.
There are also more fixes and improvements. Thank you all for making uftrace more useful, efficient and portable!
Full change list
- Enable testing of -fpatchable-function-entry instrumentation. by @yugr in #1614
- build: Add DEBUG=2 build option for macro debugging by @honggyukim in #1621
- Read patchable entries from memory instead of disk by @yugr in #1623
- demangle: More elaborated demangling for Rust by @ChoKyuWon in #1625
- uftrace: Port to Android x86_64/AArch64. by @yugr in #1605
- libmcount: Turn off unexpected vectorization in libmcount by @honggyukim in #1632
- uftrace: Modify install location for uftrace libraries by @kangtegong in #1633
- tests: Fix multiple issues in runtest.py by @honggyukim in #1628
- pre-commit: Fix RuntimeError in isort hook by @honggyukim in #1634
- tests: Fix t191_posix_spawn.py by @honggyukim in #1636
- x86_64: Fix an error in s-nested.c with -fpatchable-function-entry by @honggyukim in #1637
- tests: Fix t135_trigger_time2.py test by @honggyukim in #1638
- unittest: Fix c99 compiler error by @clementguidi in #1642
- Catch IndexError from self.sort in test/runtest.py by @bernhardkaindl in #1655
- misc: Add more prototypes enums for socket by @honggyukim in #1656
- README.md: Add links to command-specific documentation by @bernhardkaindl in #1657
- aarch64/runtest.py: Fix tests where gcc/clang emits memcpy() by @bernhardkaindl in #1659
- doc/uftrace.md: Add a common list of all options (generated from -h) by @bernhardkaindl in #1658
- cmd/recv.c: Migrate from deprecated gethostbyname() to getaddrinfo() by @bernhardkaindl in #1661
- tui: Change the loading message for report mode by @qpakzk in #1666
- README.md: Update the introduction to uftrace by @bernhardkaindl in #1653
- README.md: Improve paragraph on features regarding recorded trace data by @bernhardkaindl in #1670
- Allow customizing the bash completions dir for system-RPM installs by @bernhardkaindl in #1654
- doc/uftrace-info.md: Improve the description of info --symbols by @bernhardkaindl in #1663
- Implement client/agent protocol by @clementguidi in #1665
- kernel: Add "exit_to_user_mode_prepare" in kernel skip list by @honggyukim in #1677
- mcount: Add RCU-like capabilities to the rbtree by @clementguidi in #1678
- dynamic: Print dynamic patch stats for skipped by @honggyukim in #1675
- python: Fix source location missing problem by @honggyukim in #1686
- mcount: Toggle tracing at runtime by @clementguidi in #1643
- dynamic: x86_64: Do not allow ret insn for patch target by @honggyukim in #1701
- fix: #1690 unable to identify shebang when it has initial spaces by @yihong0618 in #1697
- Fix #1707 x86 build by @yihong0618 in #1708
- mcount: Update time and depth filters at runtime by @clementguidi in #1644
- compile: Fix compile error due to low libcapstone-dev package version by @MichelleJin12 in #1713
- Control name filters at runtime by @clementguidi in #1645
- mcount: remove variable declaration-after-statement by @paranlee in #1718
- uftrace: Add 'void' to functions without arguments by @paranlee in #1720
- python: Handle os._exit() properly by @honggyukim in #1725
- doc: Describe agent usage by @clementguidi in #1715
- Control triggers at runtime by @clementguidi in #1646
- filter: Cleanup debug code by @clementguidi in #1731
- doc: Add a python function tracing section in slide by @honggyukim in #1732
- doc: Add discord badge at the top of README.md by @honggyukim in #1733
- New release: v0.14 by @namhyung in #1714
New Contributors
- @ChoKyuWon made their first contribution in #1625
- @yihong0618 made their first contribution in #1697
Full Changelog: v0.13.1...v0.14
uftrace v0.13
I'm happy to announce that uftrace v0.13 is released.
You can get it from the below link:
https://github.com/namhyung/uftrace/releases/tag/v0.13
As usual, this release contains new features and many bug fixes.
This release comes with a couple of new filtering options. The first one
is the location filter. The -L or --loc-filter option can specify names
of directory or file for the source code. That means the binary should
have the debug information (DWARF). Since uftrace saves the (reduced
form of) debug info separately, we can use this option at replay as well.
$ uftrace -L myfile.c myprog
The above will show functions only in the 'myfile.c' file. You can also
use directory names and mix the two. When you use a directory name, it
will match all files under the directory. And the regex or the wildcard
patterns can be used for more fine-grainded filtering.
The next one is the size filter using -Z or --size-filter option.
Actually this is not a new addition, we had it for the dynamic tracing.
But now we can use it as a general filter regardless if you use the
dynamic tracing or not.
$ uftrace -Z 100 myprog
The above will show functions that their size is greater than equal to
100 bytes. At record (or in live command), it can read the size from
the ELF symbol table directly. When you use the option during replay
(or report and so on), it determines the size from the symbol file in
the uftrace data.
But it can have a small difference than the original symbol size
(usually bigger than the original). This is because the symbol file
doesn't actually save the size of functions. It currently saves the
symbol addresses only and function size is calculated as a difference
between the two adjacent fucntions. If your compiler added some
paddings at the end of the function (to aligned the function start
address), it'll have a different size. Please be aware of that when
using it from replay.
To check the size in the symbol file, you can use 'size' field in the
uftrace report output.
$ uftrace report -f size
This will show the size of functions (saved in the uftrace data).
The uftrace dump got --mermaid
option to produce the mermaid format
[1] for visualizing function call graphs. Also it supports to change
the base function of the graph interactively.
The --no-sched-preempt option is to suppress schedule events only if
it's pre-empted. So the voluntary schedules will be shown.
And we added many testing/CI infra changes thanks for Github actions.
I appreciate Travis CI team for the works so far but decided to move.
Finally, it added the preliminary support for running an agent in
background. It does nothing as of now, but it will talk to external
uftrace processes via a unix socket to control the tracing behavior
later. The uftrace live got -p option to specify the pid of the
original process with the agent.
There are many more things. Thank you all for making uftrace more
useful, efficient and portable!