Effective Soundness-Guided Reflection Analysis Yue Li , Tian Tan and Jingling Xue Complier Research Group @ UNSW, Australia September 10, 2015 SAS 2015 Saint-Malo
Static analysis for OO in practice ?
Static analysis for OO in practice ? re re re … reflection !
Class Person { void setName(String nm) {…}; … … } Person p = new Person(); p.setName(“John”);
Class Person { void setName(String nm) {…}; … … } Person p = new Person(); p.setName(“John”);
Class Person { void setName(String nm) {…}; … … } Person p = new Person(); p.setName(“John”);
Class Person { void setName(String nm) {…}; … … } Person p = new Person(); class p.setName(“John”); field method
Class Person { void setName(String nm) {…}; … … } Person p = new Person(); class p.setName(“John”); field method
Class c = Class.forName(“Person”); Method m = c.getMethod(“setName”, …); Object p = c.newInstance(); m.invoke(p, “John”); Class Person { void setName(String nm) {…}; … … } Person p = new Person(); class p.setName(“John”); field method
Class c = Class.forName(“Person”); Method m = c.getMethod(“setName”, …); Object p = c.newInstance(); m.invoke(p, “John”); Class Person { void setName(String nm) {…}; … … Compile Time } Person p = new Person(); class p.setName(“John”); field method
Class c = Class.forName(“Person”); Method m = c.getMethod(“setName”, …); Object p = c.newInstance(); m.invoke(p, “John”); Class Person { void setName(String nm) {…}; … … Compile Time } Person p = new Person(); class p.setName(“John”); field method
Class c = Class.forName(“Person”); Method m = c.getMethod(“setName”, …); Runtime Object p = c.newInstance(); m.invoke(p, “John”); Class Person { void setName(String nm) {…}; … … Compile Time } Person p = new Person(); class p.setName(“John”); field method
n o i t c e t e D g u B Class c = Class.forName(cName); Method m = c.getMethod(mName, …); A a = new A(); m.invoke(a, …);
n o i t c e t e D g u B Class c = Class.forName(cName); Method m = c.getMethod(mName, …); A a = new A(); m.invoke(a, …); Method 1 Method 2 Method 3 Bug
n o i t c e t e D g u B Class c = Class.forName(cName); Method m = c.getMethod(mName, …); A a = new A(); m.invoke(a, …); Method 1 Method 2 Method 3 Soundness Bug
Soundness
Soundness ECOOP’14 ICSE’11 OOPSLA’09 APLAS’05
Soundness Best-Effort ECOOP’14 ICSE’11 OOPSLA’09 APLAS’05
Soundness Best-Effort SAS’15 ECOOP’14 ICSE’11 OOPSLA’09 APLAS’05
Soundness Best-Effort SAS’15 ECOOP’14 ICSE’11 OOPSLA’09 More sound 1 APLAS’05
Unsoundness Soundness Best-Effort SAS’15 ECOOP’14 ICSE’11 OOPSLA’09 More sound 1 APLAS’05
Unsoundness Soundness Best-Effort SAS’15 ECOOP’14 ICSE’11 OOPSLA’09 More sound 1 APLAS’05 Controllable 2
Unsoundness Soundness Best-Effort SAS’15 ECOOP’14 Soundness-Guided ICSE’11 OOPSLA’09 More sound 1 APLAS’05 Controllable 2
More sound Controllable 1 2
More sound 1
The Challenging Problem unknown Class c = Class.forName(cName) i: Object v = c1.newInstance( )
Existing Approach unknown Class c = Class.forName(cName) i: Object v = c1.newInstance( ) A a = (A) v2 Intra-procedural post-dominant cast operations
Existing Approach unknown Class c = Class.forName(cName) c A i: Object v = c1.newInstance( ) A a = (A) v2 Intra-procedural post-dominant cast operations
Existing Approach unknown Class c = Class.forName(cName) c A i: Object v = c1.newInstance( ) A a = (A) v2 Intra-procedural post-dominant cast operations only works for this intra-post-dominance pattern
Existing Approach unknown Class c = Class.forName(cName) c A d d e e r r o o n n i: Object v = c1.newInstance( ) g g I I A a = (A) v2 Intra-procedural post-dominant cast operations only works for this intra-post-dominance pattern
Lazy Heap Modeling (LHM)
Lazy Heap Modeling (LHM) Observation A reflectively created object (returned by newInstance()) is usually used in two cases in practice
Lazy Heap Modeling (LHM) Observation A reflectively created object (returned by newInstance()) is usually used in two cases in practice Intuition The side effect of a newInstance() call can be modeled lazily at these usage points
Lazy Heap Modeling (LHM) unknown Class c = Class.forName(cName) i: Object v = c1.newInstance( )
Lazy Heap Modeling (LHM) unknown Class c = Class.forName(cName) c u i: Object v = c1.newInstance( )
Lazy Heap Modeling (LHM) unknown Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) o u i
Lazy Heap Modeling (LHM) unknown Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) o u i Abstract Heap Objects of newInstance() are created lazily ( at LHM points )
Lazy Heap Modeling (LHM) unknown Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) o u i A a = (A) v1 B b = (B) v2 Case ( I ) Abstract Heap Objects of newInstance() are created lazily ( at LHM points )
Lazy Heap Modeling (LHM) unknown Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) o u i A a = (A) v1 B b = (B) v2 Case ( I ) Abstract Heap Objects | | | Type Object Location Pointed by | a of newInstance() A | o A | i i are created lazily b, v4 | o B | i | o B i b B | | | B i i ( at LHM points )
Lazy Heap Modeling (LHM) unknown Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) o u i A a = (A) v1 B b = (B) v2 m1.invoke(v3, args) Case ( I ) Case ( II ) Abstract Heap Objects | | | Type Object Location Pointed by | a of newInstance() A | o A | i i are created lazily b, v4 | o B | i | o B i b B | | | B i i ( at LHM points )
Lazy Heap Modeling (LHM) unknown Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) Method m = c2.getDeclaredMethod(mName, ...) o u i A a = (A) v1 B b = (B) v2 m1.invoke(v3, args) Case ( I ) Case ( II ) Abstract Heap Objects | | | Type Object Location Pointed by | a of newInstance() A | o A | i i are created lazily b, v4 | o B | i | o B i b B | | | B i i ( at LHM points )
Lazy Heap Modeling (LHM) unknown c D Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) Method m = c2.getDeclaredMethod(mName, ...) o u i A a = (A) v1 B b = (B) v2 m1.invoke(v3, args) Case ( I ) Case ( II ) Abstract Heap Objects | | | Type Object Location Pointed by | a of newInstance() A | o A | i i are created lazily b, v4 | o B | i | o B i b B | | | B i i ( at LHM points )
Lazy Heap Modeling (LHM) unknown c D Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) Method m = c2.getDeclaredMethod(mName, ...) o u i A a = (A) v1 B b = (B) v2 m1.invoke(v3, args) v3.mName(args) Case ( I ) Case ( II ) Abstract Heap Objects | | | Type Object Location Pointed by | a of newInstance() A | o A | i i are created lazily b, v4 | o B | i | o B i b B | | | B i i ( at LHM points )
Lazy Heap Modeling (LHM) unknown c D Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) Method m = c2.getDeclaredMethod(mName, ...) o u i A a = (A) v1 B b = (B) v2 m1.invoke(v3, args) v3.mName(args) Case ( I ) Case ( II ) Abstract Heap Objects | | | Type Object Location Pointed by | a of newInstance() A | o A | i i are created lazily b, v4 | o B | i | o B i b B | | | B i i ( at LHM points ) D | o D | v3 | i i
Lazy Heap Modeling (LHM) unknown c D Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) Method m = c2.getDeclaredMethod(mName, ...) o u i A a = (A) v1 B b = (B) v2 m1.invoke(v3, args) v3.mName(args) Case ( I ) Case ( II ) Abstract Heap Objects | | | Type Object Location Pointed by | a of newInstance() A | o A | i i are created lazily b, v4 | o B | i | o B i b B | | | B i i ( at LHM points ) D | o D | v3 | i i ? B | o B v3 | i | i
Lazy Heap Modeling (LHM) unknown c D Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) Method m = c2.getDeclaredMethod(mName, ...) o u i A a = (A) v1 B b = (B) v2 m1.invoke(v3, args) v3.mName(args) Case ( I ) Case ( II ) Abstract Heap Objects | | | Type Object Location Pointed by | a of newInstance() A | o A | i i are created lazily b, v4 | o B | i | o B i b B | | | B i i ( at LHM points ) D | o D | v3 | i i X ? B | o B v3 | i | i
Lazy Heap Modeling (LHM) unknown c D Class c = Class.forName(cName) c u i: Object v = c1.newInstance( ) Method m = c2.getDeclaredMethod(mName, ...) o u i A a = (A) v1 B b = (B) v2 m1.invoke(v3, args) v3.mName(args) Case ( I ) Case ( II ) Abstract Heap Objects | | | Type Object Location Pointed by | a of newInstance() A | o A | i i are created lazily b, v4 | o B | i | o B i b B | | | B i i ( at LHM points ) D | o D | v3 | i i X ? B | o B v3 | i | i o B i b, v3 | | | B i
Recommend
More recommend