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
- make uftrace more friendly to daemon programs by @shen390s in #1883
- info: Add utc_offset info for external usage by @honggyukim in #1923
- cmds: static variable used stack after return by @yskelg in #1924
- doc: Add packaging status in README.md by @MichelleJin12 in #1929
- uftrace: Align exact argument on calloc by @yskelg in #1936
- doc: Fix redundant 'the' in readme.md by @vimkim in #1931
- misc: Add -h/--help options and end marker to demangler_options by @kangtegong in #1940
- uftrace: Add sub-command specific help by @ParkSeungHyeok in #1946
- misc: Add checkout-pr.sh script for easier checkout by @honggyukim in #1947
- record: Fix crash when the root is not existed by @zyxeeker in #1979
- Release v0.17 by @namhyung in #1984
New Contributors
- @yskelg made their first contribution in #1924
- @vimkim made their first contribution in #1931
- @ParkSeungHyeok made their first contribution in #1946
- @zyxeeker made their first contribution in #1979
Full Changelog: v0.16...v0.17