Skip to content

uftrace v0.17

Latest
Compare
Choose a tag to compare
@namhyung namhyung released this 17 Dec 06:42

New features

One notable change is the watchpoint support for global variables.
This is still very limited but users can track changes of the given
variable at the entry and the exit of each function. Please keep in
mind that it doesn't use hardware debug registers and checks the value
in softwawre. Currently it can only handle integer types.

This is an example output of trivial test program called 'watchy'
which changes a variable called 'global' multiple times.

$ uftrace -W var:global ./watchy
# DURATION     TID      FUNCTION
            [2736290] | main() {
            [2736290] |   /* watch:var (global=1) */
            [2736290] |   foo() {
            [2736290] |     /* watch:var (global=2) */
            [2736290] |     bar() {
            [2736290] |       /* watch:var (global=3) */
   0.142 us [2736290] |     } /* bar */
            [2736290] |     /* watch:var (global=4) */
   3.523 us [2736290] |   } /* foo */
            [2736290] |   /* watch:var (global=5) */
  24.555 us [2736290] | } /* main */

Another important improvement is the dlopen support. From now on, it
can capture arguments and return values as well as other debug info such
as srcline.

The below test program opens two libraries with dlopen(3) and calls
functions in them. The lib_[abc] and foo are from the libraries and you
can see the arguments the source code information.

$ uftrace -a --srcline ./t-dlopen 
# DURATION     TID      FUNCTION [SOURCE]
   0.747 us [2737082] | __monstartup();
   0.374 us [2737082] | __cxa_atexit();
            [2737082] | main(1, 0x7ffed8abe788) { /* s-dlopen.c:5 */
            [2737082] |   dlopen("./libabc_test_lib.so", RTLD_LAZY) {
   1.000  s [2737082] |     /* linux:schedule */
   1.004  s [2737082] |   } = 0x55eb7cb474c0; /* dlopen */
  11.505 us [2737082] |   dlsym(0x55eb7cb474c0, "lib_a") = &lib_a;
            [2737082] |   lib_a(1) { /* s-lib.c:10 */
            [2737082] |     lib_b(2) { /* s-lib.c:15 */
   4.867 us [2737082] |       lib_c(1) = 0; /* s-lib.c:20 */
   6.624 us [2737082] |     } = 1; /* lib_b */
   7.875 us [2737082] |   } = 0; /* lib_a */
  98.767 us [2737082] |   dlclose(0x55eb7cb474c0) = 0;
            [2737082] |   dlopen("./libfoo.so", RTLD_LAZY) {
   1.000  s [2737082] |     /* linux:schedule */
   1.015  s [2737082] |   } = 0x55eb7cb474c0; /* dlopen */
   9.467 us [2737082] |   dlsym(0x55eb7cb474c0, "foo") = &foo;
            [2737082] |   foo(1) { /* s-libfoo.cpp:12 */
   0.285 us [2737082] |     AAA::bar(1);
   5.261 us [2737082] |   } /* foo */
  95.406 us [2737082] |   dlclose(0x55eb7cb474c0) = 0;
   2.020  s [2737082] | } = 0; /* main */

But this also comes with a cost. Now it needs to exchange the internal
data structure to track arguments and others when dlopen is called. For
now it needs to wait for 1 second before releasing the old one.

What's Changed

New Contributors

Full Changelog: v0.16...v0.17