代码之家  ›  专栏  ›  技术社区  ›  Daniel Schneller

如何检测Java字节码(FixBug)中的数组大小

  •  4
  • Daniel Schneller  · 技术社区  · 15 年前

    当然,如果在编译时知道这个信息,我想通过查看字节码来了解正在分配的数组的大小。

    背景:我想写一个findbugs检测器(它查看编译后的字节码)并报告数组分配的某些情况。为了过滤掉误报,我对“小”数组不感兴趣,只对编译时大小不可用或大于可配置阈值的数组感兴趣。

    由于findbugs源代码没有太多的文档记录,我正在寻找一些关于如何开始的指针——可能已经有一个dectector在做我可以看到的类似的事情。

    2 回复  |  直到 15 年前
        1
  •  2
  •   McDowell rahul gupta    15 年前

    这可能会有点棘手。我的知识还不完整,但您至少需要注意三种指令(newarray、anewarray和multianewarray)。查看之前的说明(或在多网络Warray的情况下, n 前面的指令)获取大小,即使它是常量,也可能加载bipush、sipush或ldc(还有其他内容吗?)取决于大小。正如您所指出的,如果类是计算的结果,那么您可能会无限期地跟踪指令。

    如果我没记错的话,findbugs在内部使用BCEL,但我从来没有深入研究过它们到底有多聪明。如果这些团队中的任何一个都有合适的邮件列表,他们可能会被证明是一个更好的提问地点——他们可能至少会知道是否有人曾经走过这条路。

        2
  •  5
  •   Michael Myers KitsuneYMG    15 年前

    好吧,如果它们是基于一个常量分配的,那么您可以检查在分配之前推送的常量。例如:

    class ArraySize {
        private static final int smallsize = 10;
        private static final int largesize = 1000;
        public static void main(String[] args) {
            int[] small = new int[smallsize];
            int[] big = new int[largesize];
        }
    }
    

    给出字节码:

    Compiled from "ArraySize.java"
    class ArraySize extends java.lang.Object{
    ArraySize();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return
    
    public static void main(java.lang.String[]);
      Code:
       0:   bipush  10
       2:   newarray int
       4:   astore_1
       5:   sipush  1000
       8:   newarray int
       10:  astore_2
       11:  return
    
    }