想必大家都用過內核態的lockdep,它有死鎖預測的功能。能夠在運行態動態地去識別一些潛在的、發生概率較小的(也許一輩子都很難碰到)死鎖風險。目前有人把它移植到了用戶,並加入到內核主線($root/tools/lib/lockdep)
你沒看錯,它真的只有2行,從它的路徑上看,它是直接借用了內核的lockdep.c。也就是說以後內核的lockdep.c修復了bugfix或實現新的功能,用戶態工具也可以直接受益,而幾乎不用修改一行代碼(下文看到,其實新的樁是需要打的)。
原來作者的思路不是移植,而是完全借用內核的算法,因爲lockdep是相對算法化的。而依賴的內核函數,作者都全部做了一些假的打樁,讓lockdep主體功能以爲自己是在內核環境運行。雖然文件不少,但是基本上都是通過預編譯把它們給去掉。
用戶態lockdep是一個lib庫,已經可以用來檢測用戶態的pthread_mutex以及pthread_rwlock 2種鎖,是通過LD_PRELOAD的方式來截獲glibc的調用。從代碼量來看,這個文件其實才是整個lib的主要代碼,後續可以通過修改這個文件擴展實現監控其它更多的鎖。(參考$root/tools/lib/lockdep/preload.c)。
除此之外,庫還可以脫離內核代碼主線進行編譯,具體更多信息,請參考http://lwn.net/Articles/536363/。
你還在猶豫麼?趕緊去試試吧。:)
(備註:文中參考路徑root=https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/)
筆者這裏想講的是它的“移植”方法非常得巧妙,請看看$root/tools/lib/lockdep/lockdep.c的主體函數:
-
#include <linux/lockdep.h>
- #include "../../../kernel/locking/lockdep.c"
原來作者的思路不是移植,而是完全借用內核的算法,因爲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()
除此之外,庫還可以脫離內核代碼主線進行編譯,具體更多信息,請參考http://lwn.net/Articles/536363/。
你還在猶豫麼?趕緊去試試吧。:)
(備註:文中參考路徑root=https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/)