我们说我有javap -v
生成的两个文件。
输出看起来像这样:
[...]
299: astore 15
301: aload 15
303: aload 18
305: if_acmpeq 367
308: aload 15
310: arraylength
311: istore 17
313: iload 17
315: ifeq 348
318: aload 15
320: iconst_2
321: laload
322: lstore 19
324: aload_1
325: getfield #49 // Field my/somewhere/Some.thing:J
328: lstore 21
330: lload 19
332: lload 21
334: land
335: lstore 19
[...]
如果我将其与另一个文件区分开来,大部分的麻布都会发生变化并显示为差异"。
我可以写一个删除它们的sript,但我仍然需要它们来查看我的代码跳转到哪里。
同样,该字段/ Field my/somewhere/Some.thing:J
恰好与#49
完全无关。
同时,更改的寄存器与相关。
那么是否有一个工具(当然,最好有一个GUI,因为文件非常大,上下文有助于弄清楚发生了什么)来区分两个文件而忽略了部分线而没有删除所说的部分?
行号,至少。可以像&#34一样简单;忽略第一个:
的所有内容。
理想情况下,当然,它允许我设置更复杂的排除检查,例如"如果标记为#
则忽略整数,或者在前缀为同一行的单词上跟随if
,jsr
或goto
。但我不希望有一些方便的东西。
更新
根据@ user882813的建议使用asmtools jdis会产生类似
的输出 astore 6;
aload 6;
aload 8;
if_acmpeq L795;
aload 6;
arraylength;
istore 7;
iload 7;
ifeq L781;
aload 6;
iload 4;
laload;
lstore 9;
aload_1;
getfield Field my/somehwere/Some.thing:"J";
lstore 11;
lload 9;
lload 11;
land;
lstore 9;
...
L795: stack_frame_type full;
locals_map ...
对于差异而言,这比javap -v
输出更好。
(而且就个人而言,我非常喜欢内联的locals_map
和stack_map
。)
然而,跳跃目标/标签(例如L795
)都显示为误报。
此外,现在同样适用于try-catch块标签(例如t6
)。
try t6;
aload 4;
getfield Field Something.f:"Lparc/lang/Foo;";
checkcast class SpecialFoo;
endtry t6;
goto L495;
catch t6 java/lang/ClassCastException;
stack_frame_type full;
locals_map class Something, class parc/some/Thing, bogus, int, class Something$1, class SpecialFoo, class "[J", bogus, class "[J", bogus, bogus, bogus, bogus, null, null;
stack_map class java/lang/ClassCastException;
new class java/lang/Error;
dup;
ldc String "not SpecialFoo";
invokespecial Method java/lang/Error."<init>":"(Ljava/lang/String;)V";
athrow;
L495: stack_frame_type stack1;
stack_map class SpecialFoo;
nop;
因此,如果可以将工具配置为忽略行的t<integer>
和L<integer>
部分,那么仍然会很方便。
答案 0 :(得分:1)
尝试使用asmtools jdis代替javap
asmtools jdis
有更多干净的输出。
例如,对于简单的HelloWorld应用程序
class Hello {
public static void main(String... args) {
System.out.println("Hello, world!");
}
}
asmtools jdis
输出将是:
super class Hello
version 52:0
{
Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
}
public static varargs Method main:"([Ljava/lang/String;)V"
stack 2 locals 1
{
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Hello, world!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
return;
}
} // end Class Hello
JFYI,指令前面的数字不是行号,而是字节码指令偏移量。