差异两个文件忽略行的某些部分

时间:2018-01-11 07:53:24

标签: debugging diff bytecode meld

我们说我有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一样简单;忽略第一个:的所有内容。

理想情况下,当然,它允许我设置更复杂的排除检查,例如"如果标记为#则忽略整数,或者在前缀为同一行的单词上跟随ifjsrgoto。但我不希望有一些方便的东西。

更新

根据@ 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_mapstack_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>部分,那么仍然会很方便。

1 个答案:

答案 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,指令前面的数字不是行号,而是字节码指令偏移量。