想必大家都用过内核态的lockdep,它有死锁预测的功能。能够在运行态动态地去识别一些潜在的、发生概率较小的(也许一辈子都很难碰到)死锁风险。目前有人把它移植到了用户,并加入到内核主线($root/tools/lib/lockdep)
笔者这里想讲的是它的“移植”方法非常得巧妙,请看看$root/tools/lib/lockdep/lockdep.c的主体函数:
-
#include <linux/lockdep.h>
-
#include "../../../kernel/locking/lockdep.c"
你没看错,它真的只有2行,从它的路径上看,它是直接借用了内核的lockdep.c。也就是说以后内核的lockdep.c修复了bugfix或实现新的功能,用户态工具也可以直接受益,而几乎不用修改一行代码(下文看到,其实新的桩是需要打的)。
原来作者的思路不是移植,而是完全借用内核的算法,因为lockdep是相对算法化的。而依赖的内核函数,作者都全部做了一些假的打桩,让lockdep主体功能以为自己是在内核环境运行。虽然文件不少,但是基本上都是通过预编译把它们给去掉。
-
path: root/tools/lib/lockdep/uinclude/linux
-
Mode Name Size
-
-rw-r--r-- bitops.h 19 logstatsplain
-
-rw-r--r-- compiler.h 146 logstatsplain
-
-rw-r--r-- debug_locks.h 221 logstatsplain
-
-rw-r--r-- delay.h 19 logstatsplain
-
-rw-r--r-- export.h 139 logstatsplain
-
-rw-r--r-- ftrace.h 19 logstatsplain
-
-rw-r--r-- gfp.h 19 logstatsplain
-
-rw-r--r-- hardirq.h 241 logstatsplain
-
-rw-r--r-- hash.h 41 logstatsplain
-
-rw-r--r-- interrupt.h 19 logstatsplain
-
-rw-r--r-- irqflags.h 1347 logstatsplain
-
-rw-r--r-- kallsyms.h 551 logstatsplain
-
-rw-r--r-- kern_levels.h 915 logstatsplain
-
-rw-r--r-- kernel.h 1076 logstatsplain
-
-rw-r--r-- kmemcheck.h 168 logstatsplain
-
-rw-r--r-- linkage.h 19 logstatsplain
-
-rw-r--r-- list.h 41 logstatsplain
-
-rw-r--r-- lockdep.h 1010 logstatsplain
-
-rw-r--r-- module.h 120 logstatsplain
-
-rw-r--r-- mutex.h 19 logstatsplain
-
-rw-r--r-- poison.h 43 logstatsplain
-
-rw-r--r-- prefetch.h 149 logstatsplain
-
-rw-r--r-- proc_fs.h 19 logstatsplain
-
-rw-r--r-- rbtree.h 43 logstatsplain
-
-rw-r--r-- rbtree_augmented.h 77 logstatsplain
-
-rw-r--r-- rcu.h 277 logstatsplain
-
-rw-r--r-- seq_file.h 19 logstatsplain
-
-rw-r--r-- spinlock.h 484 logstatsplain
-
-rw-r--r-- stacktrace.h 639 logstatsplain
-
-rw-r--r-- stringify.h 161 logstatsplain
-
-rw-r--r-- types.h 966 logstatsplain
-
# define trace_hardirq_context(p) 0
-
# define trace_softirq_context(p) 0
-
# define trace_hardirqs_enabled(p) 0
-
# define trace_softirqs_enabled(p) 0
-
# define trace_hardirq_enter() do { } while (0)
-
# define trace_hardirq_exit() do { } while (0)
-
# define lockdep_softirq_enter() do { } while (0)
-
# define lockdep_softirq_exit() do { } while (0)
-
# define INIT_TRACE_IRQFLAGS
-
-
# define stop_critical_timings() do { } while (0)
-
# define start_critical_timings() do { } while (0)
-
-
#define raw_local_irq_disable() do { } while (0)
-
#define raw_local_irq_enable() do { } while (0)
-
#define raw_local_irq_save(flags) ((flags) = 0)
-
#define raw_local_irq_restore(flags) do { } while (0)
-
#define raw_local_save_flags(flags) ((flags) = 0)
-
#define raw_irqs_disabled_flags(flags) do { } while (0)
-
#define raw_irqs_disabled() 0
-
#define raw_safe_halt()
用户态lockdep是一个lib库,已经可以用来检测用户态的pthread_mutex以及pthread_rwlock 2种锁,是通过LD_PRELOAD的方式来截获glibc的调用。从代码量来看,这个文件其实才是整个lib的主要代码,后续可以通过修改这个文件扩展实现监控其它更多的锁。(参考$root/tools/lib/lockdep/
preload.c)。
除此之外,库还可以脱离内核代码主线进行编译,具体更多信息,请参考。
你还在犹豫么?赶紧去试试吧。:)
(备注:文中参考路径root=)
阅读(4760) | 评论(1) | 转发(0) |