needs effective finitary representation failed
play

. Needs effective (finitary) representation .. Failed Termination - PDF document

Runtime Errors Proving Non-Termination Ashutosh K. Gupta Thomas A. Henzinger Rupak Majumdar MPI-SWS EPFL UCLA Andrey Rybalchenko Ru-Gang Xu MPI-SWS UCLA 2 Non-Termination Errors Proving Non-Termination Search for infinite


  1. Runtime Errors Proving Non-Termination Ashutosh K. Gupta Thomas A. Henzinger Rupak Majumdar MPI-SWS EPFL UCLA Andrey Rybalchenko Ru-Gang Xu MPI-SWS UCLA 2 Non-Termination Errors Proving Non-Termination • Search for infinite executions …. • Needs effective (finitary) representation .. Failed Termination Proof vs. Non- TNT: Testing Non-Termination Termination • Successful termination provers: Tool for proving non-termination PolyRank, Terminator, ACL2, TerminWeb, AProVE, … • Inherently incomplete algorithms Input leading to C program • Failed termination proof ≠ non-termination TNT non-termination Don’t know Proved Proved Non- Proved Non- Terminating Terminating Terminating Terminating Non-Terminating Terminating Non-Terminating

  2. Outline Example: Non-termination Error • Input to TNT: – Mondriaan memory protection system • Example: • (early version courtesy: E. Witchel) – Uses recursion for basic operation – Non-termination error in a memory protection system – Termination required • TNT algorithm: • Output by TNT: – Lasso search – non-termination bug (now fixed) in _mmpt_insert procedure: – Recurrent set computation cyclic sequences of calls to _mmpt_insert ( … , 0, 3, … …, TAB_ROOT , 0, … ) Non-Termination in _mmpt_insert Non-Termination in _mmpt_insert (first call) void _mmpt_insert (struct* mmpt, base, len, prot, tab_t* tab, level, … ) { void _mmpt_insert (struct* mmpt, 0, 3, prot, TAB_ROOT , 0, … ) { if(len == 0) return; // Exit condition if(len == 0) return; // Exit condition int idx = make_idx(mmpt, base, level); int idx = make_idx(mmpt, base, level); if(level < 2 && … … … && len >= tab_len(mmpt, level + 1)) { if(level < 2 && … … … && len >= tab_len(mmpt, level + 1)) { … … … … … … } else if(level < 2 && tab[idx] && !uentry_is_data(mmpt, tab[idx])) { } else if(level < 2 && tab[idx] && !uentry_is_data(mmpt, tab[idx])) { _mmpt_insert (mmpt, base, len, prot, (tab_t*)tab[idx], level + 1, …); _mmpt_insert (mmpt, base, len, prot, (tab_t*)tab[idx], level + 1, …); } else if(level < 2 && … … … ) { } else if(level < 2 && … … … ) { … … … … … … } else { } else { for(; len >= subblock_len(mmpt, level) && … … … ; … … … ) { for(; len >= subblock_len(mmpt, level) && … … … ; … … … ) { … … … … … … } } _mmpt_insert (mmpt, base, len, prot, mmpt->tab, 0, …); _mmpt_insert (mmpt, base, len, prot, mmpt->tab, 0, …); } } } } Non-Termination in _mmpt_insert Non-Termination in _mmpt_insert (first call) (second call) void _mmpt_insert (struct* mmpt, 0, 3, prot, TAB_ROOT , 0, … ) { void _mmpt_insert (struct* mmpt, 0, 3, prot, TAB_MID , 1, … ) { if( 3 == 0) return; // Exit condition if(len == 0) return; // Exit condition int 0 = make_idx(mmpt, 0, 0); int idx = make_idx(mmpt, base, level); if( 0 < 2 && … … … && 3 >= 4MB ) { if(level < 2 && … … … && len >= tab_len(mmpt, level + 1)) { … … … … … … } else if( 0 < 2 && tab[ 0 ] && !uentry_is_data(mmpt, tab[ 0 ])) { } else if(level < 2 && tab[idx] && !uentry_is_data(mmpt, tab[idx])) { _mmpt_insert (mmpt, 0, 3, prot, (tab_t*)tab[ 0 ], 0 + 1, …); _mmpt_insert (mmpt, base, len, prot, (tab_t*)tab[idx], level + 1, …); } else if(level < 2 && … … … ) { } else if(level < 2 && … … … ) { … … … … … … } else { } else { for(; len >= subblock_len(mmpt, level) && … … … ; … … … ) { for(; len >= subblock_len(mmpt, level) && … … … ; … … … ) { … … … … … … } } _mmpt_insert (mmpt, base, len, prot, mmpt->tab, 0, …); _mmpt_insert (mmpt, base, len, prot, mmpt->tab, 0, …); } } } }

  3. Non-Termination in _mmpt_insert Non-Termination in _mmpt_insert (second call) (third call) void _mmpt_insert (struct* mmpt, 0, 3, prot, TAB_MID , 1, … ) { void _mmpt_insert (struct* mmpt, 0, 3, prot, TAB_LEAF , 2, … ) { if( 3 == 0) return; // Exit condition if(len == 0) return; // Exit condition int 0 = make_idx(mmpt, 0, 1); int idx = make_idx(mmpt, base, level); if( 1 < 2 && … … … && 3 >= 4KB ) { if( level < 2 && … … … && len >= tab_len(mmpt, level + 1)) { … … … … … … } else if( 1 < 2 && tab[ 0 ] && !uentry_is_data(mmpt, tab[ 0 ])) { } else if( level < 2 && tab[idx] && !uentry_is_data(mmpt, tab[idx])) { _mmpt_insert (mmpt, 0, 3, prot, (tab_t*)tab[ 0 ], 1 + 1, …); _mmpt_insert (mmpt, base, len, prot, (tab_t*)tab[idx], level + 1, …); } else if(level < 2 && … … … ) { } else if( level < 2 && … … … ) { … … … … … … } else { } else { for(; len >= subblock_len(mmpt, level) && … … … ; … … … ) { for(; len >= subblock_len(mmpt, level) && … … … ; … … … ) { … … … … … … } } _mmpt_insert (mmpt, base, len, prot, mmpt->tab, 0, …); _mmpt_insert (mmpt, base, len, prot, mmpt->tab, 0, …); } } } } Non-Termination in _mmpt_insert What does TNT do? (third call) void _mmpt_insert (struct* mmpt, 0, 3, prot, TAB_LEAF , 2, … ) { if( 3 == 0) return; // Exit condition • TNT finds a cyclic sequence of calls to _mmpt_insert int 0 = make_idx(mmpt, 0, 2); if( 2 < 2 && … … … && 3 >= tab_len(mmpt, 2 + 1)) { • The sequence is lasso – shaped … … … } else if( 2 < 2 && tab[idx] && !uentry_is_data(mmpt, tab[idx])) { level=0 level=1 level=2 level=0 _mmpt_insert (mmpt, base, len, prot, (tab_t*)tab[idx], level + 1, …); } else if( 2 < 2 && … … … ) { … … … Recursive call sequence } else { for(; 3 >= 4 && … … … ; … … … ) { • Non-termination is proved by analyzing the lasso Same … … … – same valuation of input parameters after the call cycle Parameters as } we started _mmpt_insert (mmpt, 0, 3, prot, TAB_ROOT , 0, …); } } Paths and Executions Outline: a: x = 0; x=0 b: while(x>=0){ c: x=x + 1; x=1 x=2 x=3 } • Search for lassos a: x = 0; x=0 • Prove a lasso is non-terminating through recurrent sets c: x=x + 1; x=1 c: x=x + 1; x=2 c: x=x + 1; x=3 Path = seq. of statements Execution = seq. of states

  4. Lassos What do infinite paths look like? Stem • Pair of paths: (stem, loop) • General paths: • Represents infinite periodic path: e.g. stmtA Loop a: stmtA stem(loop) ω stmtB 2 stmtC 3 stmtB 5 stmtC 7 … while( … ){ Stem a if( … ) a: x = 0; • Periodic paths or Lassos: x=0; x=0; b: stmtB b: while(x>=0){ e.g. stmtA stmtB stmtC stmtB stmtC b else c: x=x + 1; … c: stmtC } Loop assume(x>=0); assume(x>=0); x=x+1; } c c x=x+1; stmtA(stmtB stmtC) ω • Lasso = ( x=0; , assume(x>=0) ; x=x+1; ) • TNT only considers periodic paths TNT Algorithm Lasso Search • Find lassos by symbolic execution • Implementation similar to DART, CUTE, SAGE, … • Two-step algorithm: 1. Search for feasible lassos Stem • Uses symbolic execution … … a: while( … ){ • Quickly find candidates for non-termination b: while( … ){ … … Loo } 2. Check each lasso for non-termination p } • Uses SAT and constraint solving … • Precise reasoning on small program fragments Recurrent Sets Outline: • Proves non-termination using inductive argument • Set of states RecSet is recurrent for relation ρ (x, x’) if: • Lasso search – non-empty � – some successor RecSet � of each state is in RecSet • Recurrent set computation � Theorem: ρ (x, x’) is non-terminating iff there exists RecSet . 24

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend