Signed-off-by: Martin Kletzander <mkletzan@xxxxxxxxxx> --- examples/systemtap/lock-debug.stp | 115 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 examples/systemtap/lock-debug.stp diff --git a/examples/systemtap/lock-debug.stp b/examples/systemtap/lock-debug.stp new file mode 100644 index 0000000..bf18bc6 --- /dev/null +++ b/examples/systemtap/lock-debug.stp @@ -0,0 +1,115 @@ +#!/usr/bin/stap --ldd -d /usr/sbin/libvirtd -c libvirtd +# +# Usage with installed libvirt daemon: +# stap --ldd -d /usr/sbin/libvirtd -c libvirtd \ +# lock-debug.stp /usr/lib/libvirt.so +# +# If made executable; simple './lock-debug.stp' should work too. +# +# TODO: Document usage with uninstalled daemon and libs. +# Assuming CWD is toplevel source git directory, it should be only +# slight modification to the following: +# +# ./run stap --ldd -c daemon/libvirtd -d daemon/libvirtd +# examples/systemtap/lock-debug.stp src/.libs/libvirt.so +# +# Author: Martin Kletzander <mkletzan@xxxxxxxxxx> + +global mx_tolock +global mx_locked + + +function filter() +{ + if (pid() != target()) + return 1 + + return 0 +} + +probe library = process( %( $# > 0 %? @1 %: "/usr/lib/libvirt.so" %) ) +{ + if (filter()) next +} + +probe lock = library.function("virMutexLock") +{ + lockname = usymdata($m) +} + +probe unlock = library.function("virMutexUnlock") +{ + lockname = usymdata($m) +} + +probe begin +{ + %( $# > 1 %? println("error: Too many parameters"); exit(); + %: print("Started, press ^C when the proccess hangs\n"); %) +} + +probe lock.call +{ + mx_tolock[lockname, tid()] = sprint_ubacktrace() +} + +probe lock.return +{ + if ([lockname, tid()] in mx_tolock) { + mx_locked[lockname, tid()] = mx_tolock[lockname, tid()] + delete mx_tolock[lockname, tid()] + } else { + printf("internal error: lock acquired unwillingly?\n") + } +} + +probe unlock.return +{ + found = 0 + + foreach ([lock, tid] in mx_locked) { + if (lock != lockname) + continue + if (tid != tid()) { + printf("Warning: lock released on different thread that locked it.\n"); + printf("Lock trace:\n%s\n", mx_locked[lock, tid]) + printf("Unlock trace:\n%s\n", sprint_ubacktrace()) + } + + found = tid + break + } + + if (found) { + if ([lockname, found] in mx_locked) + delete mx_locked[lockname, found] + else + println("FDSA") + } else { + printf("Warning: lock released without being locked.\n") + printf("Unlock trace:\n%s\n", sprint_ubacktrace()) + } +} + +probe end +{ + printf("\n=============\n") + + tmp = 0; + foreach (bt = [lock, tid] in mx_locked) { + if (!tmp++) + printf("The following locks are locked:\n") + printf("%s(%d):\n%s\n---\n", lock, tid, bt) + } + if (!tmp) + printf("No locks are locked, apparently\n") + + tmp = 0; + foreach (bt = [lock, tid] in mx_tolock) { + if (!tmp++) + printf("The following locks are waiting to be acquired:\n") + printf("%s(%d):\n%s\n---\n", lock, tid, bt) + } + if (!tmp) + printf("No locks are being acquired, apparently\n") +} -- 2.1.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list