Python包与标准CLI Java调试器“JDB”接口,以提取有关Java程序执行的信息。
pyjdb的Python项目详细描述
Pyjdb
python通过jdb与java调试器接口。
概述
JdbProcess
使用pexpect
附加到jdb
进程并记录获得的所有信息。
对于每一条指令,我们都会记录以下格式的字典:
{"return":10000,"thread":"main","class.method":"IterPower.iterPower()","method":"iterPower","line":15,"bci":17,"instruction":"return result;"}
对于每条指令,我们还可以获得当前方法参数的字典,以及它的所有局部变量:
({'base':10,'exp':0},{'result':10000})
示例
假设我们有这个java文件,IterPower.java
:
publicclassIterPower{publicstaticvoidmain(String[]args){// ... parse arguments ...System.out.println(iterPower(base,exp));}publicstaticintiterPower(intbase,intexp){intresult=1;while(exp>0){result*=base;exp-=1;}returnresult;}}
它是用调试信息javac -g IterPower.java
编译的。以下是python代码片段:
importpyjdbimportitertoolsp=pyjdb.JdbProcess("IterPower")p.spawn("10 4")variables={}whileTrue:# Try to make an additional step and retrieve local variablesresult=Nonetry:p.step()result=p.locals()exceptpyjdb.EOF:breakifresultisNone:continue# Store the values of each variable(args,locs)=resultfor(var,val)initertools.chain(args.items(),locs.items()):variables[var]=variables.get(var,list())variables[var].append(val)variables_unique_values={var:list(set(vals))for(var,vals)invariables.items()}print(variables_unique_values)
代码段将在执行过程中输出此程序的变量值的跟踪:
{"args":["instance of java.lang.String[0] (id=495)"],"base":[10],"exp":[0,1,2,3,4],"result":[1,10,100,1000,10000]}
{'base':[10],'exp':[0,1,2,3,4],'result':[1,100,1000,10,10000],'args':['java.lang.string[2]的实例(id=495)]}
灵感
这个项目的灵感来自一个talk by Elena Glassman,在这个项目中,她展示了如何根据内部变量的跟踪对different implementations of the same solution进行聚类。她的工作包括OverCode和foobaz,重点是python程序。在我的家乡,我们在入门课程中使用java。这个项目的最初目标是将Glassman博士的技术应用到Java任务中。
相关项目
有几个雄心勃勃的项目涉及到将java调试器引入python。这些项目强调了实现实际的jdwp协议是多么复杂。这就是为什么在这个项目中,我们的方法是依靠jdb
来实现协议级功能。
csuter/pyjdb(放弃):jdwp规范的python实现。
soulseekah/pyjdb(放弃):用更友好的特性替换
jdb
。