Continuous Verification of Large Embedded Software using SMT-Based Bounded Model Checking Lucas Cordeiro, Bernd Fischer, Joao Marques-Silva lcc08r@ecs.soton.ac.uk
������ � ����������������������� � �������������������������������������� � ����������������� ���!������"������ � ����������������#������$���
Continuous Verification • based on Fowler’s continuous integration (CI): build and test full system after each change • complement testing by verification (SMT-based bounded model checking) – assertions – language-specific properties – language-specific properties • exploit existing information – development history (SCM) – test cases • limit change propagation – equivalence checks
Functional Equivalence Checking • determine whether modified functions need to be re-verified – no need to re-verify properties if functions are equivalent – less expensive than re-verifying the function – undecidable due to unbounded memory usage
Functional Equivalence Checking • determine whether modified functions need to be re-verified – no need to re-verify properties if functions are equivalent – less expensive than re-verifying the function – undecidable due to unbounded memory usage • goal: compare input-output relation �������� %�&� ��� ��������' �������� ��&�����( �������� ��&�����( �� ��������)*�+� ��&������*�������( ���� ��&������*��,-������( ������ ��&�����( . �������� %�&� ��� ��������' �� ��������/�+� ������ �������( ���� ������ ������( .
Functional Equivalence Checking • determine whether modified functions need to be re-verified – no need to re-verify properties if functions are equivalent – less expensive than re-verifying the function – undecidable due to unbounded memory usage • goal: compare input-output relation �������� %�&� ��� ��������' �������� ��&�����( �������� ��&�����( – remove variables and returns �� ��������)*�+� ��&������*�������( ���� ��&������*��,-������( ������ ��&�����( . �������� %�&� ��� ��������' �� ��������/�+� ������ �������( ���� ������ ������( .
Functional Equivalence Checking • determine whether modified functions need to be re-verified – no need to re-verify properties if functions are equivalent – less expensive than re-verifying the function – undecidable due to unbounded memory usage • goal: compare input-output relation �������� %�&� ��� ��������' �������� ��&�����( �������� ��&�����( – remove variables and returns �� ��������)*�+� ��&������*�������( ���� – convert the function bodies into SSA ��&������*��,-������( ������ ��&�����( � � inverter = signal . 1 1 � � α = ∧ inverter = − 1 ∗ signal � � �������� %�&� ��� ��������' 1 2 1 � ) � �� ��������/�+� ( � � ∧ inverter = signal ≥ 0 ? inverter : inverter 3 1 1 2 ������ �������( ���� ������ ������( [ ] ( ) α = signal = signal < − signal signal ' ' 0 ? ' : ' . 2 2 1 1 1
Functional Equivalence Checking • determine whether modified functions need to be re-verified – no need to re-verify properties if functions are equivalent – less expensive than re-verifying the function – undecidable due to unbounded memory usage • goal: compare input-output relation – remove variables and returns – convert the function bodies into SSA – show that the input and output variables coincide SSA of function 1 and 2 ( ( ) ) ( ) α ∧ α ∧ signal = signal ' → inverter = signal ' 1 2 1 1 3 2 inputs outputs
Generalizing Test Cases • use existing test cases to reduce the state space – run the unit tests, keep track of inputs – guide model checker to visit states not yet visited • test stubs break the global model into local models – use test case as initial state – generate reachable states on-demand ⇒ reduces the number of paths and variables !��� ����� ������ ����� ������ ��!�� ������ �*������0������( ����!���),+�11��/2++�(
Generalizing Test Cases: Example Simple circular FIFO buffer: ����������� ������3�4##�"0�567( Test case: ���� ����8��� ��� !����' check whether messages are ������0��9� *�!��( ������*������*�+( added to and removed from the . circular buffer ��� ��!�&�8�����!� ���� ��' ������������ �������������������&�����' �����::( �����::( ��� ���;���37�*�',<��,2=<�>=<�==<�?>< ��� ���;���37�*�',<��,2=<�>=<�==<�?>< ������ ������3������,7( ,<��,2=<�>+<�+<��AB.( . ��� �( ����8���?�( ���� ������8�����!� ��� ���' ��� ��*+(��/,+(��::� �� ������/�������0��9���' ������8�����!����;���3�7�( ������3����7�*��( ��� ��*?(��/,+(��::� �����*������:,�@������0��9�( ���������������� ����;���3�7< . ��!�&�8�����!���( . .
Generalizing Test Cases: Example Simple circular FIFO buffer: ����������� ������3�4##�"0�567( BUT: implementation is flawed! ���� ����8��� ��� !����' ������0��9� *�!��( ������*������*�+( The array buffer is of type char[] . ��� ��!�&�8�����!� ���� ��' �����::( �����::( Assign an integer variable ������ ������3������,7( . ���� ������8�����!� ��� ���' �� ������/�������0��9���' ������3����7�*��( �����*������:,�@������0��9�( . .
Generalizing Test Cases: Example Simple circular FIFO buffer: ����������� ������3�4##�"0�567( BUT: implementation is flawed! ���� ����8��� ��� !����' ������0��9� *�!��( ������*������*�+( The array buffer is of type char[] . ��� ��!�&�8�����!� ���� ��' �����::( �����::( Assign an integer variable ������ ������3������,7( . ���� ������8�����!� ��� ���' We can detect the error by �� ������/�������0��9���' assigning a non-deterministic ������3����7�*�������0�����( �����*������:,�@������0��9�( value . . This can lead to false results
Recommend
More recommend