SlideShare a Scribd company logo
1 of 75
Taming Reflection
Aiding Static Analysis in the Presence of Reflection
                           and Custom Class Loaders

         Eric Bodden, Andreas Sewe, Jan Sinschek,
                    Hela Oueslati and Mira Mezini
necti ons!”
                    ose d   con
          rite to cl
“D on’t w
Reflective method calls
               public class Main {

           	       public static void main(String[] args) throws Exception {
           	       	 Connection c = new Connection();

                       Class c = Class.forName( "Evil" );
                       Method m = c.getMethod("doEvil", Connection.class);
Evil.doEvil(c);        m.invoke(null,c);

           	       	   c.write("ohoh...");
           	       }

               public class Evil {

                public static void doEvil(Connection c) {
                    c.close();
                }

               }




                                                3
Reflective method calls
               public class Main {

           	       public static void main(String[] args) throws Exception {
           	       	 Connection c = new Connection();

                       Class c = Class.forName( "Evil" );
                       Method m = c.getMethod("doEvil", Connection.class);
Evil.doEvil(c);        m.invoke(null,c);

           	       	   c.write("ohoh...");
           	       }

               public class Evil {              hard to analyze statically!
                public static void doEvil(Connection c) {
                    c.close();
                }

               }




                                                3
Reflective method calls
               public class Main {

           	       public static void main(String[] args) throws Exception {
           	       	 Connection c = new Connection();

                       Class c = Class.forName( args[0] );
                                                 "Evil"
                       Method m = c.getMethod("doEvil", Connection.class);
Evil.doEvil(c);        m.invoke(null,c);

           	       	   c.write("ohoh...");
           	       }
                                                 imp ossible
               public class Evil {              hard to analyze statically!
                public static void doEvil(Connection c) {
                    c.close();
                }

               }




                                                3
Reflective method calls
               public class Main {

           	       public static void main(String[] args) throws Exception {
           	       	 Connection c = new Connection();

                       Class c = Class.forName( args[0] );
                                                 "Evil"
                       Method m = c.getMethod("doEvil", Connection.class);
Evil.doEvil(c);        m.invoke(null,c);

           	       	   c.write("ohoh...");
           	       }
                                                 imp ossible
               public class Evil {              hard to analyze statically!
                public static void doEvil(Connection c) {
                    c.close();
                }
                                                Present a pragmatic,
               }                                partial solution

                                                3
Important reflective calls

Class.forName(String
className)


Class.newInstance()




Method.invoke(Object
tgt,
Object[]
args)


Constructor.newInstance(Object[]
args)


...

                  4
Uses of Reflection

Extensibility

Separate Compilation

Runtime class generation

“Hacking”: call private methods


                5
Reflection is...

   used a lot

   unsound to ignore

   often impossible to resolve
Play-Out   Boost       Analyse &   Play-In
                       Transform


                   7
y-O ut
     1 :P la
Step

       8
Play-Out
    public class Main {

	       public static void main(String[] args) throws Exception {
           Connection c = new Connection();

            Class c = Class.forName( "Evil" );
            Method m = c.getMethod("doEvil", Connection.class);
            m.invoke(null,c);

            c.write("ohoh...");
	       }

    public class Evil {

     public static void doEvil(Connection c) {
         c.close();
     }

    }




                                                           9
Play-Out
    public class Main {

	       public static void main(String[] args) throws Exception {
           Connection c = new Connection();

            Class c = Class.forName( "Evil" );
            Method m = c.getMethod("doEvil", Connection.class);
            m.invoke(null,c);

            c.write("ohoh...");
	       }

    public class Evil {

                                        $
javac
Main.java

     public static void doEvil(Connection c) {
                                      $
java
‐javaagent:poa‐trunk.jar=out
Main
         c.close();
     }
                                        =============================================
    }                                   TamiFlex
Play‐Out
Agent
Version
trunk
                                        Found
2
new
log
entries.
                                        Log
file
written
to:
out/refl.log
                                        $
cat
out/refl.log

                                        Class.forName;Evil;Main.main;6
                                        Method.invoke;<Evil:
void
doEvil(Connection)>;Main.main;8;




                                                           9
Play-Out
    public class Main {

	       public static void main(String[] args) throws Exception {
           Connection c = new Connection();

            Class c = Class.forName( "Evil" );
            Method m = c.getMethod("doEvil", Connection.class);
            m.invoke(null,c);

            c.write("ohoh...");
	       }

    public class Evil {

                                        $
javac
Main.java

     public static void doEvil(Connection c) {
                                      $
java
‐javaagent:poa‐trunk.jar=out
Main
         c.close();
     }
                                        =============================================
    }                                   TamiFlex
Play‐Out
Agent
Version
trunk
                                        Found
2
new
log
entries.
                                        Log
file
written
to:
out/refl.log
                                        $
cat
out/refl.log

                                        Class.forName;Evil;Main.main;6
                                        Method.invoke;<Evil:
void
doEvil(Connection)>;Main.main;8;

              kind of call

                                                           9
Play-Out
    public class Main {

	       public static void main(String[] args) throws Exception {
           Connection c = new Connection();

            Class c = Class.forName( "Evil" );
            Method m = c.getMethod("doEvil", Connection.class);
            m.invoke(null,c);

            c.write("ohoh...");
	       }

    public class Evil {

                                        $
javac
Main.java

     public static void doEvil(Connection c) {
                                      $
java
‐javaagent:poa‐trunk.jar=out
Main
         c.close();
     }
                                        =============================================
    }                                   TamiFlex
Play‐Out
Agent
Version
trunk
                                        Found
2
new
log
entries.
                                        Log
file
written
to:
out/refl.log
                                        $
cat
out/refl.log

                                        Class.forName;Evil;Main.main;6
    fully resolved                      Method.invoke;<Evil:
void
doEvil(Connection)>;Main.main;8;


    target of call
                                                           9
Play-Out
    public class Main {

	       public static void main(String[] args) throws Exception {
           Connection c = new Connection();

            Class c = Class.forName( "Evil" );
            Method m = c.getMethod("doEvil", Connection.class);
            m.invoke(null,c);

            c.write("ohoh...");
	       }

    public class Evil {

                                        $
javac
Main.java

     public static void doEvil(Connection c) {
                                      $
java
‐javaagent:poa‐trunk.jar=out
Main
         c.close();
     }
                                        =============================================
    }                                   TamiFlex
Play‐Out
Agent
Version
trunk
                                        Found
2
new
log
entries.
                                        Log
file
written
to:
out/refl.log
                                        $
cat
out/refl.log

                                        Class.forName;Evil;Main.main;6
                                        Method.invoke;<Evil:
void
doEvil(Connection)>;Main.main;8;

        location of call
                                                           9
Play-Out
    public class Main {

	       public static void main(String[] args) throws Exception {
           Connection c = new Connection();

            Class c = Class.forName( "Evil" );
            Method m = c.getMethod("doEvil", Connection.class);
            m.invoke(null,c);

            c.write("ohoh...");
	       }

    public class Evil {

                                                $
find
out
‐name
*.class
     public static void doEvil(Connection c) {
                                              out/com/apple/java/BackwardsCompatibility.class
         c.close();
     }                                        out/java/io/BufferedInputStream.class
                                                out/java/io/BufferedOutputStream.class
    }                                           out/java/io/BufferedReader.class
                                                out/java/io/BufferedWriter.class
                                                out/java/io/ByteArrayInputStream.class
                                                out/java/io/ByteArrayOutputStream.class
                                                out/java/io/Closeable.class
                                                out/java/io/DataInput.class
                                                ...




                                                           9
Why dump classes?




10
Why dump classes?



     Static
     analysis
     needs to
     know the
     code
10
Why dump classes?
                $
java
‐jar
dacapo‐9.12‐bach.jar
fop
                =====
DaCapo
9.12
fop
starting
=====
                =====
DaCapo
9.12
fop
PASSED
in
2503
msec
=====




     Static
     analysis
     needs to
     know the
     code
10
Why dump classes?
                $
java
‐jar
dacapo‐9.12‐bach.jar
fop
                =====
DaCapo
9.12
fop
starting
=====
                =====
DaCapo
9.12
fop
PASSED
in
2503
msec
=====




     Static
     analysis
     needs to
     know the
     code
10
Play-out Agent
Program         ClassLoader




               Play‐Out
Agent




                      11
Play-out Agent
Program         ClassLoader




                     Main.class
               Play‐Out
Agent




                      11
Play-out Agent
          load class java.lang.reflect.Method

Program                    ClassLoader




                          Play‐Out
Agent



                                      dump every
                                      loaded class to disk




             Main.class
                                 11
Play-out Agent
          load class java.lang.reflect.Method

Program                    ClassLoader




                                      Method.class
                          Play‐Out
Agent



                                      dump every
                                      loaded class to disk




             Main.class
                                 11
Play-out Agent
          load class java.lang.reflect.Method

Program                    ClassLoader




                                 Method.class
                          Play‐Out
Agent



                                      dump every
                                      loaded class to disk




             Main.class
                                 11
Play-out Agent
               load class java.lang.reflect.Method

 Program                         ClassLoader




Method.class



                                Play‐Out
Agent



                                            dump every
                                            loaded class to disk




                   Main.class
                Method.class
                                       11
Play-out Agent
                   load class java.lang.reflect.Method

 Program                              ClassLoader




Method.class
               call to
               Method.invoke


                                     Play‐Out
Agent



                                                 dump every
                                                 loaded class to disk




                        Main.class
                     Method.class
                                            11
Play-out Agent
                       load class java.lang.reflect.Method

     Program                              ClassLoader




    Method.class
                   call to
                   Method.invoke


                                         Play‐Out
Agent



                                                     dump every
                                                     loaded class to disk




write entry                 Main.class
to log file               Method.class
                                                11
Play-out Agent
                          load class java.lang.reflect.Method

     Program                              ClassLoader




    Method.class
                      call to
                      Method.invoke


                                         Play‐Out
Agent

  Constructor.class
                                                    dump every
                                                    loaded class to disk

    Class.class




write entry                    Main.class
                              Constructor.class
to log file                  Method.class
                               Class.class     11
Step 2: Boosting




         12
Booster transforms program into
                                  statically analyzable version

    public class Main {
                                                                                  Connection.<init>
	       public static void main(String[] args) throws Exception {



                                   ?
           Connection c = new Connection();

            Class cl = Class.forName(args[0]);




                                   ?
            Method m = cl.getMethod("do"+"Evil", Connection.class);
                                                                                  Class.forName
                                                                      Main.main
            m.invoke(null,c);

            c.write("ohoh...");                                                   Class.getMethod
	       }

    public class Evil {                                                           Method.invoke
     public static void doEvil(Connection c) {
         c.close();
     }                                                                            Connection.write

    }




                                                           13
Booster transforms program into
                                  statically analyzable version

    public class Main {
                                                                                    Connection.<init>
	       public static void main(String[] args) throws Exception {



                                   ?
           Connection c = new Connection();

            Class cl = Class.forName(args[0]);




                                   ?
            Method m = cl.getMethod("do"+"Evil", Connection.class);
                                                                                        Class.forName
                                                                      Main.main
            m.invoke(null,c);

            c.write("ohoh...");                                                         Class.getMethod
	       }

    public class Evil {                                                                 Method.invoke
     public static void doEvil(Connection c) {
         c.close();
     }                                                                                  Connection.write

    }                      $
cat
out/refl.log

                           Class.forName;Evil;Main.main;6
                           Method.invoke;<Evil:
void
doEvil(Connection)>;Main.main;8;




                                                           13
Booster transforms program into
                                statically analyzable version
    public class Main {

	       public static void main(String[] args) throws Exception {                    Connection.<init>
           Connection c = new Connection();

            Class cl;
            if(args[0].equals("Evil"))
                cl = Evil.class;
            else {
                                                                                     Class.forName
                TamiFlexRT.warnClassForName(args[0]);                 Main.main
                cl = Class.forName(args[0]);
            }
                                                                                     Class.getMethod
            Method m = cl.getMethod("do"+"Evil", Connection.class);

            if(m.getDeclaringClass().getName().equals("Evil") &&                     Method.invoke
              m.getName().equals("doEvil"))
                Evil.doEvil(c);
            else {
                TamiFlexRT.warnMethodInvoke(m);                                      Connection.write
                m.invoke(null,c);
            }

            c.write("ohoh...");
	       }                                                              Evil.doEvil   Connection.close

	       ...

    }


                                                            13
Booster transforms program into
                                statically analyzable version
    public class Main {

	       public static void main(String[] args) throws Exception {                    Connection.<init>
           Connection c = new Connection();

            Class cl;
            if(args[0].equals("Evil"))
                cl = Evil.class;
            else {
                                                                                     Class.forName
                TamiFlexRT.warnClassForName(args[0]);                 Main.main
                cl = Class.forName(args[0]);
            }
                                                                                     Class.getMethod
            Method m = cl.getMethod("do"+"Evil", Connection.class);

            if(m.getDeclaringClass().getName().equals("Evil") &&                     Method.invoke
              m.getName().equals("doEvil"))
                Evil.doEvil(c);
            else {
                TamiFlexRT.warnMethodInvoke(m);                                      Connection.write
                m.invoke(null,c);
            }

            c.write("ohoh...");
	       }                                                              Evil.doEvil   Connection.close

	       ...

    }


                                                            13
Booster
Implemented on top of Soot

Operates on 3-address code (Jimple)
generated from bytecode

Input: class files recorded by play-out agent

Emits class files of “boosted” program

Some nitty-gritty details with respect to the
use of non-standard class loaders (see paper)


                    14
Booster
     Program                         ClassLoader




                                                                    Main.class


    Method.class


                                          Main.class
                                    Play‐Out
Agent

  Constructor.class
                                             dump every
                                             loaded class to disk

    Class.class




write entry
to log file
                      Main.class
                                                                                 15
Booster
     Program                         ClassLoader




                                                                    Main.class


    Method.class


                                          Main.class
                                    Play‐Out
Agent

  Constructor.class
                                             dump every
                                             loaded class to disk

    Class.class




write entry
to log file                            Booster            Main.class
                      Main.class
                                                                                 15
Booster
     Program                         ClassLoader




                                                                    Main.class


    Method.class


                                          Main.class
                                    Play‐Out
Agent
                                                                                     Main.class
  Constructor.class
                                             dump every
                                             loaded class to disk

    Class.class




write entry                                                                  Static Analysis
to log file                            Booster            Main.class
                      Main.class
                                                                                           15
Booster
     Program                         ClassLoader




                                                                    Main.class


    Method.class


                                          Main.class
                                    Play‐Out
Agent



                                                                             ?
                                                                                     Main.class
  Constructor.class
                                             dump every
                                             loaded class to disk

    Class.class




write entry                                                                  Static Analysis
to log file                            Booster            Main.class
                      Main.class
                                                                                           15
Step
       3: Pla
              y-In


          16
Play-in Agent
                                                        load from
                                                       somewhere,
                       load class Main                 or generate
             Program                       Custom

                                         ClassLoader




                                     Play‐In
Agent



Main.class




                                         17
Play-in Agent
                                                        load from
                                                       somewhere,
                       load class Main                 or generate
             Program                       Custom

                                         ClassLoader




                                     Play‐In
Agent



Main.class




                                         17
Play-in Agent
                                                              load from
                                                             somewhere,
                       load class Main                       or generate
             Program                       Custom

                                         ClassLoader




                                                       Main.class
                                     Play‐In
Agent



Main.class




                                         17
Play-in Agent
                                                        load from
                                                       somewhere,
                       load class Main                 or generate
             Program                       Custom

                                         ClassLoader




                                     Play‐In
Agent


                        search
Main.class
                     transformed
                   version of Main

                                         17
Play-in Agent
                                                 load from
                                                somewhere,
                load class Main                 or generate
Program                             Custom

                                  ClassLoader




replace Main by
            Main.class

  transformed
      class



                              Play‐In
Agent


                 search
              transformed
            version of Main

                                  17
Just when
we thought
we were
done...
ge nerate d   classes
      m ay bear
ran d o mize d names!



         19
Play-in Agent

             Program        Custom

                          ClassLoader




                        Play‐In
Agent



C$42.class




                          20
Play-in Agent

             Program               Custom

                                 ClassLoader




         ≠
                               Play‐In
Agent



C$42.class

             C$23.class


                                 20
Play-in Agent

             Program              Custom

                                ClassLoader




                 C$23.class




                              Play‐In
Agent



C$42.class




                                20
Solution
Normalization: replace randomized name by
normalized name

  in the log, the binaries, everywhere...

Quite involved: classes to normalize may be
interdependent

Details in the paper

More details in our Tech Report

Yet more details in the source


                       21
Evaluation




    22
Evaluation


     an th is be s o u n d?
How c




             22
Evaluation


     an th is be s o u n d?
How c

                     It’s not!
           But it’s sounder!

             22
Evaluation


     an th is be s o u n d?
How c

                      It’s not!
            But it’s sounder!
      It’s “representative”!
             22
Correctness


static call graph ⊇   ∪{recorded call graph} ?




                       23
Correctness


    static call graph ⊇    ∪{recorded call graph} ?
computed with Soot/Spark         recorded with JVMTI agent




                            23
Correctness


    static call graph ⊇    ∪{recorded call graph} ?
computed with Soot/Spark         recorded with JVMTI agent



                                                Yes!
                       (call graphs are representative;
tested with Lhotak’s Call-graph comparison tool ProBe)

                            23
Effectiveness: How much does log-file
  quality depend on program input?




        Dacapo “bach” release
                  24
Effectiveness: How much does log-file
  quality depend on program input?




        Dacapo “bach” release
                  24
Effectiveness: How much does log-file
  quality depend on program input?




        Dacapo “bach” release
                  24
Effectiveness: How much does log-file
  quality depend on program input?




        Dacapo “bach” release
                  24
Effectiveness: How much does log-file
  quality depend on program input?




        Dacapo “bach” release
                  24
Effectiveness: How much does log-file
  quality depend on program input?




        Dacapo “bach” release
                  24
Effectiveness: How much does log-file
  quality depend on program input?




        Dacapo “bach” release
                  24
Effectiveness: How much does log-file
   quality depend on program input?




Can now safely use static analyses on DaCapo:
         Warnings never triggered!
                     24
Effectiveness: How much does log-file
  quality depend on program input?




 Other prominent programs/frameworks
                  25
Effectiveness: How much does log-file
  quality depend on program input?




 Appro ach requ ires go o d
   “feature co verage”



                 26
3.00
                                                                                                                                       2.62



           2.00



                                                     1.22                                                                                      1.18
                  1.02          1.02      1.08                     1.06          1.09                  1.03    1.05           1.04
                                                            1.00                            1.00
Play-Out   1.00

                    vro
                        ra
                                  ati
                                      k         e
                                             ips fo
                                                    p        h2          on          e  x            h
                                                                                                  arc pm
                                                                                                         d              ow          s   p
                                                                                                                                  an soa xala
                                                                                                                                              n
                  a             b          cl                      j yth         ind            e                   nfl         e
                                                                                                                              eb rade
                                          e                                   lu          lus                  su           d
                                                                                                                        tra       t



           3.00




           2.00



                                              1.12                  1.09           1.06                             1.06        1.04    1.05
                   1.03         1.00                 1.04   1.03                                1.04    1.00                                    1.00
Play-In    1.00

                    vro
                        r   a
                                  ati
                                      k            e
                                                ips fo
                                                       p      h2         o   n          e   x         h
                                                                                                   arc pm
                                                                                                          d               o w           s   p
                                                                                                                                      an soa xala
                                                                                                                                                  n
                  a             b             cl                    jyth           i nd          e                    nfl           e
                                                                                                                                  eb rade
                                          e                                      lu         lus                 su              d
                                                                                                                            tra       t
Related Work
Partial evaluation
Braux & Noyé, PEPM 1999

String analysis
Christensen et al., SAS 2003
Livshits et al., APLAS 2005

Application extraction
Tip et. al, TOPLAS 2002

“Finding the code”
Bessey et. al (Coverity), CACM 2010

                   28
Related Work

Online Call-Graph Construction
Hirzel et al., TOPLAS 2007

Blended Analysis
Dufour et al., ISSTA 2007

Runtime type inference in PRuby
Furr et al., OOPSLA 2009




                   29
http://tamiflex.googlecode.com/


               First external users



 Cheng Zhang, SJTU        Saswat Anand, Georgia Tech      Jochen Huck, KIT

Play-out, Soot, Play-In         Play-out, Soot             Play-out, Soot

Call frequency analysis     Points-to, Symb. Exec.     Side-Effects, Dominance
http://tamiflex.googlecode.com/




Play-Out   Boost    Analyse &    Play-In
                    Transform


Correct     Effective       Efficient
http://tamiflex.googlecode.com/


               MODULARITY - aosd 2012                submit to



         2nd of 3 submission deadlines: July 14th


                                                  Record
                                                 number of
                                                submitted &
                                                 accepted
                July 17th-21st, 2011, Toronto     papers

attend

More Related Content

What's hot

Advanced Java Practical File
Advanced Java Practical FileAdvanced Java Practical File
Advanced Java Practical File
Soumya Behera
 
C# 6.0 - April 2014 preview
C# 6.0 - April 2014 previewC# 6.0 - April 2014 preview
C# 6.0 - April 2014 preview
Paulo Morgado
 
Scripting
ScriptingScripting
Scripting
aztack
 

What's hot (14)

2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"
Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"
Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"
 
Exceptional exceptions
Exceptional exceptionsExceptional exceptions
Exceptional exceptions
 
Generics and Lambda survival guide - DevNexus 2017
Generics and Lambda survival guide - DevNexus 2017Generics and Lambda survival guide - DevNexus 2017
Generics and Lambda survival guide - DevNexus 2017
 
Dart London hackathon
Dart  London hackathonDart  London hackathon
Dart London hackathon
 
Advanced Java Practical File
Advanced Java Practical FileAdvanced Java Practical File
Advanced Java Practical File
 
Java Questions
Java QuestionsJava Questions
Java Questions
 
C# 6.0 - April 2014 preview
C# 6.0 - April 2014 previewC# 6.0 - April 2014 preview
C# 6.0 - April 2014 preview
 
Scripting
ScriptingScripting
Scripting
 
Lecture 6, c++(complete reference,herbet sheidt)chapter-16
Lecture 6, c++(complete reference,herbet sheidt)chapter-16Lecture 6, c++(complete reference,herbet sheidt)chapter-16
Lecture 6, c++(complete reference,herbet sheidt)chapter-16
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
 
Final JAVA Practical of BCA SEM-5.
Final JAVA Practical of BCA SEM-5.Final JAVA Practical of BCA SEM-5.
Final JAVA Practical of BCA SEM-5.
 
Java File
Java FileJava File
Java File
 
Objective-c Runtime
Objective-c RuntimeObjective-c Runtime
Objective-c Runtime
 

Viewers also liked (8)

Het Milieu
Het MilieuHet Milieu
Het Milieu
 
Presentsimple
PresentsimplePresentsimple
Presentsimple
 
Het Milieu
Het MilieuHet Milieu
Het Milieu
 
telling the time
telling the timetelling the time
telling the time
 
Collioure
CollioureCollioure
Collioure
 
Law Scribe Corporate Profile Cs
Law Scribe Corporate Profile CsLaw Scribe Corporate Profile Cs
Law Scribe Corporate Profile Cs
 
La canya
La canyaLa canya
La canya
 
Plantem faves
Plantem favesPlantem faves
Plantem faves
 

Similar to ICSE 2011 - TamiFlex

WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Mar-2021_L14...
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Mar-2021_L14...WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Mar-2021_L14...
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Mar-2021_L14...
MaruMengesha
 
2 object orientation-copy
2 object orientation-copy2 object orientation-copy
2 object orientation-copy
Joel Campos
 

Similar to ICSE 2011 - TamiFlex (20)

Test Engine
Test EngineTest Engine
Test Engine
 
Comp 328 final guide
Comp 328 final guideComp 328 final guide
Comp 328 final guide
 
7
77
7
 
Test Engine
Test EngineTest Engine
Test Engine
 
Class 6 2ciclo
Class 6 2cicloClass 6 2ciclo
Class 6 2ciclo
 
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Mar-2021_L14...
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Mar-2021_L14...WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Mar-2021_L14...
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Mar-2021_L14...
 
Java Threads
Java ThreadsJava Threads
Java Threads
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with Javassist
 
Oop lecture5
Oop lecture5Oop lecture5
Oop lecture5
 
Review Questions for Exam 10182016 1. public class .pdf
Review Questions for Exam 10182016 1. public class .pdfReview Questions for Exam 10182016 1. public class .pdf
Review Questions for Exam 10182016 1. public class .pdf
 
Object-oriented Basics
Object-oriented BasicsObject-oriented Basics
Object-oriented Basics
 
5 Rmi Print
5  Rmi Print5  Rmi Print
5 Rmi Print
 
Scjp6.0
Scjp6.0Scjp6.0
Scjp6.0
 
Java Inheritance
Java InheritanceJava Inheritance
Java Inheritance
 
Constructor and destructor
Constructor and destructorConstructor and destructor
Constructor and destructor
 
Java programming lab_manual_by_rohit_jaiswar
Java programming lab_manual_by_rohit_jaiswarJava programming lab_manual_by_rohit_jaiswar
Java programming lab_manual_by_rohit_jaiswar
 
11slide.ppt
11slide.ppt11slide.ppt
11slide.ppt
 
2 object orientation-copy
2 object orientation-copy2 object orientation-copy
2 object orientation-copy
 
Java file
Java fileJava file
Java file
 
Intro to Java for C++ Developers
Intro to Java for C++ DevelopersIntro to Java for C++ Developers
Intro to Java for C++ Developers
 

Recently uploaded

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

ICSE 2011 - TamiFlex

  • 1. Taming Reflection Aiding Static Analysis in the Presence of Reflection and Custom Class Loaders Eric Bodden, Andreas Sewe, Jan Sinschek, Hela Oueslati and Mira Mezini
  • 2. necti ons!” ose d con rite to cl “D on’t w
  • 3. Reflective method calls public class Main { public static void main(String[] args) throws Exception { Connection c = new Connection(); Class c = Class.forName( "Evil" ); Method m = c.getMethod("doEvil", Connection.class); Evil.doEvil(c); m.invoke(null,c); c.write("ohoh..."); } public class Evil { public static void doEvil(Connection c) { c.close(); } } 3
  • 4. Reflective method calls public class Main { public static void main(String[] args) throws Exception { Connection c = new Connection(); Class c = Class.forName( "Evil" ); Method m = c.getMethod("doEvil", Connection.class); Evil.doEvil(c); m.invoke(null,c); c.write("ohoh..."); } public class Evil { hard to analyze statically! public static void doEvil(Connection c) { c.close(); } } 3
  • 5. Reflective method calls public class Main { public static void main(String[] args) throws Exception { Connection c = new Connection(); Class c = Class.forName( args[0] ); "Evil" Method m = c.getMethod("doEvil", Connection.class); Evil.doEvil(c); m.invoke(null,c); c.write("ohoh..."); } imp ossible public class Evil { hard to analyze statically! public static void doEvil(Connection c) { c.close(); } } 3
  • 6. Reflective method calls public class Main { public static void main(String[] args) throws Exception { Connection c = new Connection(); Class c = Class.forName( args[0] ); "Evil" Method m = c.getMethod("doEvil", Connection.class); Evil.doEvil(c); m.invoke(null,c); c.write("ohoh..."); } imp ossible public class Evil { hard to analyze statically! public static void doEvil(Connection c) { c.close(); } Present a pragmatic, } partial solution 3
  • 8. Uses of Reflection Extensibility Separate Compilation Runtime class generation “Hacking”: call private methods 5
  • 9. Reflection is... used a lot unsound to ignore often impossible to resolve
  • 10. Play-Out Boost Analyse & Play-In Transform 7
  • 11. y-O ut 1 :P la Step 8
  • 12. Play-Out public class Main { public static void main(String[] args) throws Exception { Connection c = new Connection(); Class c = Class.forName( "Evil" ); Method m = c.getMethod("doEvil", Connection.class); m.invoke(null,c); c.write("ohoh..."); } public class Evil { public static void doEvil(Connection c) { c.close(); } } 9
  • 13. Play-Out public class Main { public static void main(String[] args) throws Exception { Connection c = new Connection(); Class c = Class.forName( "Evil" ); Method m = c.getMethod("doEvil", Connection.class); m.invoke(null,c); c.write("ohoh..."); } public class Evil { $
javac
Main.java
 public static void doEvil(Connection c) { $
java
‐javaagent:poa‐trunk.jar=out
Main c.close(); } ============================================= } TamiFlex
Play‐Out
Agent
Version
trunk Found
2
new
log
entries. Log
file
written
to:
out/refl.log $
cat
out/refl.log
 Class.forName;Evil;Main.main;6 Method.invoke;<Evil:
void
doEvil(Connection)>;Main.main;8; 9
  • 14. Play-Out public class Main { public static void main(String[] args) throws Exception { Connection c = new Connection(); Class c = Class.forName( "Evil" ); Method m = c.getMethod("doEvil", Connection.class); m.invoke(null,c); c.write("ohoh..."); } public class Evil { $
javac
Main.java
 public static void doEvil(Connection c) { $
java
‐javaagent:poa‐trunk.jar=out
Main c.close(); } ============================================= } TamiFlex
Play‐Out
Agent
Version
trunk Found
2
new
log
entries. Log
file
written
to:
out/refl.log $
cat
out/refl.log
 Class.forName;Evil;Main.main;6 Method.invoke;<Evil:
void
doEvil(Connection)>;Main.main;8; kind of call 9
  • 15. Play-Out public class Main { public static void main(String[] args) throws Exception { Connection c = new Connection(); Class c = Class.forName( "Evil" ); Method m = c.getMethod("doEvil", Connection.class); m.invoke(null,c); c.write("ohoh..."); } public class Evil { $
javac
Main.java
 public static void doEvil(Connection c) { $
java
‐javaagent:poa‐trunk.jar=out
Main c.close(); } ============================================= } TamiFlex
Play‐Out
Agent
Version
trunk Found
2
new
log
entries. Log
file
written
to:
out/refl.log $
cat
out/refl.log
 Class.forName;Evil;Main.main;6 fully resolved Method.invoke;<Evil:
void
doEvil(Connection)>;Main.main;8; target of call 9
  • 16. Play-Out public class Main { public static void main(String[] args) throws Exception { Connection c = new Connection(); Class c = Class.forName( "Evil" ); Method m = c.getMethod("doEvil", Connection.class); m.invoke(null,c); c.write("ohoh..."); } public class Evil { $
javac
Main.java
 public static void doEvil(Connection c) { $
java
‐javaagent:poa‐trunk.jar=out
Main c.close(); } ============================================= } TamiFlex
Play‐Out
Agent
Version
trunk Found
2
new
log
entries. Log
file
written
to:
out/refl.log $
cat
out/refl.log
 Class.forName;Evil;Main.main;6 Method.invoke;<Evil:
void
doEvil(Connection)>;Main.main;8; location of call 9
  • 17. Play-Out public class Main { public static void main(String[] args) throws Exception { Connection c = new Connection(); Class c = Class.forName( "Evil" ); Method m = c.getMethod("doEvil", Connection.class); m.invoke(null,c); c.write("ohoh..."); } public class Evil { $
find
out
‐name
*.class public static void doEvil(Connection c) { out/com/apple/java/BackwardsCompatibility.class c.close(); } out/java/io/BufferedInputStream.class out/java/io/BufferedOutputStream.class } out/java/io/BufferedReader.class out/java/io/BufferedWriter.class out/java/io/ByteArrayInputStream.class out/java/io/ByteArrayOutputStream.class out/java/io/Closeable.class out/java/io/DataInput.class ... 9
  • 19. Why dump classes? Static analysis needs to know the code 10
  • 20. Why dump classes? $
java
‐jar
dacapo‐9.12‐bach.jar
fop =====
DaCapo
9.12
fop
starting
===== =====
DaCapo
9.12
fop
PASSED
in
2503
msec
===== Static analysis needs to know the code 10
  • 21. Why dump classes? $
java
‐jar
dacapo‐9.12‐bach.jar
fop =====
DaCapo
9.12
fop
starting
===== =====
DaCapo
9.12
fop
PASSED
in
2503
msec
===== Static analysis needs to know the code 10
  • 22. Play-out Agent Program ClassLoader Play‐Out
Agent 11
  • 23. Play-out Agent Program ClassLoader Main.class Play‐Out
Agent 11
  • 24. Play-out Agent load class java.lang.reflect.Method Program ClassLoader Play‐Out
Agent dump every loaded class to disk Main.class 11
  • 25. Play-out Agent load class java.lang.reflect.Method Program ClassLoader Method.class Play‐Out
Agent dump every loaded class to disk Main.class 11
  • 26. Play-out Agent load class java.lang.reflect.Method Program ClassLoader Method.class Play‐Out
Agent dump every loaded class to disk Main.class 11
  • 27. Play-out Agent load class java.lang.reflect.Method Program ClassLoader Method.class Play‐Out
Agent dump every loaded class to disk Main.class Method.class 11
  • 28. Play-out Agent load class java.lang.reflect.Method Program ClassLoader Method.class call to Method.invoke Play‐Out
Agent dump every loaded class to disk Main.class Method.class 11
  • 29. Play-out Agent load class java.lang.reflect.Method Program ClassLoader Method.class call to Method.invoke Play‐Out
Agent dump every loaded class to disk write entry Main.class to log file Method.class 11
  • 30. Play-out Agent load class java.lang.reflect.Method Program ClassLoader Method.class call to Method.invoke Play‐Out
Agent Constructor.class dump every loaded class to disk Class.class write entry Main.class Constructor.class to log file Method.class Class.class 11
  • 32. Booster transforms program into statically analyzable version public class Main { Connection.<init> public static void main(String[] args) throws Exception { ? Connection c = new Connection(); Class cl = Class.forName(args[0]); ? Method m = cl.getMethod("do"+"Evil", Connection.class); Class.forName Main.main m.invoke(null,c); c.write("ohoh..."); Class.getMethod } public class Evil { Method.invoke public static void doEvil(Connection c) { c.close(); } Connection.write } 13
  • 33. Booster transforms program into statically analyzable version public class Main { Connection.<init> public static void main(String[] args) throws Exception { ? Connection c = new Connection(); Class cl = Class.forName(args[0]); ? Method m = cl.getMethod("do"+"Evil", Connection.class); Class.forName Main.main m.invoke(null,c); c.write("ohoh..."); Class.getMethod } public class Evil { Method.invoke public static void doEvil(Connection c) { c.close(); } Connection.write } $
cat
out/refl.log
 Class.forName;Evil;Main.main;6 Method.invoke;<Evil:
void
doEvil(Connection)>;Main.main;8; 13
  • 34. Booster transforms program into statically analyzable version public class Main { public static void main(String[] args) throws Exception { Connection.<init> Connection c = new Connection(); Class cl; if(args[0].equals("Evil")) cl = Evil.class; else { Class.forName TamiFlexRT.warnClassForName(args[0]); Main.main cl = Class.forName(args[0]); } Class.getMethod Method m = cl.getMethod("do"+"Evil", Connection.class); if(m.getDeclaringClass().getName().equals("Evil") && Method.invoke m.getName().equals("doEvil")) Evil.doEvil(c); else { TamiFlexRT.warnMethodInvoke(m); Connection.write m.invoke(null,c); } c.write("ohoh..."); } Evil.doEvil Connection.close ... } 13
  • 35. Booster transforms program into statically analyzable version public class Main { public static void main(String[] args) throws Exception { Connection.<init> Connection c = new Connection(); Class cl; if(args[0].equals("Evil")) cl = Evil.class; else { Class.forName TamiFlexRT.warnClassForName(args[0]); Main.main cl = Class.forName(args[0]); } Class.getMethod Method m = cl.getMethod("do"+"Evil", Connection.class); if(m.getDeclaringClass().getName().equals("Evil") && Method.invoke m.getName().equals("doEvil")) Evil.doEvil(c); else { TamiFlexRT.warnMethodInvoke(m); Connection.write m.invoke(null,c); } c.write("ohoh..."); } Evil.doEvil Connection.close ... } 13
  • 36. Booster Implemented on top of Soot Operates on 3-address code (Jimple) generated from bytecode Input: class files recorded by play-out agent Emits class files of “boosted” program Some nitty-gritty details with respect to the use of non-standard class loaders (see paper) 14
  • 37. Booster Program ClassLoader Main.class Method.class Main.class Play‐Out
Agent Constructor.class dump every loaded class to disk Class.class write entry to log file Main.class 15
  • 38. Booster Program ClassLoader Main.class Method.class Main.class Play‐Out
Agent Constructor.class dump every loaded class to disk Class.class write entry to log file Booster Main.class Main.class 15
  • 39. Booster Program ClassLoader Main.class Method.class Main.class Play‐Out
Agent Main.class Constructor.class dump every loaded class to disk Class.class write entry Static Analysis to log file Booster Main.class Main.class 15
  • 40. Booster Program ClassLoader Main.class Method.class Main.class Play‐Out
Agent ? Main.class Constructor.class dump every loaded class to disk Class.class write entry Static Analysis to log file Booster Main.class Main.class 15
  • 41. Step 3: Pla y-In 16
  • 42. Play-in Agent load from somewhere, load class Main or generate Program Custom
 ClassLoader Play‐In
Agent Main.class 17
  • 43. Play-in Agent load from somewhere, load class Main or generate Program Custom
 ClassLoader Play‐In
Agent Main.class 17
  • 44. Play-in Agent load from somewhere, load class Main or generate Program Custom
 ClassLoader Main.class Play‐In
Agent Main.class 17
  • 45. Play-in Agent load from somewhere, load class Main or generate Program Custom
 ClassLoader Play‐In
Agent search Main.class transformed version of Main 17
  • 46. Play-in Agent load from somewhere, load class Main or generate Program Custom
 ClassLoader replace Main by Main.class transformed class Play‐In
Agent search transformed version of Main 17
  • 47. Just when we thought we were done...
  • 48. ge nerate d classes m ay bear ran d o mize d names! 19
  • 49. Play-in Agent Program Custom
 ClassLoader Play‐In
Agent C$42.class 20
  • 50. Play-in Agent Program Custom
 ClassLoader ≠ Play‐In
Agent C$42.class C$23.class 20
  • 51. Play-in Agent Program Custom
 ClassLoader C$23.class Play‐In
Agent C$42.class 20
  • 52. Solution Normalization: replace randomized name by normalized name in the log, the binaries, everywhere... Quite involved: classes to normalize may be interdependent Details in the paper More details in our Tech Report Yet more details in the source 21
  • 54. Evaluation an th is be s o u n d? How c 22
  • 55. Evaluation an th is be s o u n d? How c It’s not! But it’s sounder! 22
  • 56. Evaluation an th is be s o u n d? How c It’s not! But it’s sounder! It’s “representative”! 22
  • 57. Correctness static call graph ⊇ ∪{recorded call graph} ? 23
  • 58. Correctness static call graph ⊇ ∪{recorded call graph} ? computed with Soot/Spark recorded with JVMTI agent 23
  • 59. Correctness static call graph ⊇ ∪{recorded call graph} ? computed with Soot/Spark recorded with JVMTI agent Yes! (call graphs are representative; tested with Lhotak’s Call-graph comparison tool ProBe) 23
  • 60. Effectiveness: How much does log-file quality depend on program input? Dacapo “bach” release 24
  • 61. Effectiveness: How much does log-file quality depend on program input? Dacapo “bach” release 24
  • 62. Effectiveness: How much does log-file quality depend on program input? Dacapo “bach” release 24
  • 63. Effectiveness: How much does log-file quality depend on program input? Dacapo “bach” release 24
  • 64. Effectiveness: How much does log-file quality depend on program input? Dacapo “bach” release 24
  • 65. Effectiveness: How much does log-file quality depend on program input? Dacapo “bach” release 24
  • 66. Effectiveness: How much does log-file quality depend on program input? Dacapo “bach” release 24
  • 67. Effectiveness: How much does log-file quality depend on program input? Can now safely use static analyses on DaCapo: Warnings never triggered! 24
  • 68. Effectiveness: How much does log-file quality depend on program input? Other prominent programs/frameworks 25
  • 69. Effectiveness: How much does log-file quality depend on program input? Appro ach requ ires go o d “feature co verage” 26
  • 70. 3.00 2.62 2.00 1.22 1.18 1.02 1.02 1.08 1.06 1.09 1.03 1.05 1.04 1.00 1.00 Play-Out 1.00 vro ra ati k e ips fo p h2 on e x h arc pm d ow s p an soa xala n a b cl j yth ind e nfl e eb rade e lu lus su d tra t 3.00 2.00 1.12 1.09 1.06 1.06 1.04 1.05 1.03 1.00 1.04 1.03 1.04 1.00 1.00 Play-In 1.00 vro r a ati k e ips fo p h2 o n e x h arc pm d o w s p an soa xala n a b cl jyth i nd e nfl e eb rade e lu lus su d tra t
  • 71. Related Work Partial evaluation Braux & Noyé, PEPM 1999 String analysis Christensen et al., SAS 2003 Livshits et al., APLAS 2005 Application extraction Tip et. al, TOPLAS 2002 “Finding the code” Bessey et. al (Coverity), CACM 2010 28
  • 72. Related Work Online Call-Graph Construction Hirzel et al., TOPLAS 2007 Blended Analysis Dufour et al., ISSTA 2007 Runtime type inference in PRuby Furr et al., OOPSLA 2009 29
  • 73. http://tamiflex.googlecode.com/ First external users Cheng Zhang, SJTU Saswat Anand, Georgia Tech Jochen Huck, KIT Play-out, Soot, Play-In Play-out, Soot Play-out, Soot Call frequency analysis Points-to, Symb. Exec. Side-Effects, Dominance
  • 74. http://tamiflex.googlecode.com/ Play-Out Boost Analyse & Play-In Transform Correct Effective Efficient
  • 75. http://tamiflex.googlecode.com/ MODULARITY - aosd 2012 submit to 2nd of 3 submission deadlines: July 14th Record number of submitted & accepted July 17th-21st, 2011, Toronto papers attend

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. With this, even works for runtime-generated classes!\n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  141. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  142. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  143. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  144. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  145. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  146. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  147. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  148. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  149. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  150. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  151. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  152. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  153. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  154. TODO: Warnings never triggered\nTODO: Venn: num of Methods or num of edges?\n
  155. \n
  156. \n
  157. TODO: redo with Numbers, split up into POA and PIA\n
  158. \n
  159. TODO: talk about relative number of resolved call sites\n
  160. \n
  161. \n
  162. \n
  163. \n