[libvirt] [PATCH 1/2] lock-debug.stp

Martin Kletzander mkletzan at redhat.com
Mon Sep 8 14:17:45 UTC 2014


Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
---
 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 at redhat.com>
+
+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




More information about the libvir-list mailing list