Clojure世界:利用HouseMD诊断clojure (二)

2014-11-24 08:17:13 · 作者: · 浏览: 1
s null
core$loop.getRequiredArity() sun.misc.Launcher$AppClassLoader@a6eb38a 0 -ms null

INFO : Ended by timeout
INFO : reset class clojure.core$loop

在5秒内,clojure.core$loop类有两个方法各被调用了5次,doInvoke是实际的调用,而getRequiredArity用来查询loop所需要的参数个数。trace还可以跟踪到具体的方法,例如我们跟踪prn函数的调用情况:
housemd> trace -t 5 core$prn.doInvoke
INFO : probe class clojure.core$prn
core$prn.doInvoke(Object) sun.misc.Launcher$AppClassLoader@a6eb38a 1 1ms clojure.core$prn@3e4ac866

core$prn.doInvoke(Object) sun.misc.Launcher$AppClassLoader@a6eb38a 2 <1ms clojure.core$prn@3e4ac866

core$prn.doInvoke(Object) sun.misc.Launcher$AppClassLoader@a6eb38a 3 <1ms clojure.core$prn@3e4ac866

core$prn.doInvoke(Object) sun.misc.Launcher$AppClassLoader@a6eb38a 4 <1ms clojure.core$prn@3e4ac866

core$prn.doInvoke(Object) sun.misc.Launcher$AppClassLoader@a6eb38a 5 <1ms clojure.core$prn@3e4ac866

INFO : Ended by timeout
INFO : reset class clojure.core$prn

trace打印了方法的调用次数(5秒内)和每次调用的时间(毫秒级别),以及调用的target object。小技巧:没有可变参数的函数生成类最终调用的是invoke方法(参数个数可能重载),有可变参数的函数调用的是doInvoke方法。

trace命令还支持打印调用堆栈到文件,例如:
trace -t 5 -d -s core$prn.doInvoke

利用-s和-d命令会将详细的调用信息输出到临时目录,临时目录的路径可以通过trace help命令查询到,在我的机器上是/tmp/trace/@host目录下。调用堆栈的输出类似:
example$square.invoke(Long) call by thread [main]
example$eva l9.invoke(test.clj:11)
clojure.lang.Compiler.eva l(Compiler.java:6465)
clojure.lang.Compiler.load(Compiler.java:6902)
clojure.lang.Compiler.loadFile(Compiler.java:6863)
clojure.main$load_script.invoke(main.clj:282)
clojure.main$script_opt.invoke(main.clj:342)
clojure.main$main.doInvoke(main.clj:426)
clojure.lang.RestFn.invoke(RestFn.java:421)
clojure.lang.Var.invoke(Var.java:405)
clojure.lang.AFn.applyToHelper(AFn.java:163)
clojure.lang.Var.applyTo(Var.java:518)
clojure.main.main(main.java:37)

上面这个简单的例子展示了使用housemd跟踪诊断clojure进程的方法。

自定义ns和函数的调试与此类似,假设我们有下面的clojure代码:
(ns example)
(defn square [x]
(* x x))

(loop [x 1]
(Thread/sleep 1000)
(square x)
(recur (inc x)))

ns为example,自定义函数square并定期循环调用。使用housemd诊断这段代码:
loaded -h example$square #查询square的加载情况
trace -t 10 -d -s example$square.invoke #跟踪10秒内square的调用情况

作者: dennis