谷本 心 in せろ部屋

はてなダイアリーから引っ越してきました

Javapでエラーが起きる場所をよく見てみた

Eclipseからsun.tools.javap.Mainを叩いてみた。
まずは、問題が起きる箇所のスタックトレース

java.io.EOFException
	at java.io.DataInputStream.readUnsignedByte(DataInputStream.java:273)
	at sun.tools.javap.StackMapData.readType(StackMapData.java:46)
	at sun.tools.javap.StackMapData.readTypeArray(StackMapData.java:40)
	at sun.tools.javap.StackMapData.<init>(StackMapData.java:32)
	at sun.tools.javap.MethodData.readStackMap(MethodData.java:213)
	at sun.tools.javap.MethodData.readCode(MethodData.java:131)
	at sun.tools.javap.MethodData.read(MethodData.java:59)
	at sun.tools.javap.ClassData.readMethods(ClassData.java:206)
	at sun.tools.javap.ClassData.read(ClassData.java:99)
	at sun.tools.javap.ClassData.<init>(ClassData.java:52)
	at sun.tools.javap.JavapPrinter.<init>(JavapPrinter.java:30)
	at sun.tools.javap.Main.displayResults(Main.java:201)
	at sun.tools.javap.Main.perform(Main.java:61)
	at sun.tools.javap.Main.entry(Main.java:49)
	at sun.tools.javap.Main.main(Main.java:34)
ERROR:fatal exception

readUnsignedByteで、EOFを含むバイトを読もうとしてコケてるみたい。
その辺りのソースを見てみると、、、

    StackMapData(DataInputStream in, MethodData method) throws IOException {
        offset = in.readUnsignedShort();
        int local_size = in.readUnsignedShort();
        locals = readTypeArray(in, local_size, method);
        int stack_size = in.readUnsignedShort();
        stack = readTypeArray(in, stack_size, method);
    }
  
    static final int[] readTypeArray(DataInputStream in, int length, MethodData method) throws IOException {
	int[] types = new int[length];
	for (int i=0; i<length; i++) {
	    types[i] = readType(in, method);
	}
	return types;
    }
  
    static final int readType(DataInputStream in, MethodData method) throws IOException {
	int type = in.readUnsignedByte();
	if (type == ITEM_Object || type == ITEM_NewObject) {
	    type = type | (in.readUnsignedShort()<<8);
        }
	return type;
    }

なるほど、
要は「int local_size = in.readUnsignedShort();」をやってる箇所で
正しい値が取れなくて、過剰にfor文を回しているだけのようですね。


classのバイナリ構造に関してはよく知らないので推測だけど、
恐らく、ASMでclassをいじる際に、
local_sizeに相当する箇所のサイズを書き換えず、
クラスの内容だけ書き換えちゃってるから、
整合性が取れずにjavapでコケちゃってるんだと思う。


当面、javapができなくて困ってるわけじゃないので、
このぐらいで止めとこう。