Presentation is loading. Please wait.

Presentation is loading. Please wait.

Ahmed Bouajjani Constantin Enea Michael Emmi Serdar Tasiran

Similar presentations


Presentation on theme: "Ahmed Bouajjani Constantin Enea Michael Emmi Serdar Tasiran"— Presentation transcript:

1 Verifying Robustness of Event-Driven Asynchronous Programs against Concurrency
Ahmed Bouajjani Constantin Enea Michael Emmi Serdar Tasiran IRIF - University of Paris Diderot Nokia Bell Labs Koc University Burcu Kulahcioglu Ozkan – Max Planck Institute for Software Systems ESOP’ th European Symposium on Programming

2 Ubiquitous event-driven asynchronous systems
event loop offload user inputs background threads callback Need for concurrency analysis tools

3 An execution example 1 2 Background thread Background thread
Main/UI thread Background thread // the user clicks on the search button void searchForNews(String key) { new SearchTask().execute(key); } 1 void doInBackground () { // get the list from the network } void onPostExecute () { // display list of results } // the user clicks on a headline void showDetail(int id) { new DownloadTask().execute(key); } 2 void doInBackground () { // get details from the network } void onPostExecute () { // display news details }

4 Towards characterization of a correctness criteria:
Illusion of atomicity What happens in reality Event 1 App Event 2 Execution of an event-driven program

5 A bug example in Irccloud Android app
userR 3 Double click on the user name 1 2 Type “Hello” Press send button

6 A bug example in Irccloud Android app
Main/UI thread Background thread // the user clicks on the send button // the msgTxt input is currently contains “Hello” boolean onKey(...) { if(... // check connection, etc ) new SendTask().execute(); } 2 // executed before doInBackground void onPreExecute(...) { ... = msgTxt.getText(); } void doInBackground () { if (... && msgTxt.getText() != null && msgTxt.getText().length() > 0) { ... L1: write msgTxt.getText() into JSON object } Sent message: “Hello userR” // the user clicks on the username “UserR” public void onUserDoubleClicked(String name) { ... text += " " + name; msgTxt.setText(text); } 3 Sent message: “Hello”

7 Towards characterization of a correctness criteria:
event_Handler_To_Send { // check connection etc. // send msgTxt in the backg. } 2 A program must be robust against: event interleavings async. invocation interleavings out of order dispatch event_Handler_To_DoubleClick { // update msgTxt } 3

8 How to detect concurrency bugs and verify correctness?
Contributions: Provide a programming abstraction that corresponds to the expectation of the program behavior Robustness against concurrency Algorithmic methods for checking robustness

9 Rweak(P, E)  Rstrong(P, E)
A program is robust iff all reachable states in the weak semantics are also reachable in the strong semantics Rweak(P, E)  Rstrong(P, E) Weak/Multi-threaded semantics (Reality) Events can interleave with each other Async invocations can run on separate threads and can interleave Async invocations can run in any order Strong/Single-threaded semantics (Illusion) An event is dispatched only if the task buffer is empty and no tasks are running Async invocations run on the same thread

10 Execution of a program under strong semantics
Event handler 1 Event handler 2 searchForNews showDetail // connects to the network // saves the keyword to the db // connects to the network SearchTask .doInBackground SaveTask .doInBackground DownldTask .doInBackground // displays the results on UI // displays the results on UI SearchTask .onPostExecute DownldTask .onPostExecute

11 Robustness = Event-serializability + Event-determinism
Every global state in Rweak(P, E) can be reached by an event-serial execution Event-determinism: For every global state g0 , the set Rweak(P, g0, e) is a singleton or empty. R( )  R( ) R( )  R( )

12 Checking robustness against concurrency
We check a stronger notion of conflict robustness Our novel algorithmic approach reduces robustness checking into the reachability in the sequential programs! We use the decomposition: Conflict robustness = conflict event-determinism + conflict event-serializability more on this talk relies on the determinism of the event handlers

13 Conflict-robustness Conservative notion of conflict robustness  ensures robustness Conflict-relation: Given actions a1, a2 ∈ {rd(x), wr(x)} for some x, a1 < a2 (where a1 occurs before a2) iff: a1 and a2 access the same variable at least one of them is a write A trace t’ is a conflict-preserving permutation of t iff: for every pair of conflicting actions a1 < a2 appear in the same order e.g. rd(x) wr(y) wr(x) rd(x) wr(x) wr(y)

14 Conflict-event determinism
An execution is conflict event-deterministic if the conflict-invocation graph is acyclic: An event handler procedure: A trace t of e: Call graph of e: e // on main thread proc e() { async[any] p(); async[main] q(); x := 1; } proc p() { z := 1; y := 1; proc q() { y := 2; x := 2; <e, async(ip)> <e, async(iq)> <e, wr(x)> <q, wr(y)> <q, wr(x)> <p, wr(z)> <p, wr(y)> p q Conflict-invocation graph of t: e dfs p t is not a conflict preserving permutation of the DFS-serial execution conflict dfs q

15 Checking conflict-event determinism of e()
proc e() { async p(); async q(); ...} Checking conflict-event determinism of e() Checking conflict-event determinism of e() under the multi-threaded semantics e() p() q() e() p() q() e() p() q() ... ... ... reduced to Code-to-code transformation that: Simulates conflict-preserving traces of borderline-violations on the strong semantics Checking conflict-event determinism of e() under the single-threaded semantics e() p() q()

16 Checking conflict-event determinism of e()
p q Checking conflict-event determinism of e() Borderline violation to conflict-determinism: A not DFS-equivalent trace whose strict prefixes are DFS-serial Borderline violations can be simulated on the strong semantics ! proc e() { async p(); async q(); ...} A trace t of e: e <e, async(p)> <e, async(q)> <e, wr(x)> <q, wr(y)> <q, wr(x)> <p, wr(z) > <p, wr(y)> dfs DFS-serial prefix (a permutation of the trace in the strong semantics) p conflict dfs q Creates a borderline-violation

17 Checking conflict-determinism of e()
p q proc e() { async p(); async q(); ...} Checking conflict-determinism of e() Execution trace t Reordering t into DFS and simulation of the violation e e async(p) async(q) wr(x) async(p) async(q) wr(x) p q DFS serial part wr(z) wr(y) wr(x) if(*) skip q if(*) ® := l2 wr(y) wr(x) p goto ℗ wr(z) wr(y) ℗ := l1; wr(y) Borderline violation if(conflict (℗, ®)) error := true If error = true is reachable, e() is not event-deterministic

18 Checking conflict-serializability
Employs a similar reduction that relies on: Conflict deterministic event handlers (simulated by a sequential program) Simulating borderline violations for conflict-event serializability by a sequential program Code-to-code translation to a sequential program which guesses and validates The accesses that create the conflict (similar to det. checking) The accesses that form the dependency between events e1 e2 conflict

19 robustness checking code
Experimental work to verify conflict-robustness (conflict-event determinism + conflict-event serializability ) Implementation as an automatic instrumentation to Java programs Obtained sequential program can be verified with a sequential program verification tool conflict robust automatic instrumentation not conflict robust + cycle info Android Library Stubs + Android app data nondeterministic sequential program sequential program verification tool + driver program to specify user inputs Java PathFinder robustness checking code

20 Checking conflict-event determinism
can successfully detect nondeterministic event handlers

21 Checking conflict-event serializability
Experimental results: True bugs – not conflict serializable and not serializable False alarms – not conflict serializable but serializable Inter-related events – not conflict serializable but not buggy (e.g. an event handler aborts an async task of a previous event)

22 Most related work Refactoring of Asynchronous Programs (Lin et al FSE’14, ASE’15) Moves long running parts of the code into asynchronous invocations Refactors into proper use of asynchrony constructs Event Anomalies (Safi et. al FSE’15) More than one event handlers access to same memory location Static analysis of event handlers Data Race Checking (Maiya et al. PLDI’14, Hsiao et al. PLDI’14, Bielik et al. OOPSLA’15) Symptomatic detection of concurrency bugs Analysis on the collected traces, high number of false positives “Robustness against concurrency” defines a high-level correctness criterion that captures the concurrency errors can be efficiently checked by using sequential program verification tools

23 Conclusion Future Work
Robustness = event serializability + event determinism Can be checked algorithmically: Reduces the analysis of a highly concurrent program with unbounded number of asynchronous tasks into a sequential program analysis Practical to check, can be used to uncover unknown bugs Future Work Event handlers with synchronization Requires slight modification of strong semantics Utilization of robustness-checking for different programming models


Download ppt "Ahmed Bouajjani Constantin Enea Michael Emmi Serdar Tasiran"

Similar presentations


Ads by Google