Skip to content

Releases: namhyung/uftrace

uftrace v0.16

25 Apr 03:49
Compare
Choose a tag to compare

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

New Contributors

Full Changelog: v0.15...v0.16

uftrace v0.15.2

25 Jan 05:47
Compare
Choose a tag to compare

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

uftrace v0.15.1

12 Jan 23:53
Compare
Choose a tag to compare

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

08 Jan 03:57
Compare
Choose a tag to compare

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

New Contributors

Full Changelog: v0.14...v0.15

uftrace v0.14

20 Jun 06:09
Compare
Choose a tag to compare

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

New Contributors

Full Changelog: v0.13.1...v0.14

uftrace v0.13

09 Jan 06:52
Compare
Choose a tag to compare

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!

[1] https://mermaid-js.github.io