Event-Based Race Detection in Android Apps Using SIERRA

Static Detection of Event-based
Races in Android App
Yongjian Hu
Univ. of California, Riverside
 Iulian Neamtiu
NJIT
Motivation
Rise of Event-Driven Systems
 Concurrency is a Serious Issue
66% of high-severity Android bugs are due to concurrency
[Zhou et al., EASE’15]
84% of Android race bugs are event-driven races [Bielik et al.,
OOPSLA’15; Hsial et al. PLDI’14; Maiya et al., PLDI’14]
Mobile apps
Web apps
Data centers
Concurrency Error Example
class MainActivity {
  DataBase mDB;
  BroadcastReceiver recv =
    new BroadcastReceiver() {
    void onReceive(Context ctx, Intent i)
 
{
      Bundle b = i.getExtras();
      mDB.update(b);
    }
  }
  void onCreate(...) {
    mDB = new DataBase();
    registerReceiver(recv, ...);
  }
  void onStart() {
    mDB.open();
  }
  void onStop() {
    mDB.close();
  }
  void onDestroy() {
    unregisterReceiver(recv);
    mDB = null;
  }}
 
update()
before
close()
OK
 
not ordered
Concurrency Error Example
class MainActivity {
  DataBase mDB;
  BroadcastReceiver recv =
    new BroadcastReceiver() {
    void onReceive(Context ctx, Intent i)
 
{
      Bundle b = i.getExtras();
      mDB.update(b);
    }
  }
  void onCreate(...) {
    mDB = new DataBase();
    registerReceiver(recv, ...);
  }
  void onStart() {
    mDB.open();
  }
  void onStop() {
    mDB.close();
  }
  void onDestroy() {
    unregisterReceiver(recv);
    mDB = null;
  }}
Main Thread
Broadcast Receiver
onCreate()
register
unregister
 
update
onStart()
onReceive()
onStop()
onDestroy()
 
update()
after
close()
Exception!
not ordered
State-of-the-art in (Android) Race Detection
Prior Android race detectors: all are dynamic
DroidRacer [Maiya et al., PLDI’14]; CAFA [Hsiao et al., PLDI’14];
EventRacer [Bielik et al., OOPSLA’15]
Limitations
Coverage issues 
 False negatives; “no run - no see”
False positives (imprecise Android modeling)
Static race detection is hard [Hong and Kim, STVR’15]
Only 7 out of 43 detectors are static
“the accuracy of [static] models is often low because of the
imprecision inherent to static analysis methods”
Our Approach
SIERRA
: the first 
static, sound
 event-driven race
detector for Android apps
Highly effective
Finds 
29
 true races per app vs. 4 (best dynamic detector)
Efficient
Analyzes an app in 31 minutes on average
SIERRA: 
S
tat
I
c 
E
vent-based 
R
ace
detecto
R
 for 
A
ndroid
App
Analysis
booster
Hybrid
Context
Selector
Call Graph
Builder
PA
Refiner
Pointer
Analysis
Static HB
Graph
Race
Reports
Path/Context
Sensitivity
Refutation
Race
Prioritization
WALA
THRESHER
Building HB Graph
Race Refinement
Race Reporting
Event Race Definition
Action 
=
 
context-sensitive event handling
Novel abstraction, reifies
Callbacks (lifecycle, GUI callbacks, etc.)
Thread, AsyncTask, Executor
Handler’s SendMessage and PostRunnable
Happens-before
 (HB): A1 
 A2
A1 is completed before A2
Event race 
= “racy” pair of memory accesses
Access same location: α(x) = α(y)
At least one access is write: α(x):Write ꓦ α(y):Write
Access from two actions: 
θ
(x) = A1 ꓥ 
θ
(y) = A2 ꓥ A1 ≠ A2
No HB between two actions: A1 
 A2 ꓥ A2 
 A1
“Boosting” Static Analysis with Fixpoint-
based Callgraph Construction
Manifest.xml lists all the activities
For each activity:
1.
Find lifecycle callbacks, e.g., onCreate,
onStart
2.
Find XML registered callbacks, e.g., onClick
3.
Find system callbacks, e.g., onLowMemory
4.
Build call graph for found actions
a)
Find and add to work list registered UI
callbacks, e.g., onItemClick,
onLongPress
b)
Added to work list if new actions
found
5.
Go back to step 4. Iterate until fixpoint
Action Sensitivity:
 When Context
Sensitivity is Insufficient
Hybrid context sensitivity [Kastrinis et al., PLDI’13]
K object sensitivity for dispatch invocations
K call-site sensitivity for static invocations
a
Points-to(<[c2::c3], os>) =
{<[c2::c3], new
OutputStream>}
Event1:
WRITE: <[c2::c3], os>
READ: <[c2::c3], os>
Points-to(<[c2::c3], os>) =
{<[c2::c3], new
OutputStream>}
Event2:
WRITE: <[c2::c3], os>
READ: <[c2::c3], os>
 
Conflated → Imprecise → False positive
 
K=2
Action Sensitivity:
 When Context
Sensitivity is Insufficient
Hybrid context sensitivity [Kastrinis et al., PLDI’13]
K object sensitivity for dispatch invocations
K call-site sensitivity for static invocations
We add
 Action sensitivity
Points-to (<[c2::c3
@a1
], os>) =
{<[c2::c3
@a1
], new
OutputStream>}
Event1:
WRITE: <[c2::c3
@a1
], os>
READ: <[c2::c3
@a1
], os>
Points-to(<[c2::c3
@a2
], os>) =
{<[c2::c3
@a2
], new
OutputStream>}
Event2:
WRITE: <[c2::c3
@a2
], os>
READ: <[c2::c3
@a2
], os>
 
No race
No race
Happens-before Rules
1.
Action invocation rule (sender 
receiver)
2.
Component lifecycle rule
3.
GUI layout/object order
4.
Intra-procedural domination
5.
Intra-action, inter-procedural
domination
6.
Inter-action transitivity
7.
Transitivity
onResume()  
onPause()
*
onClick1()
onClick2()
onClick3()
onResume 
 onClick1
onResume 
 onClick2
onClick2 
 onClick3
Symbolic Execution-based Refutation
So far, the analysis is
Context sensitive
Field sensitive
Path insensitive
and discovers 22% of all possible actions orders
Which is not bad!
Next, we use 
symbolic execution-based refutation
to further order accesses
Bonus: on-demand path sensitivity!
Example
Path
Constraints
OpenSudoku app
Can 
𝜶
A
 occur before 𝜶
B
? 
Timer.Runnable runner = {
void run() {//action 
A
 if (mIsRunning) {
  mAccumTime=... // 
𝜶
A
  if (*) {
   ...
   postDelayed(runner,...);
  }
  else
   mIsRunning=false; }
}}
void stop(){// action 
B
 if (mIsRunning) {
   mIsRunning = false;
   mAccumTime=... // 𝜶
B
 }
}
 
Yes!
Example
Path
Constraints
Can 
𝜶
B
 occur before 𝜶
A
? 
Timer.Runnable runner = {
void run() {//action 
A
 if (mIsRunning) {
  mAccumTime=... // 
𝜶
A
  if (*) {
   ...
   postDelayed(runner,...);
  }
  else
   mIsRunning=false; }
}}
void stop(){// action 
B
 if (mIsRunning) {
   mIsRunning = false;
   mAccumTime=... // 𝜶
B
 }
}
 
No!
Evaluation
Best prior
work (dynamic)
 
Efficiency (median time, in seconds)
 
Effectiveness: races found
Dataset: 194 open-source apps; 20 analyzed manually
Limitation: bound #paths to 5,000 while still sound (report race, might be false positives) 
Conclusions
Event-based races: most prevalent concurrency errors in
Android
Prior approaches: all dynamic
Low coverage, false negatives, false positives
Our approach
First fully static event-based race detector
Novel action sensitive context abstraction
Static happens-before relation
Static backward symbolic execution to refute false races
Highly effective; efficient
Backup
Race Prioritization
Priority
High priority
Races in app code
Normal priority
Races in framework but invoked from app code
Low priority
Purely framework race
Report race if
Witness feasible paths from alternative schedules
Cannot refute (to preserve soundness)
E.g., Out Of Memory, max paths limit, max time limit (1,500 sec.)
Potential false positive
Context Sensitivity(cont’d)
Object insensitive  = imprecision
 
MERGED
O1:
Context Sensitivity(cont’d)
Object sensitivity in SIERRA = precision
C1:
C2:
O
h
:
K-obj + 1-call-site for event posting
and message passing
Happens-before Rules
Rule 1:  Action invocation rule
The 
sender
 action happens-before the
 recipient
Rule 2: Component lifecycle rule
Activity.onCreate < Activity.onStart
Activity.onStart < Activity.onStop
……
Rule 3: GUI layout/object order
Activity.onResume < View.onClick < Activity.onPause
Happens-before Rules (cont’d)
Rule 4: Intra-procedural domination
Method M in action A has two action posts: e
1
 and e
2
e
1
 dominates e
2
: e
1
 <
dom
 
e2
Δ
e
1
 ≤ Δ
e
2
, Δ is post delayed time
Rule 5: Intra-action, inter-procedural domination
Method M
1
 Action A, M
2
 Action A
Action posts: e
1
 , e
2
e
1
 dominates e
2
Δ
e
1
 ≤ Δ
e
2
, Δ is post delayed time
Rule 6: Inter-action transitivity
Action A
1
 < A
2
A
1
post
 A
3
, A
2
post
 A
4
Rule 7: Transitivity
A
1
 < A
2
 ꓥ A
2
 < A
3
   A
1
 < A
3
A
1
post
 A
3
, A
2
post
 A
4
Context Sensitivity(cont’d)
Object insensitive  = imprecision
 
MERGED
O1:
Context Sensitivity(cont’d)
Object sensitivity in SIERRA = precision
C1:
C2:
O
h
:
K-obj + 1-call-site for event posting
and message passing
Context Sensitivity (cont’d)
SIERRA’s hybrid context sensitivity
<k-obj + action> for normal dispatch methods
<k-cfa + action> for static methods
<k-obj + 1-call-site + action> for event posting and
message passing
SingletonContext
For singleton design pattern
Use global context instead of adding action sensitivity
InflatedViewContext
Invoked via View.findViewById(int viewId)
Use viewId as context item
Happens-before Rules
Rule 1:  Action invocation rule
The 
sender
 action happens-before the
 recipient
Rule 2: Component lifecycle rule
Activity.onCreate < Activity.onStart
Activity.onStart < Activity.onStop
……
Rule 3: GUI layout/object order
Activity.onResume < View.onClick < Activity.onPause
Happens-before Rules (cont’d)
Rule 4: Intra-procedural domination
Method M in action A has two action posts: e
1
 and e
2
e
1
 dominates e
2
: e
1
 <
dom
 
e2
Δ
e
1
 ≤ Δ
e
2
, Δ is post delayed time
Rule 5: Intra-action, inter-procedural domination
Method M
1
 Action A, M
2
 Action A
Action posts: e
1
 , e
2
e
1
 dominates e
2
Δ
e
1
 ≤ Δ
e
2
, Δ is post delayed time
Rule 6: Inter-action transitivity
Action A
1
 < A
2
A
1
post
 A
3
, A
2
post
 A
4
Rule 7: Transitivity
A
1
 < A
2
 ꓥ A
2
 < A
3
   A
1
 < A
3
A
1
post
 A
3
, A
2
post
 A
4
Concurrency Error, Example 1
Intra-component Race
Concurrency Error, Example 2
Inter-component Race
update()
before
close()
:
OK
Concurrency Error, Example 2
Inter-component Race
update()
after
close()
:
Exception!
“Boosting” Static Analysis with Fixpoint-based
Callgraph Construction
 
Manifest.xml lists all the activities
For each activity:
1.
Find lifecycle callbacks, e.g., onCreate,
onStart
2.
Find XML registered callbacks, e.g., onClick
3.
Find system callbacks, e.g., onLowMemory
4.
Build call graph for found actions
a)
Find and add to work list registered UI callbacks,
e.g., onItemClick, onLongPress
b)
Added to work list if new actions found
5.
Go back to step 4. Iterate until fixpoint
onCreate
onStart
onResume
onClick
onCreate
OptionsMenu
onLow
Memory
thread
AsyncTask
onPost
Execution
msg1.
handleMessage
Runnable1
onItemClick
onLongPress
Runnable2
 
 
 
Prior Android static analyses: imprecise
Slide Note
Embed
Share

The research discusses the significance of detecting event-based races in Android applications due to concurrency issues. It emphasizes the prevalence of such bugs in high-severity Android issues and motivates the need for static detection methods. The proposed approach, SIERRA, is introduced as the first static, sound event-driven race detector for Android apps. SIERRA demonstrates high effectiveness in identifying true races and efficiency in app analysis. The limitations of existing dynamic race detectors are also highlighted, underscoring the value of static analysis in race detection.

  • Android Apps
  • Event-Based Races
  • Static Detection
  • SIERRA
  • Concurrency Issues

Uploaded on Oct 04, 2024 | 2 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. Static Detection of Event-based Races in Android App Yongjian Hu Iulian Neamtiu NJIT Univ. of California, Riverside

  2. Motivation Rise of Event-Driven Systems Mobile apps Web apps Data centers Concurrency is a Serious Issue 66% of high-severity Android bugs are due to concurrency [Zhou et al., EASE 15] 84% of Android race bugs are event-driven races [Bielik et al., OOPSLA 15; Hsial et al. PLDI 14; Maiya et al., PLDI 14]

  3. Concurrency Error Example class MainActivity { DataBase mDB; BroadcastReceiver recv = new BroadcastReceiver() { void onReceive(Context ctx, Intent i) { Bundle b = i.getExtras(); mDB.update(b); } } void onCreate(...) { mDB = new DataBase(); registerReceiver(recv, ...); } void onStart() { mDB.open(); } void onStop() { mDB.close(); } void onDestroy() { unregisterReceiver(recv); mDB = null; }} Broadcast Receiver Main Thread onCreate() onStart() update not ordered onReceive() onStop() update() before close() OK onDestroy()

  4. Concurrency Error Example class MainActivity { DataBase mDB; BroadcastReceiver recv = new BroadcastReceiver() { void onReceive(Context ctx, Intent i) { Bundle b = i.getExtras(); mDB.update(b); } } void onCreate(...) { mDB = new DataBase(); registerReceiver(recv, ...); } void onStart() { mDB.open(); } void onStop() { mDB.close(); } void onDestroy() { unregisterReceiver(recv); mDB = null; }} Broadcast Receiver Main Thread onCreate() onStart() onStop() not ordered onReceive() update() after close() Exception! onDestroy()

  5. State-of-the-art in (Android) Race Detection Prior Android race detectors: all are dynamic DroidRacer [Maiya et al., PLDI 14]; CAFA [Hsiao et al., PLDI 14]; EventRacer [Bielik et al., OOPSLA 15] Limitations Coverage issues False negatives; no run - no see False positives (imprecise Android modeling) Static race detection is hard [Hong and Kim, STVR 15] Only 7 out of 43 detectors are static the accuracy of [static] models is often low because of the imprecision inherent to static analysis methods

  6. Our Approach SIERRA: the first static, sound event-driven race detector for Android apps Highly effective Finds 29 true races per app vs. 4 (best dynamic detector) Efficient Analyzes an app in 31 minutes on average

  7. SIERRA: StatIc Event-based Race detectoR for Android Race Reporting Building HB Graph Race Refinement Race Hybrid Context Selector Race <rw1,rw1 > Prioritization Static HB Graph PA App Race <rw2,rw2 > Refiner . . . Call Graph Builder Pointer Analysis Analysis booster Race Reports WALA Path/Context Sensitivity Refutation THRESHER

  8. Event Race Definition Action =context-sensitive event handling Novel abstraction, reifies Callbacks (lifecycle, GUI callbacks, etc.) Thread, AsyncTask, Executor Handler s SendMessage and PostRunnable Happens-before (HB): A1 A2 A1 is completed before A2 Event race = racy pair of memory accesses Access same location: (x) = (y) At least one access is write: (x):Write (y):Write Access from two actions: (x) = A1 (y) = A2 A1 A2 No HB between two actions: A1 A2 A2 A1

  9. Boosting Static Analysis with Fixpoint- based Callgraph Construction Manifest.xml lists all the activities For each activity: 1. Find lifecycle callbacks, e.g., onCreate, onStart 2. Find XML registered callbacks, e.g., onClick 3. Find system callbacks, e.g., onLowMemory 4. Build call graph for found actions a) Find and add to work list registered UI callbacks, e.g., onItemClick, onLongPress b) Added to work list if new actions found 5. Go back to step 4. Iterate until fixpoint onCreate onItemClick thread onStart Runnable1 onLongPress onResume onClick Runnable2 AsyncTask onPost Execution onCreate OptionsMenu msg1. onLow Memory handleMessage

  10. Action Sensitivity: When Context Sensitivity is Insufficient Hybrid context sensitivity [Kastrinis et al., PLDI 13] K object sensitivity for dispatch invocations K call-site sensitivity for static invocations a K=2 Points-to(<[c2::c3], os>) = {<[c2::c3], new OutputStream>} Base64.encodeBytes (byte[] source, int offset, int length, int options) Base64.encodeBytesToBytes(byte[] source, int offset, int length, int options) { os = new OutputStream( ); os.write( ); } Base64.encodeBytes (byte[] source) c3: c2: c1: Action1 Event1: WRITE: <[c2::c3], os> READ: <[c2::c3], os> Points-to(<[c2::c3], os>) = {<[c2::c3], new OutputStream>} Base64.encodeBytes (byte[] source, int offset, int length, int options) Base64.encodeBytesToBytes(byte[] source, int offset, int length, int options) { os = new OutputStream( ); os.write( ); } Base64.encodeBytes (byte[] source) c3: c2: c1 : Action2 Event2: WRITE: <[c2::c3], os> READ: <[c2::c3], os> Conflated Imprecise False positive

  11. Action Sensitivity: When Context Sensitivity is Insufficient Hybrid context sensitivity [Kastrinis et al., PLDI 13] K object sensitivity for dispatch invocations K call-site sensitivity for static invocations We add Action sensitivity Points-to (<[c2::c3@a1], os>) = {<[c2::c3@a1], new OutputStream>} Base64.encodeBytes (byte[] source, int offset, int length, int options) Base64.encodeBytesToBytes(byte[] source, int offset, int length, int options) { os = new OutputStream( ); os.write( ); } Base64.encodeBytes (byte[] source) c3: c2: c1: Action1 Event1: WRITE: <[c2::c3@a1], os> READ: <[c2::c3@a1], os> No race Points-to(<[c2::c3@a2], os>) = {<[c2::c3@a2], new OutputStream>} Base64.encodeBytes (byte[] source, int offset, int length, int options) Base64.encodeBytesToBytes(byte[] source, int offset, int length, int options) { os = new OutputStream( ); os.write( ); } Base64.encodeBytes (byte[] source) c3: c2: c1 : Action2 Event2: WRITE: <[c2::c3@a2], os> READ: <[c2::c3@a2], os>

  12. Happens-before Rules onResume() 1. Action invocation rule (sender receiver) * 2. Component lifecycle rule 3. GUI layout/object order 4. Intra-procedural domination onClick2() onClick1() onClick3() onPause() 5. Intra-action, inter-procedural domination 6. Inter-action transitivity 7. Transitivity Method M e1 e1 <dom A1 A1 A2 e2 e2 A2

  13. Symbolic Execution-based Refutation So far, the analysis is Context sensitive Field sensitive Path insensitive and discovers 22% of all possible actions orders Which is not bad! Next, we use symbolic execution-based refutation to further order accesses Bonus: on-demand path sensitivity!

  14. OpenSudoku app Example Path Constraints Timer.Runnable runner = { void run() {//action A if (mIsRunning) { mAccumTime=... // ? ?A if (*) { ... postDelayed(runner,...); } else mIsRunning=false; } }} void stop(){// action B if (mIsRunning) { mIsRunning = false; mAccumTime=... // ?B } } Method entry mIsRunning = false if (mIsRunning) mAccumTime = Backward symbolic execution if (*) Post Delayed mIsRunning = false mIsRunning = false Method exit mIsRunning = true if (mIsRunning) true mIsRunning = false mAccumTime = Can ? ?A occur before ?B? Yes!

  15. Example Path Constraints Method entry void stop(){// action B if (mIsRunning) { mIsRunning = false; mAccumTime=... // ?B } } mIsRunning = false if (mIsRunning) true mIsRunning = false mIsRunning = false mAccumTime = Backward symbolic execution Timer.Runnable runner = { void run() {//action A if (mIsRunning) { mAccumTime=... // ? ?A if (*) { ... postDelayed(runner,...); } else mIsRunning=false; } }} Method exit mIsRunning = true if (mIsRunning) mAccumTime = Race Refuted! No! Can ? ?B occur before ?A?

  16. Evaluation Effectiveness: races found App Installs (millions) Actions HB edges Racy pairs After action sensitivit y After refu- tation True races False posi- tives Event Racer Barcode Scanner > 100 136 2,756 (30%) 64 24 15 11 4 7 VLC > 100 151 2,349 (20%) 202 78 35 32 3 0 FB Reader > 10 259 4,710 (14%) 836 285 106 93 13 5 K-9 > 5 312 5,725 1,347 370 89 72 17 1 Best prior work (dynamic) Efficiency (median time, in seconds) (12%) > 1 490 NPR HB 10,673 (9%) 607 132 21 21 0 3 Basic static analysis (CG,PA) Symbolic Execution Total construction 2,755 (22%) Across 20 apps 1,310 160 431 80 33 1,899 29 4 4 29 560 Dataset: 194 open-source apps; 20 analyzed manually Limitation: bound #paths to 5,000 while still sound (report race, might be false positives)

  17. Conclusions Event-based races: most prevalent concurrency errors in Android Prior approaches: all dynamic Low coverage, false negatives, false positives Our approach First fully static event-based race detector Novel action sensitive context abstraction Static happens-before relation Static backward symbolic execution to refute false races Highly effective; efficient

  18. Backup

  19. Context Sensitivity(contd) Object insensitive = imprecision O1: void onTouchEvent(MotionEvent e1, MotionEvent e2) { if (e1.getX() e2.getX() > 120.0f ) { Message msg = new Message(); msg.what = FLING; this.handler.sendMessage(msg); } else { Message msg = new Message(); msg.what = LONG_PRESS; this.handler.sendMessage(msg); } } Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case FLING: case LONG_PRESS: } } }

  20. Context Sensitivity(contd) Object sensitivity in SIERRA = precision Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case FLING: case LONG_PRESS: } } } Oh: void onTouchEvent(MotionEvent e1, MotionEvent e2) { if (e1.getX() e2.getX() > 120.0f ) { Message msg = new Message(); msg.what = FLING; this.handler.sendMessage(msg); } else { Message msg = new Message(); msg.what = LONG_PRESS; this.handler.sendMessage(msg); } } C1: C2: Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case FLING: case LONG_PRESS: } } } K-obj + 1-call-site for event posting and message passing

  21. Happens-before Rules Rule 1: Action invocation rule The sender action happens-before the recipient Rule 2: Component lifecycle rule Activity.onCreate < Activity.onStart Activity.onStart < Activity.onStop Rule 3: GUI layout/object order Activity.onResume < View.onClick < Activity.onPause

  22. Happens-before Rules (contd) Rule 4: Intra-procedural domination Method M in action A has two action posts: e1 and e2 e1 dominates e2: e1 <dome2 e1 e2, is post delayed time Rule 5: Intra-action, inter-procedural domination Method M1 Action A, M2 Action A Action posts: e1 , e2 e1 dominates e2 e1 e2, is post delayed time Rule 6: Inter-action transitivity Action A1 < A2 A1 post A3, A2 post A4 Rule 7: Transitivity A1 < A2 A2 < A3 A1 < A3 A1 post A3, A2 post A4 Method M e1 e1 <dom A1 <HB e2 e2 A2

  23. Context Sensitivity(contd) Object insensitive = imprecision O1: void onTouchEvent(MotionEvent e1, MotionEvent e2) { if (e1.getX() e2.getX() > 120.0f ) { Message msg = new Message(); msg.what = FLING; this.handler.sendMessage(msg); } else { Message msg = new Message(); msg.what = LONG_PRESS; this.handler.sendMessage(msg); } } Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case FLING: case LONG_PRESS: } } }

  24. Context Sensitivity(contd) Object sensitivity in SIERRA = precision Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case FLING: case LONG_PRESS: } } } Oh: void onTouchEvent(MotionEvent e1, MotionEvent e2) { if (e1.getX() e2.getX() > 120.0f ) { Message msg = new Message(); msg.what = FLING; this.handler.sendMessage(msg); } else { Message msg = new Message(); msg.what = LONG_PRESS; this.handler.sendMessage(msg); } } C1: C2: Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case FLING: case LONG_PRESS: } } } K-obj + 1-call-site for event posting and message passing

  25. Happens-before Rules Rule 1: Action invocation rule The sender action happens-before the recipient Rule 2: Component lifecycle rule Activity.onCreate < Activity.onStart Activity.onStart < Activity.onStop Rule 3: GUI layout/object order Activity.onResume < View.onClick < Activity.onPause

  26. Happens-before Rules (contd) Rule 4: Intra-procedural domination Method M in action A has two action posts: e1 and e2 e1 dominates e2: e1 <dome2 e1 e2, is post delayed time Rule 5: Intra-action, inter-procedural domination Method M1 Action A, M2 Action A Action posts: e1 , e2 e1 dominates e2 e1 e2, is post delayed time Rule 6: Inter-action transitivity Action A1 < A2 A1 post A3, A2 post A4 Rule 7: Transitivity A1 < A2 A2 < A3 A1 < A3 A1 post A3, A2 post A4 Method M e1 e1 <dom A1 <HB e2 e2 A2

  27. Concurrency Error, Example 1 Intra-component Race Image overridden!

  28. Concurrency Error, Example 2 Inter-component Race update() before close(): OK

  29. Concurrency Error, Example 2 Inter-component Race update() after close(): Exception!

  30. Boosting Static Analysis with Fixpoint-based Callgraph Construction Manifest.xml lists all the activities onCreate onItemClick For each activity: 1. Find lifecycle callbacks, e.g., onCreate, onStart 2. Find XML registered callbacks, e.g., onClick 3. Find system callbacks, e.g., onLowMemory 4. Build call graph for found actions a) Find and add to work list registered UI callbacks, e.g., onItemClick, onLongPress thread onStart Runnable1 onLongPress onResume onClick Runnable2 AsyncTask onPost Execution onCreate OptionsMenu b) Added to work list if new actions found 5. Go back to step 4. Iterate until fixpoint msg1. onLow Memory handleMessage onCreate Prior Android static analyses: imprecise onStart * onResume onPost Execution msg1. onCreate OptionsMenu onLow Memory Runnable1 Runnable2 thread onClick onLongPress onItemClick AsyncTask handleMessage *

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#