Pragmatic Typestate Verification with Permissions ���������������� �������������������������� with Kevin Bierhoff, with Kevin Bierhoff, Nels Beckman, Sven Stork, and Yoon Phil Kim Spring 2010 (Yoon Phil Kim not pictured)
Software development today heavily relies on re%usable APIs APIs in this talk include libraries and frameworks APIs in this talk include libraries and frameworks Many APIs require clients to follow ��������� that allow API implementations to work correctly Protocols in this work are defined based on ���������� ���������������� ����������������������� �
Protocol Examples: Iterators and InputStreams ��������� ������������ • Return all elements • Read from a of a sequence character stream read() read() available hasNext() is ���� close() next() open closed hasNext() is ����� end External choice: read() or close() Internal choice: Return value available or end ���������������� ����������������������� � ���������������������������������������������������������������������
APIs are hard to use and implement ������������������ ���������������� • Difficult to understand • Documentation consistent correct usage with actual code • Incorrect use does not • Consistent runtime tests to always lead to clear errors protect against misuse • Hard to guarantee protocol • Shared objects might be is followed on all paths is followed on all paths modified unexpectedly modified unexpectedly • Code modifications may • Reentrancy introduce new errors • Unexpected overriding and open recursion ��������������������������!������������������������ ���������������� ����������������������� �
Automatically check API designers specify code against protocols API protocols Interactive protocol violation warnings ���������������� ����������������������� �
Checking protocol compliance is hard s = new BufferedInputStream(); Problem: What if there are other while((c = s.read()) >= 0) references to the object c? ��������� " #�������������$ s.close(); read() read() private void fill() { private void process(int c) { private void process(int c) { pos = 0; pos = 0; if(valid(c)) { B } int cnt = underlyingStream.read(B); open closed open closed close() close() else s.close(); count = pos + cnt; } } ����������������������$ public synchronized int read() { if (pos >= count) { Problems: Does this object use ����� " other objects correctly? What if if (pos >= count) return %1; } multiple threads are involved? return buf[pos++] & 0xff; } ���������������� ����������������������� �
Key Challenges in Previous Work Previous work provides ��������������� checking of both ������� and ��������������� But, previous work had serious limitations: • Limited tracking of ������� state • ���������������� state changes • • ����������� ����������� • Dynamic ����������� • States with ��������������� and �������� • Verifying ��������� code • �������� states in subclasses • ������� superclasses that are in different states • ������������ typestate ���������������� ����������������������� �
Contributions Previous work provides ��������������� checking of both ������� and ��������������� Our contributions • New modular approaches to tracking ������� state • ���������������� state changes • • ����������� ����������� • Dynamic ����������� • States with ��������������� and �������� • Verifying ��������� code • �������� states in subclasses • ������� superclasses that are in different states • ������������ typestate ���������������� ����������������������� �
Outline Previous work provides ��������������� checking of both �������� and ��������������� Our contributions • New modular approaches to tracking ������� state • ���������������� state changes • • ����������� ����������� • Dynamic ����������� • States with ��������������� and �������� ���������������� ����������������������� �
Typestate Specification ������� open, closed • Declare states open, closed ������ StreamProtocol { ���� ⇒ ⇒ ���%�� ( ���� ) ��� open ⇒ ⇒ • Constructor returns ���%�� ������� StreamProtocol() { B } permission to open stream ���� ( ���� ) ��� open • Read requires ���� (exclusive ⇒ ���� ( ���� ) ��� open ⇒ ⇒ ⇒ ⇒ ⇒ ⇒ ���� ( ���� ) ��� open ⇒ write) access to open stream ����������� read() { B } ���� ( ���� ) ��� open • Close transitions from open ⇒ ⇒ ���� ( ���� ) ��� closed ⇒ ⇒ to closed �������&���� close() { B } } ���������������� ����������������������� ��
Typestate Verification ������� open, closed StreamProtocol s = ��!� StreamProtocol(); ������ StreamProtocol { ���%�� ( � ) ��� open ���� ⇒ ⇒ ���%�� ( ���� ) ��� open ⇒ ⇒ !���� (s.available() > 0) ������� StreamProtocol() { B } s.read(); ������������������������� ���%�� ( � ) ��� open ���� ( ���� ) ��� open s.close(); ⇒ ⇒ ⇒ ⇒ ���� ( ���� ) ��� open ⇒ ⇒ ⇒ ⇒ ���� ( ���� ) ��� open ���%�� ( � ) ��� closed ���%�� ( � ) ��� closed ����������� read() { B } ���������������������������� s.read(); ���� ( ���� ) ��� open ⇒ ⇒ ���� ( ���� ) ��� closed ⇒ ⇒ �������&���� close() { B } } ���������������� ����������������������� ��
Modular Typestate Verification ���� ( � ) ��� open ⇒ ⇒ ���� ( � ) ��� open ⇒ ⇒ ������� open, closed ������ StreamProtocol { &���� process(StreamProtocol s) { ���� ⇒ ⇒ ���%�� ( ���� ) ��� open ⇒ ⇒ ���� ( � ) ��� open ������� StreamProtocol() { B } s.read(); ������������������������� ���� ( � ) ��� open ���� ( ���� ) ��� open } ⇒ ⇒ ���� ( ���� ) ��� open ⇒ ⇒ ⇒ ���� ( ���� ) ��� open ⇒ ⇒ ⇒ ����������� read() { B } StreamProtocol s = ��!� StreamProtocol(); ���%�� ( � ) ��� open ���� ( ���� ) ��� open !���� (s.available() > 0) ⇒ ⇒ ���� ( ���� ) ��� closed ⇒ ⇒ ������������������������� process(s); �������&���� close() { B } ���%�� ( � ) ��� open } s.close(); ���%�� ( � ) ��� closed ���������������� ����������������������� ��
DEMONSTRATION % PLURAL • Plural.test.StreamProtocol ���������������� ����������������������� ��
Recommend
More recommend