210 likes | 324 Vues
This guide explores C# model checking methodologies, offering an overview of model structure, flow control, state representation, and thread management. It discusses key features of prominent model checkers like BLAST, SLAM, and CBMC, detailing how to translate into Boolean programs or CIL. The use of theorem provers and SAT solvers for predicate checks, as well as the capability to translate to Promela for SPIN verification, is also covered. Additional insights include refinement checking, exception handling, and atomicity control, enhancing traceability for testing and debugging.
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..