/
Finding Programming Errors Earlier by Evaluating Runtime Monitors Ahead-of-Time Finding Programming Errors Earlier by Evaluating Runtime Monitors Ahead-of-Time

Finding Programming Errors Earlier by Evaluating Runtime Monitors Ahead-of-Time - PowerPoint Presentation

okelly
okelly . @okelly
Follow
0 views
Uploaded On 2024-03-15

Finding Programming Errors Earlier by Evaluating Runtime Monitors Ahead-of-Time - PPT Presentation

McGill University Eric Bodden University of Waterloo Patrick Lam McGill University Laurie Hendren 3 abc compiler property specification No missed violations 4 Problem 1 Potentially large ID: 1048724

amp iterator line hasnext iterator amp hasnext line call return oopsla foo null false positive ismu static void tracematch

Share:

Link:

Embed:

Download Presentation from below link

Download Presentation The PPT/PDF document "Finding Programming Errors Earlier by Ev..." is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

1. Finding Programming Errors Earlier by Evaluating Runtime Monitors Ahead-of-TimeMcGill University Eric BoddenUniversity of Waterloo Patrick LamMcGill University Laurie Hendren

2.

3. 3abc compilerpropertyspecificationNo missed violations!

4. 4Problem 1:Potentially largeruntime overhead

5. 5Problem 2:Dynamic, with no static guarantees

6. bug patternspecification6Novel staticprogram analysisNo missed violations!Optimized Runtime

7. Problem 3:Existing sound static approaches have many false positives

8. bug patternspecification8Novel staticprogram analysisClassification

9. Most simple example: HasNextDon't call next() twice on an Iterator iwithout calling hasNext() in between!9

10. Tracematch HasNexttracematch(Iterator i) {}10Allan et al., OOPSLA 05

11. Tracematch HasNexttracematch(Iterator i) { sym hasNext after returning: call(* Iterator.hasNext()) && target(i);sym next after returning: call(* Iterator.next()) && target(i);}11Allan et al., OOPSLA 05

12. Tracematch HasNexttracematch(Iterator i) { sym hasNext after returning: call(* Iterator.hasNext()) && target(i);sym next after returning: call(* Iterator.next()) && target(i); next next}12Allan et al., OOPSLA 05

13. Tracematch HasNexttracematch(Iterator i) { sym hasNext after returning: call(* Iterator.hasNext()) && target(i);sym next after returning: call(* Iterator.next()) && target(i); next next { System.out.println( “Called ‘next’ twice on”+i+“!”); }}13Allan et al., OOPSLA 05

14. nextnexti1.next();i1.hasNext();i1.next();i1.next();truefalsei = o(i1)falsei = o(i1)14{ System.out.println( “Called ‘next’ twice on”+i+“!”);}i = o(i1)next, hasNexti = o(i1)

15.

16. Novel static program analyses

17. Trade-off: Speed vs. Precision17void foo(Iterator i) {}

18. 18void foo(Iterator i) {}Summary Information?What events ever occur on i?For every program variable i:“Both hasNext() and next()”Can program variable j point tothe same object as i?“Only hasNext()”

19. Problem 1: Missing info at method entry19void foo(Iterator i) { i.next();}

20. Key observation!20012nextnextnext, hasNextPossible targets of “next”012Possible targets of “hasNext”012 “hasNext” is a state-determining symbol!

21. Key observation!21Benchmarks: 68% of symbolsare state-determining

22. 22void foo(Iterator i) { if(i.hasNext()) { i.next(); }}Problem 1: Missing info at method entry

23. 23void foo(Iterator i) { if(i.hasNext()) { Iterator i2=i; i2.next(); }}Problem 2: Aliasing

24. Object representatives24 WholeprogramCurrent methodOther methodMust-not-alias (points-to)Must-aliasMust-not-aliasMustMust-noto1o2o3Must (Dummy)Don’tknow Precision where we can afford itSpeed where we need itFS:FI:

25. Problem 3: Outgoing method calls?25void foo(Iterator i) { if(i.hasNext()) { bar(i); i.next(); }}bar(i) may only call hasNext() on i!Summary Information

26. Problem 4: Continuation of control flow26void foo(Iterator i) { if(i.hasNext()) { i.next(); }}void baz(Iterator i) { foo(i); i.next();}Can we remove the instrumentation here?NO!Rest of program may call next() on i!Summary InformationNO!No missed violations at runtime!

27. Let the fun begin…binding multiple objects!For every Collection c and Iterator i:Don't modify c while i is used on c.27

28. void whiz(Collection c1){ Iterator i1 = c1.iterator(); i1.next();}Let the fun begin…binding multiple objects!28

29. Solution: "Uniqueness Check"Prove that:i = o(i1)  c = o(c1)Requires clever combination of pointer analyses (using object representatives).29Summary Information

30. Benchmarks - Tracematches30ASyncIterationHasNextElemFailSafeEnumLeakingSyncFailSafeIterReaderHashMapWriterHasNext

31. Benchmark programs31antlrhsqldbbloatjythonchartluceneeclipsepmdfopxalan… and SciMark (with 4 extra tracematches)DaCapo:

32. |.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|..|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|..|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|..32Results – Elimination of potential failure points103 program/tracematch combinationsstatic guarantees in 84 casesin 14 cases: less than10 potential failure points

33. Classification of potential failure points

34.

35. 35HasNext:next - <InductionVarAnalyzer.isMu(..)> @ line 217next - <InductionVarAnalyzer.isMu(..)> @ line 218HasNext:next - <CodeGenerator.removeEmptyBl(..)> @ line 587hasNext - <CodeGenerator.removeEmptyBl(..)> @ line 586Analysis annotates potential failure points

36. 36HasNext: features []next - <InductionVarAnalyzer.isMu(..)> @ line 217next - <InductionVarAnalyzer.isMu(..)> @ line 218HasNext: features [CALL]next - <CodeGenerator.removeEmptyBl(..)> @ line 587hasNext - <CodeGenerator.removeEmptyBl(..)> @ line 586Analysis annotates potential failure points

37. Features: Reasons for imprecisionCALLABORTEDNO_CONTEXTDELEGATECONTINUATIONDYNAMIC_LOADINGOVERLAPS37

38. 38HasNext: features [], ACTUALnext - <InductionVarAnalyzer.isMu(..)> @ line 217next - <InductionVarAnalyzer.isMu(..)> @ line 218HasNext: features [CALL]next - <CodeGenerator.removeEmptyBl(..)> @ line 587hasNext - <CodeGenerator.removeEmptyBl(..)> @ line 586Manually annotated actual failure points

39. 39CALL = 0| ABORTED = 0| | DELEGATE = 0| | | NO_CONTEXT = 0: TRUE_POSITIVE (11.0/1.0)| | | NO_CONTEXT = 1: FALSE_POSITIVE (4.0/1.0)| | DELEGATE = 1: FALSE_POSITIVE (10.0)| ABORTED = 1: FALSE_POSITIVE (30.0)CALL = 1: FALSE_POSITIVE (406.0/1.0)Weka machine learning kit

40. 40Results – FilteringFound 5 programs with bugs or questionable code.

41.

42. Related work: TypestateStatic and hybrid verification of typestate props.Typestate (Strom & Yemini, TSE Vol 12 No. 1, 86)Fugue for .NET (DeLine & Fähndrich, ECOOP 04)Typest. & Aliasing (Bierhoff & Aldrich, OOPSLA 07)Hybrid static/dynamic (Dwyer & Purandare, ASE 07)42

43. Related work: Tracematch-likeFlow-sensitive analysis of TracematchesNaeem and Lhoták, OOPSLA 08Other state-based runtime-verification tools for JavaJavaMOP (Chen & Roşu, OOPSLA 08)PQL (Martin, Livshits & Lam, OOPSLA 05)PTQL (Goldsmith, O’Callahan & Aiken, OOPSLA 05)43

44. Related work: Static checkersStatic checkersFindBugs (Hovemeyer & Pugh, OOPSLA 04)PMD (http://pmd.sf.net/)Pre and postconditions, invariantsESC/Java (Flanagan et al., PLDI 02)Java Modeling Language (JML)Specialized interprocedural analysesJlint (http://artho.com/jlint/)Comparison: Rutar et al., ISSRE 0444

45. Related work: Invariant mining and checkingDynamic invariant inference and checkingDaikon (Ernst et al., TSE Vol 27. No 2, 01)DIDUCE (Hangal & Lam, ICSE 02)JADET (Wasylkowski et al., FSE 07)Spec. Mining (Ammons et al., POPL 02)Static rule mining and checkingPR-Miner (Li & Zhou, FSE 05)Houdini (Flanagan & Leino, FME 01)45

46. Special thanks to…Co-workersOndřej LhotákNomair NaeemMaintainers of Tracematch implementationPavel AvgustinovJulian Tibble46

47. www.aspectbench.orgwww.bodden.de

48.

49. private final void FillBuff() { ... try { if ((i = inputStream.read(...)) == -1) { inputStream.close(); throw new java.io.IOException(); } else maxNextCharInd += i; return; } ... }Jython / Reader (1/2)

50. Jython / Reader (2/2)50static String getLine(BufferedReader reader, int line) { if (reader == null) return ""; try { String text=null; for(int i=0; i < line; i++) { text = reader.readLine(); } return text; } catch (IOException ioe) { return null; }}

51. bloat-HasNextpublic Block isMu(...) {... final Iterator iter = cfg.preds(phi.block()).iterator(); final Block pred1 = (Block) iter.next(); final Block pred2 = (Block) iter.next();

52. pmd / HasNext (old version)52private List markUsages(IDataFlowNode inode) { ... for (Iterator k = ((List)entry.getValue()) .iterator();k.hasNext();) { addAccess(k, inode); } ...}...private void addAccess(Iterator k, IDataFlowNode inode) { NameOccurrence occurrence = (NameOccurrence) k.next(); ... }

53. pmd / HasNext (fixed version)53private List markUsages(IDataFlowNode inode) { ... for (NameOccurrence occurrence: entry.getValue()) { addAccess(occurrence, inode); } ...}...private void addAccess(NameOccurrence occurrence, IDataFlowNode inode) { ... }

54. while (c == null && enumMap.hasMoreElements()) { ... if (!enumC.hasMoreElements()) c = null;}// At this point, c == null if there are no more elements,// and otherwise is the first collection with a free element// (with enumC set up to return that element).if (c == null) { // no more elements, so return null; return (null);} else { Perm answer = (Perm) enumC.nextElement(); ...Eclipse, false positive

55. Jython / hasNext (delegate)55public Iterator iterator() { return new Iterator() { Iterator i = list.iterator(); public void remove() { throw new UnsupportedOperationException(); } public boolean hasNext() { return i.hasNext(); } public Object next() { return i.next(); } };}

56. 56Results – Static analysis timeAverage total: 6 minutesMax total: 20 minutes

57. public Object next(){}Delegating calls57inner.next()public Object next()DELEGATE

58. boolean foo(Iterator i, Iterator j){}Reasons for imprecision58bar(i)void bar(..)CALL

59. boolean foz(Set c1, Set c2){}i1 = c1.iterator();i2 = c2.iterator();Reasons for imprecision59NO_CONTEXTpublic Iterator iterator() { return new HashIterator();}

60. boolean baz(Iterator i, Iterator j){}Reasons for imprecision60ABORTED123453000

61. Using alias queries to reduce false-positive rate61x = r1x ≠ r1x = r2x = r1 ≡ x = r2falsex ≠ r2falsex ≠ r1 ≡ x ≠ r2Assume we know r1 and r2 must-alias,r1 occurs in some constraint bound to xand we see an event that binds x to r2.

62. Using alias queries to reduce false-positive rate62x = r1x ≠ r1x = r2falsex = r2x ≠ r2x = r1x ≠ r1 ^ x ≠ r2Assume we know r1 and r2 must-not-alias,r1 occurs in some constraint bound to xand we see an event that binds x to r2.