2011-10-07 17 views
1

私はASM 3.3.1を使用しています。私はクラスを傍受し、そのメソッドの1つを変更しようとしています。 org.objectweb.asm.util.ASMifierClassVisitorを使用して、新しいメソッドを作成するASMコードを取得しています。すべてがうまくいくが、私はif()文を疑うことはできない。結果のasmコードをif文(またはループ)とともに使用しようとすると、実行時に「スタックサイズが大きすぎます」というエラーが発生します。私はClassWriterライター=新しいClassWriter(ClassWriter.COMPUTE_FRAMES);を使用しています。これは私に与えるASMIFYコードです。JavaバイトコードASMによる操作

if()文をASMIFYINGしているときにエラーが発生するのはなぜですか?私はどんな助けにも大いに感謝しています。

`mv = cw.visitMethod(ACC_PUBLIC, "doWrite", "(Lorg/apache/tomcat/util/buf/ByteChunk;)V", null, new String[] { "java/io/IOException" }); 
mv.visitCode(); 
mv.visitVarInsn(ALOAD, 0); 
mv.visitFieldInsn(GETFIELD, "org/apache/coyote/Response", "req", "Lorg/apache/coyote/Request;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/coyote/Request", "getParameters", "()Lorg/apache/tomcat/util/http/Parameters;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/tomcat/util/http/Parameters", "paramsAsString", "()Ljava/lang/String;"); 
mv.visitVarInsn(ASTORE, 2); 
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); 
mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); 
mv.visitInsn(DUP); 
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); 
mv.visitLdcInsn("The Parameters are: "); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 
mv.visitVarInsn(ALOAD, 2); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); 
mv.visitVarInsn(ALOAD, 0); 
mv.visitFieldInsn(GETFIELD, "org/apache/coyote/Response", "req", "Lorg/apache/coyote/Request;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/coyote/Request", "getParameters", "()Lorg/apache/tomcat/util/http/Parameters;"); 
mv.visitLdcInsn("json"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/tomcat/util/http/Parameters", "getParameter", "(Ljava/lang/String;)Ljava/lang/String;"); 
mv.visitVarInsn(ASTORE, 3); 
mv.visitVarInsn(ALOAD, 3); 
Label l0 = new Label(); 
mv.visitJumpInsn(IFNULL, l0); 
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); 
mv.visitLdcInsn("###%#%#%$%#%#%#%#%#%#%#%##%#"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); 
mv.visitLabel(l0); 
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); 
mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); 
mv.visitInsn(DUP); 
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); 
mv.visitLdcInsn("Headers: "); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 
mv.visitVarInsn(ALOAD, 0); 
mv.visitFieldInsn(GETFIELD, "org/apache/coyote/Response", "headers", "Lorg/apache/tomcat/util/http/MimeHeaders;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/tomcat/util/http/MimeHeaders", "toString", "()Ljava/lang/String;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 
mv.visitLdcInsn("\n"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); 
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); 
mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); 
mv.visitInsn(DUP); 
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); 
mv.visitLdcInsn("Writeing: "); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 
mv.visitVarInsn(ALOAD, 1); 
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/tomcat/util/buf/ByteChunk", "toString", "()Ljava/lang/String;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 
mv.visitLdcInsn("\n"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); 
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); 
mv.visitVarInsn(ALOAD, 0); 
mv.visitFieldInsn(GETFIELD, "org/apache/coyote/Response", "outputBuffer", "Lorg/apache/coyote/OutputBuffer;"); 
mv.visitVarInsn(ALOAD, 1); 
mv.visitVarInsn(ALOAD, 0); 
mv.visitMethodInsn(INVOKEINTERFACE, "org/apache/coyote/OutputBuffer", "doWrite", "(Lorg/apache/tomcat/util/buf/ByteChunk;Lorg/apache/coyote/Response;)I"); 
mv.visitInsn(POP); 
mv.visitVarInsn(ALOAD, 0); 
mv.visitInsn(DUP); 
mv.visitFieldInsn(GETFIELD, "org/apache/coyote/Response", "bytesWritten", "J"); 
mv.visitVarInsn(ALOAD, 1); 
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/tomcat/util/buf/ByteChunk", "getLength", "()I"); 
mv.visitInsn(I2L); 
mv.visitInsn(LADD); 
mv.visitFieldInsn(PUTFIELD, "org/apache/coyote/Response", "bytesWritten", "J"); 
mv.visitInsn(RETURN); 
mv.visitMaxs(5, 4); 
mv.visitEnd(); 
` 

コード私はASMifyingです。 (注:私はこの方法を取ったことは私が使用しているすべてだとして)

public void doWrite(ByteChunk chunk/*byte buffer[], int pos, int count*/) 
     throws IOException 
    { 

     String params=req.getParameters().paramsAsString(); 

     System.out.println("The Parameters are: "+params); 

     String reqParam = req.getParameters().getParameter("json"); 

     if(reqParam != null) 
     { 
      System.out.println("###%#%#%$%#%#%#%#%#%#%#%##%#"); 
     } 

     System.out.println("Headers: " + headers.toString()+ "\n"); 
     System.out.println("Writeing: " +chunk.toString()+"\n"); 


     outputBuffer.doWrite(chunk, this); 
     bytesWritten+=chunk.getLength(); 
    } 

元のメソッドは、ちょうど最後の2行

outputBuffer.doWrite(chunk, this); 
bytesWritten+=chunk.getLength(); 

これは良い見ていないが含まれています。私は、CheckClassAdapter.verify()メソッドを使用して、私は邪魔しているクラスの部分のためにこれを持っています。

doWrite(Lorg/apache/tomcat/util/buf/ByteChunk;)V 
00000 Response ByteChunk . . : : FRAME FULL [] [] 
00001 Response ByteChunk . . : :  ALOAD 0 
00002 Response ByteChunk . . : Response :  GETFIELD org/apache/coyote/Response.req : Lorg/apache/coyote/Request; 
00003 Response ByteChunk . . : Request :  INVOKEVIRTUAL org/apache/coyote/Request.getParameters()Lorg/apache/tomcat/util/http/Parameters; 
00004 Response ByteChunk . . : Parameters :  INVOKEVIRTUAL org/apache/tomcat/util/http/Parameters.paramsAsString()Ljava/lang/String; 
00005 Response ByteChunk . . : String :  ASTORE 2 
00006 Response ByteChunk String . : :  GETSTATIC java/lang/System.out : Ljava/io/PrintStream; 
00007 Response ByteChunk String . : PrintStream :  NEW java/lang/StringBuilder 
00008 Response ByteChunk String . : PrintStream StringBuilder :  DUP 
00009 Response ByteChunk String . : PrintStream StringBuilder StringBuilder :  INVOKESPECIAL java/lang/StringBuilder.<init>()V 
00010 Response ByteChunk String . : PrintStream StringBuilder :  LDC "The Parameters are: " 
00011 Response ByteChunk String . : PrintStream StringBuilder String :  INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; 
00012 Response ByteChunk String . : PrintStream StringBuilder :  ALOAD 2 
00013 Response ByteChunk String . : PrintStream StringBuilder String :  INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; 
00014 Response ByteChunk String . : PrintStream StringBuilder :  INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String; 
00015 Response ByteChunk String . : PrintStream String :  INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V 
00016 Response ByteChunk String . : :  ALOAD 0 
00017 Response ByteChunk String . : Response :  GETFIELD org/apache/coyote/Response.req : Lorg/apache/coyote/Request; 
00018 Response ByteChunk String . : Request :  INVOKEVIRTUAL org/apache/coyote/Request.getParameters()Lorg/apache/tomcat/util/http/Parameters; 
00019 Response ByteChunk String . : Parameters :  LDC "json" 
00020 Response ByteChunk String . : Parameters String :  INVOKEVIRTUAL org/apache/tomcat/util/http/Parameters.getParameter (Ljava/lang/String;)Ljava/lang/String; 
00021 Response ByteChunk String . : String :  ASTORE 3 
00022 Response ByteChunk String String : :  ALOAD 3 
00023 Response ByteChunk String String : String :  IFNULL L0 
00024 Response ByteChunk String String : :  GETSTATIC java/lang/System.out : Ljava/io/PrintStream; 
00025 Response ByteChunk String String : PrintStream :  LDC "###%#%#%$%#%#%#%#%#%#%#%##%#" 
00026 Response ByteChunk String String : PrintStream String :  INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V 
00027 Response ByteChunk String String : : L0 
00028 Response ByteChunk String String : : FRAME FULL [org/apache/coyote/Response org/apache/tomcat/ 
00029 Response ByteChunk String String : :  GETSTATIC java/lang/System.out : Ljava/io/PrintStream; 
00030 Response ByteChunk String String : PrintStream :  NEW java/lang/StringBuilder 
00031 Response ByteChunk String String : PrintStream StringBuilder :  DUP 
00032 Response ByteChunk String String : PrintStream StringBuilder StringBuilder :  INVOKESPECIAL java/lang/StringBuilder.<init>()V 
00033 Response ByteChunk String String : PrintStream StringBuilder :  LDC "Headers: " 
00034 Response ByteChunk String String : PrintStream StringBuilder String :  INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; 
00035 Response ByteChunk String String : PrintStream StringBuilder :  ALOAD 0 
00036 Response ByteChunk String String : PrintStream StringBuilder Response :  GETFIELD org/apache/coyote/Response.headers : Lorg/apache/tomcat/util/http/MimeHeaders; 
00037 Response ByteChunk String String : PrintStream StringBuilder MimeHeaders :  INVOKEVIRTUAL org/apache/tomcat/util/http/MimeHeaders.toString()Ljava/lang/String; 
00038 Response ByteChunk String String : PrintStream StringBuilder String :  INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; 
00039 Response ByteChunk String String : PrintStream StringBuilder :  LDC "\n" 
00040 Response ByteChunk String String : PrintStream StringBuilder String :  INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; 
00041 Response ByteChunk String String : PrintStream StringBuilder :  INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String; 
00042 Response ByteChunk String String : PrintStream String :  INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V 
00043 Response ByteChunk String String : :  GETSTATIC java/lang/System.out : Ljava/io/PrintStream; 
00044 Response ByteChunk String String : PrintStream :  NEW java/lang/StringBuilder 
00045 Response ByteChunk String String : PrintStream StringBuilder :  DUP 
00046 Response ByteChunk String String : PrintStream StringBuilder StringBuilder :  INVOKESPECIAL java/lang/StringBuilder.<init>()V 
00047 Response ByteChunk String String : PrintStream StringBuilder :  LDC "Writeing: " 
00048 Response ByteChunk String String : PrintStream StringBuilder String :  INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; 
00049 Response ByteChunk String String : PrintStream StringBuilder :  ALOAD 1 
00050 Response ByteChunk String String : PrintStream StringBuilder ByteChunk :  INVOKEVIRTUAL org/apache/tomcat/util/buf/ByteChunk.toString()Ljava/lang/String; 
00051 Response ByteChunk String String : PrintStream StringBuilder String :  INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; 
00052 Response ByteChunk String String : PrintStream StringBuilder :  LDC "\n" 
00053 Response ByteChunk String String : PrintStream StringBuilder String :  INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; 
00054 Response ByteChunk String String : PrintStream StringBuilder :  INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String; 
00055 Response ByteChunk String String : PrintStream String :  INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V 
00056 Response ByteChunk String String : :  ALOAD 0 
00057 Response ByteChunk String String : Response :  GETFIELD org/apache/coyote/Response.outputBuffer : Lorg/apache/coyote/OutputBuffer; 
00058 Response ByteChunk String String : OutputBuffer :  ALOAD 1 
00059 Response ByteChunk String String : OutputBuffer ByteChunk :  ALOAD 0 
00060 Response ByteChunk String String : OutputBuffer ByteChunk Response :  INVOKEINTERFACE org/apache/coyote/OutputBuffer.doWrite (Lorg/apache/tomcat/util/buf/ByteChunk;Lorg/apache/coyote/Response;)I 
00061 Response ByteChunk String String : I :  POP 
00062 Response ByteChunk String String : :  ALOAD 0 
00063 Response ByteChunk String String : Response :  DUP 
00064 Response ByteChunk String String : Response Response :  GETFIELD org/apache/coyote/Response.bytesWritten : J 
00065 Response ByteChunk String String : Response J :  ALOAD 1 
00066 Response ByteChunk String String : Response J ByteChunk :  INVOKEVIRTUAL org/apache/tomcat/util/buf/ByteChunk.getLength()I 
00067 Response ByteChunk String String : Response J I :  I2L 
00068 Response ByteChunk String String : Response J J :  LADD 
00069 Response ByteChunk String String : Response J :  PUTFIELD org/apache/coyote/Response.bytesWritten : J 
00070 Response ByteChunk String String : :  RETURN 
00071 ?  :  NOP 
00072 ?  :  NOP 
00073 ?  :  NOP 
00074 ?  :  NOP 
00075 ?  :  NOP 
00076 ?  :  NOP 
00077 ?  :  NOP 
00078 ?  :  NOP 
00079 ?  :  NOP 
00080 ?  :  NOP 
00081 ?  :  NOP 
00082 ?  :  NOP 
00083 ?  :  NOP 
00084 ?  :  NOP 
00085 ?  :  NOP 
00086 ?  :  NOP 
00087 ?  :  NOP 
00088 ?  :  NOP 
00089 ?  :  NOP 
00090 ?  :  NOP 
00091 ?  :  NOP 
00092 ?  :  NOP 
00093 ?  :  NOP 
00094 ?  :  NOP 
00095 ?  :  NOP 
00096 ?  :  NOP 
00097 ?  :  ATHROW 
+0

作成している非ASMコードを投稿できますか?そうした方法であなたの意図を理解しやすくし、作成しているASMがなぜスタックと議論しているのかを理解してください。 –

+0

さて、私はASMifyingのコードを更新しました。 – Chris

+0

(個人的には、これをすべて手作業でスキップし、AspectJ、btwを使用します) –

答えて

0

私はこの問題は、あなたがifステートメントを含むクラスにASMIfier使用することはできませんです疑います。

ASMifierで生成されたコードに追加すると、必要なスタックの量が増え、メソッドの最後に最大値を増やさないようにスタックを使用した可能性が非常に高くなります。

+0

お返事ありがとうございます。実際には、ASMifierコードには追加しませんでした。私が望む完全な新しい方法をASM化しました。そのコードにif文があるとエラーになります。それらがなければ他のすべてのASMifiedコードはうまく動作します。 – Chris

+0

このように失敗したJavaコードの例を挙げることはできますか? ASMは、JDKのすべてのクラスでテストされます。 –

+0

もちろん、私はASMifyingの方法を掲載しました。 if文を使用しますが、今はジャンクb/cを印刷しているだけです。しかし、If文を取り出すと、ASMifyingとクラスのインターセプトとメソッドの置き換えがうまくいきます。 – Chris

関連する問題