All of lore.kernel.org
 help / color / mirror / Atom feed
From: tip-bot for Sasha Levin <sasha.levin@oracle.com>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, sasha.levin@oracle.com,
	hpa@zytor.com, mingo@kernel.org, a.p.zijlstra@chello.nl,
	torvalds@linux-foundation.org, akpm@linux-foundation.org,
	tglx@linutronix.de
Subject: [tip:core/locking] liblockdep: Support using LD_PRELOAD
Date: Mon, 11 Feb 2013 04:31:23 -0800	[thread overview]
Message-ID: <tip-eb1aa2ea7da68149bd9ec4491379a81277127ac0@git.kernel.org> (raw)
In-Reply-To: <1360456781-32462-9-git-send-email-sasha.levin@oracle.com>

Commit-ID:  eb1aa2ea7da68149bd9ec4491379a81277127ac0
Gitweb:     http://git.kernel.org/tip/eb1aa2ea7da68149bd9ec4491379a81277127ac0
Author:     Sasha Levin <sasha.levin@oracle.com>
AuthorDate: Sat, 9 Feb 2013 19:39:39 -0500
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 11 Feb 2013 10:12:40 +0100

liblockdep: Support using LD_PRELOAD

This allows lockdep to be used without being compiled in the
original program.

Usage is quite simple:

	LD_PRELOAD=/path/to/liblockdep.so /path/to/my/program

And magically, you'll have lockdep checking in your program!

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: jamie.iles@oracle.com
Cc: penberg@kernel.org
Cc: acme@ghostprotocols.net
Cc: paulus@samba.org
Cc: namhyung@kernel.org
Cc: peterz@infradead.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1360456781-32462-9-git-send-email-sasha.levin@oracle.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/lib/lockdep/Makefile  |   4 +-
 tools/lib/lockdep/preload.c | 209 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 211 insertions(+), 2 deletions(-)

diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
index e82ffe9..245f8ba 100644
--- a/tools/lib/lockdep/Makefile
+++ b/tools/lib/lockdep/Makefile
@@ -143,7 +143,7 @@ do_app_build =						\
 
 do_compile_shared_library =			\
 	($(print_shared_lib_compile)		\
-	$(CC) --shared $^ -o $@)
+	$(CC) --shared -ldl $^ -o $@)
 
 do_build_static_lib =				\
 	($(print_static_lib_build)		\
@@ -161,7 +161,7 @@ $(obj)/%.o: $(src)/%.c
 %.o: $(src)/%.c
 	$(Q)$(call do_compile)
 
-PEVENT_LIB_OBJS = common.o lockdep.o
+PEVENT_LIB_OBJS = common.o lockdep.o preload.o rbtree.o
 
 ALL_OBJS = $(PEVENT_LIB_OBJS)
 
diff --git a/tools/lib/lockdep/preload.c b/tools/lib/lockdep/preload.c
new file mode 100644
index 0000000..b65a3f3
--- /dev/null
+++ b/tools/lib/lockdep/preload.c
@@ -0,0 +1,209 @@
+#define _GNU_SOURCE
+#include <pthread.h>
+#include <stdio.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include "include/liblockdep/mutex.h"
+#include "../../../include/linux/rbtree.h"
+
+struct lock_lookup {
+	void *orig;
+	struct lockdep_map dep_map;
+	struct rb_node node;
+};
+
+struct rb_root locks = RB_ROOT;
+
+int (*ll_pthread_mutex_init)(pthread_mutex_t *mutex,
+			const pthread_mutexattr_t *attr);
+int (*ll_pthread_mutex_lock)(pthread_mutex_t *mutex);
+int (*ll_pthread_mutex_trylock)(pthread_mutex_t *mutex);
+int (*ll_pthread_mutex_unlock)(pthread_mutex_t *mutex);
+int (*ll_pthread_mutex_destroy)(pthread_mutex_t *mutex);
+
+int (*ll_pthread_rwlock_init)(pthread_rwlock_t *rwlock,
+			const pthread_rwlockattr_t *attr);
+int (*ll_pthread_rwlock_destroy)(pthread_rwlock_t *rwlock);
+int (*ll_pthread_rwlock_rdlock)(pthread_rwlock_t *rwlock);
+int (*ll_pthread_rwlock_tryrdlock)(pthread_rwlock_t *rwlock);
+int (*ll_pthread_rwlock_trywrlock)(pthread_rwlock_t *rwlock);
+int (*ll_pthread_rwlock_wrlock)(pthread_rwlock_t *rwlock);
+int (*ll_pthread_rwlock_unlock)(pthread_rwlock_t *rwlock);
+
+static void init_preload();
+
+static struct lock_lookup *__get_lock(void *lock)
+{
+	struct rb_node **node = &locks.rb_node, *parent = NULL;
+	struct lock_lookup *l;
+
+	while (*node) {
+		l = rb_entry(*node, struct lock_lookup, node);
+
+		parent = *node;
+		if (lock < l->orig)
+			node = &l->node.rb_left;
+		else if (lock > l->orig)
+			node = &l->node.rb_right;
+		else
+			return l;
+	}
+
+	l = malloc(sizeof(*l));
+	if (l == NULL)
+		return NULL;
+
+	*l = (struct lock_lookup) {
+		.orig = lock,
+		.dep_map = STATIC_LOCKDEP_MAP_INIT("lock", &l->dep_map),
+	};
+
+	rb_link_node(&l->node, parent, node);
+	rb_insert_color(&l->node, &locks);
+
+	return l;
+}
+
+int pthread_mutex_init(pthread_mutex_t *mutex,
+			const pthread_mutexattr_t *attr)
+{
+	init_preload();
+
+	__get_lock(mutex);
+	return ll_pthread_mutex_init(mutex, attr);
+}
+
+int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+	void *ip = _THIS_IP_;
+
+        init_preload();
+
+	lock_acquire(&__get_lock(mutex)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)ip);
+	return ll_pthread_mutex_lock(mutex);
+}
+
+int pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+	void *ip = _THIS_IP_;
+
+        init_preload();
+
+	lock_acquire(&__get_lock(mutex)->dep_map, 0, 1, 0, 2, NULL, (unsigned long)ip);
+	return ll_pthread_mutex_trylock(mutex);
+}
+
+int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+	void *ip = _THIS_IP_;
+
+        init_preload();
+
+	lock_release(&__get_lock(mutex)->dep_map, 0, (unsigned long)ip);
+	return ll_pthread_mutex_unlock(mutex);
+}
+
+int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+	struct lock_lookup *l = __get_lock(mutex);
+
+        init_preload();
+
+	rb_erase(&l->node, &locks);
+	free(l);
+	return ll_pthread_mutex_destroy(mutex);
+}
+
+int pthread_rwlock_init(pthread_rwlock_t *rwlock,
+			const pthread_rwlockattr_t *attr)
+{
+        init_preload();
+
+	__get_lock(rwlock);
+	return ll_pthread_rwlock_init(rwlock, attr);
+}
+
+int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
+{
+	struct lock_lookup *l = __get_lock(rwlock);
+
+        init_preload();
+
+	rb_erase(&l->node, &locks);
+	free(l);
+	return ll_pthread_rwlock_destroy(rwlock);
+}
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
+{
+	void *ip = _THIS_IP_;
+
+        init_preload();
+
+	lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 2, 2, NULL, (unsigned long)ip);
+	return ll_pthread_rwlock_rdlock(rwlock);
+}
+
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
+{
+	void *ip = _THIS_IP_;
+
+        init_preload();
+
+	lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 2, 2, NULL, (unsigned long)ip);
+	return ll_pthread_rwlock_tryrdlock(rwlock);
+}
+
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
+{
+	void *ip = _THIS_IP_;
+
+        init_preload();
+
+	lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 0, 2, NULL, (unsigned long)ip);
+	return ll_pthread_rwlock_trywrlock(rwlock);
+}
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
+{
+	void *ip = _THIS_IP_;
+
+        init_preload();
+
+	lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)ip);
+	return ll_pthread_rwlock_wrlock(rwlock);
+}
+
+int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
+{
+	void *ip = _THIS_IP_;
+
+        init_preload();
+
+	lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)ip);
+	return ll_pthread_rwlock_unlock(rwlock);
+}
+
+__attribute__((constructor)) static void init_preload(void)
+{
+	static bool preload_done;
+
+	if (preload_done)
+		return;
+
+	ll_pthread_mutex_init = dlsym(RTLD_NEXT, "pthread_mutex_init");
+	ll_pthread_mutex_lock = dlsym(RTLD_NEXT, "pthread_mutex_lock");
+	ll_pthread_mutex_trylock = dlsym(RTLD_NEXT, "pthread_mutex_trylock");
+	ll_pthread_mutex_unlock = dlsym(RTLD_NEXT, "pthread_mutex_unlock");
+	ll_pthread_mutex_destroy = dlsym(RTLD_NEXT, "pthread_mutex_destroy");
+
+	ll_pthread_rwlock_init = dlsym(RTLD_NEXT, "pthread_rwlock_init");
+	ll_pthread_rwlock_destroy = dlsym(RTLD_NEXT, "pthread_rwlock_destroy");
+	ll_pthread_rwlock_rdlock = dlsym(RTLD_NEXT, "pthread_rwlock_rdlock");
+	ll_pthread_rwlock_tryrdlock = dlsym(RTLD_NEXT, "pthread_rwlock_tryrdlock");
+	ll_pthread_rwlock_wrlock = dlsym(RTLD_NEXT, "pthread_rwlock_wrlock");
+	ll_pthread_rwlock_trywrlock = dlsym(RTLD_NEXT, "pthread_rwlock_trywrlock");
+	ll_pthread_rwlock_unlock = dlsym(RTLD_NEXT, "pthread_rwlock_unlock");
+
+	preload_done = true;
+}

  reply	other threads:[~2013-02-11 12:31 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-10  0:39 [PATCH v2 01/11] liblockdep: remove the need for liblockdep_init Sasha Levin
2013-02-10  0:39 ` [PATCH v2 02/11] liblockdep: remove the need for liblockdep_set_thread Sasha Levin
2013-02-11 12:22   ` [tip:core/locking] liblockdep: Remove the need for liblockdep_set_thread() tip-bot for Sasha Levin
2013-02-10  0:39 ` [PATCH v2 03/11] perf: stop using liblockdep_init and liblockdep_set_thread Sasha Levin
2013-02-11 12:23   ` [tip:core/locking] perf: Stop using liblockdep_init() and liblockdep_set_thread() tip-bot for Sasha Levin
2013-02-10  0:39 ` [PATCH v2 04/11] liblockdep: fix AA test Sasha Levin
2013-02-11 12:24   ` [tip:core/locking] liblockdep: Fix the AA locking test tip-bot for Sasha Levin
2013-02-10  0:39 ` [PATCH v2 05/11] liblockdep: correct the ABCDBCDA test Sasha Levin
2013-02-11 12:25   ` [tip:core/locking] liblockdep: Correct " tip-bot for Sasha Levin
2013-02-10  0:39 ` [PATCH v2 06/11] liblockdep: rbtree support Sasha Levin
2013-02-11 12:27   ` [tip:core/locking] liblockdep: Add " tip-bot for Sasha Levin
2013-02-10  0:39 ` [PATCH v2 07/11] liblockdep: prevent multiple declarations of CALLER_ADDR0 Sasha Levin
2013-02-11 12:28   ` [tip:core/locking] liblockdep: Prevent " tip-bot for Sasha Levin
2013-02-10  0:39 ` [PATCH v2 08/11] liblockdep: keep headers declarations even if lib is disabled Sasha Levin
2013-02-11 12:30   ` [tip:core/locking] liblockdep: Keep header declarations even if the library " tip-bot for Sasha Levin
2013-02-10  0:39 ` [PATCH v2 09/11] liblockdep: support using LD_PRELOAD Sasha Levin
2013-02-11 12:31   ` tip-bot for Sasha Levin [this message]
2013-02-10  0:39 ` [PATCH v2 10/11] liblockdep: add tests for the LD_PRELOAD feature Sasha Levin
2013-02-11 12:32   ` [tip:core/locking] liblockdep: Add " tip-bot for Sasha Levin
2013-02-10  0:39 ` [PATCH v2 11/11] liblockdep: preload helper Sasha Levin
2013-02-11 12:33   ` [tip:core/locking] liblockdep: Add the 'lockdep' user-space utility tip-bot for Sasha Levin
2013-02-11 12:21 ` [tip:core/locking] liblockdep: Remove the need for liblockdep_init() tip-bot for Sasha Levin
2013-02-19  7:58 ` [liblockdep] Re: [PATCH v2 01/11] liblockdep: remove the need for liblockdep_init Ingo Molnar
2013-02-20 15:05   ` Sasha Levin
2013-02-20 15:46     ` Ingo Molnar
2013-02-20 16:12       ` Sasha Levin
  -- strict thread matches above, loose matches on Subject: below --
2013-06-13 22:41 [Patch v5 7/9] liblockdep: Support using LD_PRELOAD Sasha Levin
2013-11-27 14:09 ` [tip:core/locking] " tip-bot for Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tip-eb1aa2ea7da68149bd9ec4491379a81277127ac0@git.kernel.org \
    --to=sasha.levin@oracle.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=akpm@linux-foundation.org \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.