210 likes | 318 Views
Model Checking C# Code: A Translation Approach. Contents. Overview Model Structure Key Features Flow Control State Representation Thread management What's Next. Overview. C Source Code Model Checkers: BLAST, SLAM and CBMC etc
E N D
Contents • Overview • Model Structure • Key Features • Flow Control • State Representation • Thread management • What's Next
Overview • C Source Code Model Checkers: BLAST, SLAM and CBMC etc • Translate to Boolean Program or CIL (C Intermediate Language) • use Theorem Prover or SAT Solver to check predicates • Translate to Promela and use SPIN to check • Java and C# Model Checkers • Java PathFinder • MoonWalker • act as a virtual machine to "run" the program
Objectives • Going down to byte-code level might not be necessary • PAT is a general Model Checker with good performance and extensibility • PAT can import C# library, the polymorphism could be handled smoothly and efficiently Extra • improve the traceability for testing, model checking and debugging. • Refinement checking to ensure consistency (different dev phases or branches)
Flow Control • Statement • Branch • Loop • Block of Code • Return • Exception
{... statement1; statement2; ... } if(cond) {//block 1} else {//block 2} Block(..) = ((tau{statement1;} -> Skip); ((tau{statement1;} -> Skip); ... )); if (cond) { Block_1(..)} else { Block_2(..) } Flow Control
for(init; cond; increment) {//block 1} For_1(..) = Block_1(); increment; if(Cond) {For_1(..)} else {Skip}; ... init; if(cond) For_1(...); ... Flow Control
State Representation • Classes and Objects • Fields remain • Methods: Based on defined atomicity
class Philosopher { int name; Fork left; Fork right; } class Philosopher : ExpressionValue { public int name; public int Get_name() {return name; } public void Set_name(int val) {name = val; } public int left; public int Get_left() {return left; } public void Set_left(int val) {left = val; } ... State Representation
State Representation public class Memory : ExpressionValue {... public int Philosopher_Get_name(int obj) { return philosopherList.GetObj(obj).Get_name(); } public void Philosopher_Set_name(int obj, int val) { philosopherList.GetObj(obj).Set_name(val); } public int Philosopher_Get_left(int obj) { return philosopherList.GetObj(obj).Get_left(); } public void Philosopher_Set_left(int obj, int val) { PhilosopherList.GetObj(obj).Set_left(val); }... }
Thread Management CreateNewThread() = create_thread?ti.pid.obj -> NewThread(ti, pid, obj); NewThread(ti, pid, obj) = case { (ti == 1) : Philosopher_run(pid, obj) default: Skip } || CreateNewThread(); Sys() = Main() || CreateNewThread();
...//origin Thread newThread = new Thread(new ThreadStart(run)); newThread.Start(); ... ...//translated ((create_thread!1.pid.objx -> Skip); (atomic {tau{cpid++} -> Philosopher_run_chan_in!cpid.objx -> Skip}; ... Philosopher_run() = (Philosopher_run_chan_in?pid.obj -> ... Thread Management
Lock Fork_Lock(pid, obj) = [0 == memory.Fork_Get_LOCK(obj)] ((tau{ memory.Fork_Set_LOCK(obj, pid); } -> Skip) ); Fork_Unlock(pid, obj) = assert(memory.Fork_Get_LOCK(obj) == pid); ((tau{ memory.Fork_Set_LOCK(obj, 0); } -> Skip) );
(Fork_Lock(pid, memory.Philosopher_Get_left(obj)); (Fork_Lock(pid, memory.Philosopher_Get_right(obj)); ... (Fork_Unlock(pid, memory.Philosopher_Get_right(obj)); (Fork_Unlock(pid, memory.Philosopher_Get_left(obj)) Lock lock (left) { lock (right) { // eat! } }
Parameter Pass and Local Variable //origin public Philosopher (Fork le, Fork ri, int na) { left = le; right = ri; name = na; ... }
Parameter Pass and Local Variable //translated version 1 Philosopher_CreateObj() = (Philosopher_CreateObj_chan_in?pid.le.ri.na -> ((tau{ memory.Philosopher_Set_le(le); } -> Skip); ((tau{ memory.Philosopher_Set_ri(ri); } -> Skip); ((tau{ memory.Philosopher_Set_na(na); } -> Skip); ((tau{ objx = memory.Philosopher_CreateObj(); } -> Skip); ((tau{ memory.Philosopher_Set_left(objx, memory.Philosopher_Get_le()); } -> Skip); ((tau{ memory.Philosopher_Set_right(objx, memory.Philosopher_Get_ri()); } -> Skip); ((tau{ memory.Philosopher_Set_name(objx, memory.Philosopher_Get_na()); } -> Skip); ... ))))))))));
Parameter Pass and Local Variable //translated version 2 Philosopher_CreateObj() = (Philosopher_CreateObj_chan_in?pid.le.ri.na -> ((tau{ objx = memory.Philosopher_CreateObj(); } -> Skip); ((tau{ memory.Philosopher_Set_left(objx, le); } -> Skip); ((tau{ memory.Philosopher_Set_right(objx, ri); } -> Skip); ((tau{ memory.Philosopher_Set_name(objx, na); } -> Skip); ... ))))))));
What's next • Exception handling • Atomicity control
Reference [1] J. Sun, Y. Liu, J. S. Dong, and J. Pang, “PAT: towards flexible verification under fairness,” in Proceedings of the 21thInternational Conference on Computer Aided Verification(CAV’09). [2] K. Havelund and T. Pressburger, “Model checking javaprograms using java pathfinder,” International Journal onSoftware Tools for Technology Transfer (STTT), vol. 2, no. 4,pp. 366 – 381, 2000. [3] Wendi Zhah, Yet Another Model Checker for PROMELA, to be appear..