PatBugs: A Pattern-Based Bug Detector for Cross ...

4 downloads 57892 Views 460KB Size Report
mobile app development languages (e.g., Java for Android or. Objective-C for iOS), cross-platform mobile app development tools mostly support JavaScript-like ...
2014 IEEE International Conference on Mobile Services

PatBugs: A Pattern-Based Bug Detector for Cross-Platform Mobile Applications Guangtai Liang, Jian Wang, Shaochun Li, Rong Chang IBM Research - China, Beijing, China {gtliang, wangwj, lishaoc, rong}@cn.ibm.com app against multiple platforms, developers usually rewrite the app against each target platform. Such a manual process is labor-intensive, error-prone, and usually impracticable under a limited time or cost budget.

Abstract—Mobile application developers suffer a lot from the heterogeneity of mobile platforms (e.g., rewriting a mobile app for a new mobile platform). Cross-platform development tools enable a write-once-deploy-many approach to cost-effectively developing mobile apps. Such cross-platform development tools usually provide a set of APIs to operate various device-native components (e.g., the accelerometer sensor), and require the developers to follow certain temporal constraints when using those APIs (e.g., method clearWatch must be called after method watchAcceleration is called to assure safe release of a specific accelerometer sensor). Should such constraints be violated, temporal bugs are introduced (e.g., resulting in undesireable energy wasting problems). Compared with platform-specific mobile app development languages (e.g., Java for Android or Objective-C for iOS), cross-platform mobile app development tools mostly support JavaScript-like dynamic languages (which support execution-time change of code modules and data structures). Syntactic flexibility and event-driven programming nature of such mobile app code pose additional challenges to automatically detecting temporal bugs at development time for cross-platform mobile apps. In this paper, we propose an innovative pattern-based approach to attacking the aforementioned challenges and present a realization of the approach, named PatBugs. The approach uses a Flexible Bug Pattern Specification Notation (FBPSN) to enable an effective and flexible means of specifying a bug pattern involving a set of relevant APIs with temporal constraints. Per the specified bug patterns, PatBugs could automatically detect target temporal bugs in the cross-platform web apps in an application agnostic manner. Experimental evaluations via a set of real-world mobile apps show PatBugs is effective (e.g., attained an average precision of 84%) and efficient (e.g., took less than 5.1 seconds in detecting temporal bugs). Keywords—bug patterns; bug techniques; mobile applications;

I.

detection;

In response to the issues caused by the mobile platform heterogeneity, several cross-platform development tools (e.g., Rhodes, PhoneGap, Titanium, Worklight, etc.) have been released. Such tools facilitate generating cross-platform mobile apps using one code base without compromising the overall logic of the apps, and the generated apps are deployable for multiple platforms. With the capability of “write-once-deploymany”, these tools provide a cost-effective means to delivering and maintaining mobile apps and services: accelerating timeto-market, maximizing code reuse, and shortening release cycle. As of to date, these cross-platform tools have been improved significantly such that, among other features, their generated apps could own nicer user interface and be more capable of exploiting native functionalities of the underlying operating systems. With the capability gap between cross-platform apps and native apps being narrowed down continually, the crossplatform development tools would be more appealing to the mobile app developers. As a category of mobile services, cross-platform mobile apps must intensively exploit device-native components (e.g., GPS, camera, accelerometer, etc.) to provide rich features to their users. However, these features are usually implemented via respective sets of relevant APIs provided by the crossplatform tool in use. As shown in Fig. 1, when developing cross-platform apps in Worklight, developers can use the API “navigator.accelerometer.watchAcceleration” to get the current acceleration of a mobile device at a regular interval, and then use the API “navigator.accelerometer.clearWatch” to stop watching the accelerometer sensor. Furthermore, each set of relevant APIs usually needs to be used under some specific temporal order (e.g., in order to avoid wasting energy, method clearWatch needs to be appropriately called in time to release the accelerometer sensor after the method watchAcceleration is called). Moreover, cross-platform tools usually provide many value-added capabilities to facilitate developing cross-platform apps (e.g., Worklight provides encrypted offline cache, which makes it easy for the apps to manage offline security data in mobile systems for the users). In order to safely use these capabilities, the developers must also deal with the relevant sets of APIs under various temporal constraints (e.g., an encrypted offline cache in Worklight application should be used after opened and be closed after used in time). Should these constraints be violated, temporal bugs are introduced.

cross-platform

INTRODUCTION

Mobile applications are becoming increasingly pervasive in our daily life, and enable us to perform many more tasks via smart devices like phones and tablets. Despite the great benefits of various innovative mobile apps, the rapid growth of the mobile market has resulted in heterogeneous mobile platforms. Since different mobile platforms (e.g., Android, iOS, Windows Phone, Blackberry OS, etc.) provide different programming languages and tools for the developers to code platform-specific mobile apps, the heterogeneity greatly increases the cost and latency of developing a single mobile service for all mobile platforms. To release a specific mobile

978-1-4799-5060-7/14 $31.00 © 2014 IEEE DOI 10.1109/MS.2014.21

84

This paper focuses on automatically detecting temporal bugs for the cross-platform mobile apps at development time. Compared with traditional mobile apps developed via static languages (e.g., Java, Objective-C), cross-platform mobile apps are mostly coded via JavaScript-like dynamic languages (which support execution-time change of code modules and data structures). Such dynamic languages enables a more flexible means to operating the embedded components or resources in mobile systems. For example, as shown in Fig. 1, developers usually operate a native component via some global function invocations, and the positions the component handle may appear in these invocations are uncertain. Besides that, due to the event-driven programming nature of mobile apps, a set of relevant APIs may be separately invoked in different event handlers. Such dynamic characteristics pose additional challenges for the automatic detection of temporal bugs in cross-platform mobile apps at development time.

set of bug patterns specified in FBPSN. We have realized and evaluated the proposed approach by developing the bug detection tool PatBugs. This work makes the following research contributions:  The first published work focusing on the characteristics investigation and the automatic detection of temporal bugs in cross-platform mobile apps at development time  A Flexible Bug Pattern Specification Notation (FBPSN), which facilitates specifying correct/buggy usage scenarios of embedded components or services in cross-platform mobile apps as standalone temporal bug patterns  A practical and scalable static approach to detecting temporal bugs  Empirical evaluations on three real-world projects, which show the effectiveness and efficiency of a realization of the proposed approach, a.k.a. the tool PatBugs The rest of this paper is organized as follows. Section II presents the approach overview. Section III describes the flexible bug pattern specification notation. Section IV describes the bug detection process. Section V shows the evaluation results. Section VI discusses the related work and Section VII concludes the paper.

var finished = false; // Wait for Cordova to load function wlCommonInit() { document.addEventListener("deviceready", onDeviceReady, false); } // Cordova is ready function onDeviceReady() { // Update acceleration every 3 seconds var options = {frequency : 3000}; var watchID = navigator.accelerometer .watchAcceleration(onSuccess, onError, options); if (finished == true) { if (watchID) { navigator.accelerometer.clearWatch(watchID); } } } // onSuccess: Get a snapshot of the current acceleration function onSuccess(acceleration) { var element = document.getElementById('accelerometer'); element.innerHTML = 'Acceleration X: ' + acceleration.x + '
' + 'Acceleration Y: ' + acceleration.y + '
' + 'Acceleration Z: ' + acceleration.z + '
' + '
'; finished = true; } // onError: Failed to get the acceleration function onError() { alert('onError!'); }

II.

APPROACH OVERVIEW

FBPSN-Ba sed Bug Pa tter ns

Bug Detection Program under Analysis

CFG Construction

Bug Analysis

Warnings

Preliminary Analyses Dataflow Analyses

Fig. 2. Approach Overview.

Fig. 2 illustrates an overview of the PatBugs approach, which comprises of two major components: Predefined Bug Patterns and Bug Detection Process.

Fig. 1. A sample JavaScript code fragment from a cross-platform mobile app, which uses Apache Cordova APIs to access the accelerometer component in mobile systems.

We note that, based on our proposed flexible bug pattern specification notation (FBPSN), our temporal bug detection approach summarizes typical buggy or correct usage scenarios of each focused embedded component or service in crossplatform mobile apps as standalone predefined bug patterns. Details of the FBPSN notation are described in Section III.

In this paper, we propose a pattern-based approach to detecting temporal bugs in cross-platform mobile apps at development time. The approach is app-agnostic and scalable because the bug patterns are not coded in a programming language in an app-specific manner and they can be maintained and checked in parallel with no inter-pattern dependencies. A Flexible Bug Pattern Specification Notation (FBPSN) is created in support of this approach such that typical correct/buggy usage scenarios of the embedded components or services in cross-platform mobile apps can be easily specified as standalone bug patterns. A static defect detection approach is used to support systematic detection of temporal bugs per a

With the availability of the predefined bug patterns, our bug detection process automatically detects relevant temporal bugs for cross-platform mobile apps. In this process, PatBugs accepts source code of a program under analysis as the input, and reports its detected warnings as the output. For each method of the program, PatBugs performs two major tasks:

85

CFG Construction. This task constructs a control-flow graph (CFG) for each method under analysis. Each method entry or jump target is treated as the start of a basic block1, while each jump as the end of a basic block. Exceptionthrowing jumps are also considered. Each exception-throwing instruction ends a basic block, and then such block will be connected to its exception-handling block with an “exceptionhandling” edge. Besides that, we use the “if-false” edge and the “if-true” edge to represent the true-branch jump and the falsebranch jump of an “if” statement in a CFG, respectively. While the “fall-through” edges are used to represent other jumps or sequential inter-block connections.

BP ::= “ ” BasicInfo “ ” UsageScenarios “ ” BasicInfo ::= “” s “” “ “ s “” “” s “” UsageScenarios ::= “” State { State } “” State ::= “” {Event} “ ” Event ::= “” Stmt “ ” ToState “” Stmt ::= “” [“”] [Re] [“” Re “”] “” ToState ::= “”n”” Re ::= “” rs “” st ::= “MethodCall” | “Return” | “Assign” | “NullEqualityIfCheck” | “DirectIfNotCheck” b::= “true” | “false” s::= any string rs ::= any regular expression string n::= any number

Dataflow Analyses. For each CFG, PatBugs performs a series of dataflow analyses to detect temporal bugs. The dataflow analyses are classified as “preliminary analyses” and “bug analysis”. The preliminary analyses are used to provide preliminary information for the bug analysis, and they include a points-to analysis and an object-escape analysis. The bug analysis iteratively traverses a CFG under analysis to check whether the CFG contains some buggy usage scenarios (i.e., bug instances) of some focused embedded components or services based on predefined bug patterns. Details of this task are described in Section IV.

Fig. 3. A formal specification of the proposed FBPSN.

In contrast with predefined bug patterns (which are responsible for providing “what to detect”) the bug detection process is responsible for implementing “how to detect”. The design decision of separating bug knowledge (specified in bug patterns) from detection logic (implemented in bug analysis) improves the scalability of our approach: once a new bug pattern is discovered and then specified as a FBPSN-based bug pattern, the detection capability can be automatically enriched to support the detection of temporal bugs per the new pattern. III.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

FLEXIBLE BUG PATTERN SPECIFICATION NOTATION

Flexible Bug Pattern Specification Notation (FBPSN) facilitates codifying buggy or correct usage scenarios of focused embedded components or services in cross-platform mobile apps as standalone bug patterns. Fig. 3 shows a formal specification of the proposed FBPSN, and Fig. 4 exemplifies an FBPSN-based bug pattern regarding “ensuring accelerometer components released after used in time”. We now elaborate on the FBPSN example. The root element BugPattern specifies a concrete bug pattern with FBPSN, and it includes two main parts: BasicInfo and UsageScenarios. The part BasicInfo provides necessary basic information for a bug pattern under specification, while the part UsageScenarios provides detailed buggy or correct usage scenarios of the focused object(s) of a bug pattern under specification. The part BasicInfo includes three child elements: Description, ErrorMessage, and Severity. The elements Description, ErrorMessage, and Severity provide a short description, a warning-reporting message template, and a severity value for the bugs related to the bug pattern under specifying, respectively.

The accelerometer component is not slept after watched in time. \n [Performance(Energy)] The accelerometer component should be slept after watched in time: {0}\n Buggy paths: \n {1}\n 1 navigator.accelerometer.watchAcceleration(.*) 2 3 3 navigator.accelerometer.clearWatch(.*) 3

Fig. 4. The FBPSN-based specification of the no-sleep bug pattern “ensuring accelerometer components released after used in time”.

1

A basic block is represented as a node in a CFG and contains a straight-line piece of code without any jumps.

86

As shown in Fig. 5, the focused object Of of the no-sleep bug pattern “ensuring accelerometer components released after used in time” has three usage states. After the operation of the assignment statement “Of = navigator.accelerometer. watchAcceleration(.*)”, the state of Of would be transited from State 1 (an initial state) to State 2 (a buggy state). After the operation of a NullEqualityIfCheck statment, a DirectIfNotCheck statement (i.e., Of would be null when its condition is true), or a method-call statement, whose signature is as “navigator.accelerometer.clearWatch(.*)” and the first input parameter of whom is the current focused object Of, the state of Of would be transited from State 2 to State 3 (a bugfree state).

Fig. 5. A visualized specification of the no-sleep bug pattern “ensuring accelerometer components released after used in time”.

The element UsageScenarios uses a finite state automaton (i.e., states and state-transition events) to specify typical buggy or correct usage scenarios of focused objects of a bug pattern under specification. In each State element, the optional attribute initial indicates whether the state is the initial state of the usage scenario automaton of the bug pattern or not, and its default value is false. The attribute buggy indicates whether the state is buggy or not. Our detection approach would report a warning for each focused object which is still in a buggy state when a method under analysis exits.

IV.

BUG DETECTION PROCESS

In our approach, the bug detection process relies on a series of dataflow analyses to detect temporal bugs per predefined FBPSN-formatted bug patterns by systematically and iteratively traversing control-flow graphs of methods under analysis. The dataflow analyses comprise of Preliminary Analyses and Bug Analysis. The preliminary analyses are responsible for providing preliminary information for the bug analysis. The bug analysis is responsible for checking whether each method under analysis contains some buggy usage scenarios (i.e., bug instances) of some focused embedded components based on predefined bug patterns. Before describing the bug analysis in Section IV-B, we first introduce its dependent preliminary analyses in Section IV-A.

In a bug pattern, certain statements (which can be seen as certain usage events) can transit the focused object(s) from one state to another. Such state-transition events can be specified with the TransitionEvent element in a State element. The TransitionEvent element includes two child elements: Statement and ToState. The element ToState specifies the destination state the event would transit the current state to, while the element Statement specifies a certain type of statements that would cause the state transition.

A. Preliminary Analyses The preliminary analyses include a points-to analysis and an object-escape analysis, whose analysis results will be used by the bug analysis.

In each Statement element, the attribute Type specifies a certain type of statements that a focused object Of would be involved in. As of to date, our approach allows specifying five different types of statements: MethodCall (a method call statement that involves Of), Return (a return statement that returns Of), Assign (an assignment statement that involves Of), NullEqualityIfCheck (an if statement that makes an equality check between Of and null), and DirectIfNotCheck (an if statement in whose condition Of is directly prefixed with the negation operator, such as “if (!Of )”).

The points-to analysis performs a forward inter-procedural context-sensitive dataflow analysis to identify points-to information among all variables. The points-to information of a variable provides the potential object(s) it may points to, its potential actual type(s), and its potential aliases. For the assignment statement types listed in Table I, we have modeled and propagated their effects on points-to information during this analysis.

The element Statement also includes three optional child elements: CurrentObject, RegularExpression, and RightExpr. The element CurrentObject specifies which involved object of the statement should be treated as the current focused object of the bug pattern. If the statement is a method call statement, we could specify the invoker (by setting the attribute isInvoker as true) or any input parameter of the statement (by setting the attributes isParam and paramIndex) as the current focused object. If the statement is an assignment statement, we could also set the object that is assigned by the statement (i.e., assignee) as the current focused object (via setting the attribute isAssignee). For an assignment statement, the element RightExpr supports to specify the right-hand expression of the assign operator (e.g., a method-call expression). The element RegularExpression can be used to provide a regular-expression based signature for a statement or an expression under specifying.

TABLE I.

MAIN TYPES OF ASSIGNMENT STATEMENTS PROCESSED BY THE POINTS-TO ANALYSIS x=y x = r.f x = new X() x = null x = r.m()

r.f = r.g r.f = x r.f = new X() r.f = null r.f = r.m()

The object-escape analysis performs a forward intraprocedural dataflow analysis to identify the escaped objects of each method under analysis. In a specific method, once a local object allocated or created in the method is globally referenced (e.g., returned as a return value or assigned to a globally visible variable), other methods or threads may have chance to access it. In such cases, we say the object is an escaped object of the method since its living scope is escaped from the method scope. In this analysis, if a newly-created object in a specific method is assigned to some external variable(s) of the method or

87

returned as a return value, we treat it as an escaped object of the method.

cfgm (Lines a-b), and then generates its object-escape information Escm and its points-to information Points-tom. Then the algorithm calls analyzeMethod() to conduct the bug analysis for the method M (Line d). The function analyzeMethod() returns a data structure States, which records what usage state each focused object is in when m exits. Finally, the algorithm extracts and reports a warning for each object which is still in a buggy state when m exits by examining States (Lines e-g).

B. Bug Analysis algorithm BugAnalysis input: M: a method under analysis output: W: bug warnings to report declare: States: usage states of all focused objects at the exit node of the method Esc, Points-to: object-escape info, points-to info of a method a b c d e f g

begin generate the control-flow graph cfgm of the method M; generate its Escm, Points-tom; States = analyzeMethod (cfgm , 0, null, Escm, Points-tom); extract W from States; output W; end

The function analyzeMethod() performs a typical forward worklist algorithm, which tries to iteratively compute a fixed point over the usage states of all focused objects (Lines 1-35). In order to flexibly control the precision-cost tradeoff, it defines a maximum inter-procedural analysis depth maxDepth and a maximum iteration number maxIter. To reach a fixed point (Lines 30-31), the function traverses the nodes of cfg in the reverse-post order (Lines 7-29) iteratively until maxIter is reached (Line 5). For each node n of cfg, the function first recomputes Statesnin, the usage states of all focuses objects at the incoming-edge side (abbr. IN edge) of n (Line 6). The process details are described in Section IV-B-1. If Statesnin is changed or n is never visited (i.e., Statesnin is still null), the function visits each statement s of n and then propagates the impacts of s on Statesnin (Lines 11-27). The process details are described in Section IV-B-2. After the impact propagation, the function saves the updated Statesnin as Statesnout, the usage states of all focused objects at the outgoing-edge side (abbr. OUT edge) of n, if needed (Lines 28-29). After the nodetraversing process (i.e., either the fixed point is reached or maxIter is reached), the analysis will conduct a further analysis for the escaped objects of the method under analysis by further analyzing the typical “energy-saving” methods of the mobile app (Lines 32-33). The process details are described in Section IV-B-3. Finally, the analysis returns Statesnout as its output.

function analyzeMethod input: cfg: the control-flow graph of a method under analysis depth: inter-procedural analysis depth Statescaller: usage states of all focused objects from one of its callers Esc, Points-to output: Stateexitout: usage states of all focused objects at the out side of exit declare: entry, exit: the entry node, the exit node of cfg; maxDepth: the maximum inter-procedural analysis depth; maxIter: the maximum iteration times; Statesnin, Statesnout: States at the IN side or the OUT side of a node n; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

begin int i = 0; assign Statescaller to Statesentryin; load a predefined FBPSN-based bug pattern BP ; while (i < maxIter) do i++; foreach node n of cfg in reverse post order do recompute and save Statesnin; if (Statesnin is changed) or (Statesnin = = null) then foreach statement s of n do if (s contains a call on a method m' ) then if (s is a method call statement) then update Statesnin based on this method-call event e ; if (s is an assignment statement) then update Statesnin based on this assignment event e ; if (Statesnin has no change) then if (depth < maxIter) then if (the method code of m' is available) then generate cfgm' , Escm', Points-to m' ; depth++ ; Statenin = analyzeMethod (cfgm', depth, Statesnin, Escm', Points-to m') ; else if (s is a return statement) then in update Statesn based on this assignment event e ; else if (s is a NullEqualityIfCheck statement) then update Statesnin based on this NullEqualityIfCheck event e ; else if (s is a DirectIfNotCheck statement) then update Statesnin based on this DirectIfNotCheck event e ; if (Statesnin ! = Statesnout) then save the updated Statesnin as Statesnout; if (no States is changed for all nodes of cfg) do break; if (depth == 0) then update the states of the escaped objects in Statesexitout by further visiting the typical energy-saving methods; return Statesexitout ; end

1) Computation Process of Statesnin (Line 8). In this process, the function first retrieves all IN edges of the node n. And then, for each IN edge, the function retrieves Statesn'out of the node n' the IN edge flows out of. If the IN edge is an exception-handling edge, the function checks whether the exception is thrown when creating an object o: if yes (that means o is not successfully created), roll back the effect of the exception-throwing statement on the usage state of o StatesO guided by the loaded bug pattern BP. Finally, merge all retrieved Statesn'out as the updated Statesnin. Example 1. Fig. 7 illustrates the bug analysis process based on the constructed control flow graph of the method onDeviceReady in the code example shown in Fig. 1. In Fig. 7, States7in, the usage states of focused objects at In7 (the IN side of Block 7), is computed by merging the usage states at the site In76 (i.e., the incoming usage states of Block 7 from Block 6) and the usage states at the site In74 (i.e., the incoming usage states of Block 7 from Block 4).

Fig. 6. The algorithm of the bug analysis.

The bug analysis is a forward inter-procedural contextsensitive CFG-based dataflow analysis. After tracking states of focused objects along the CFG of a method under analysis, it will report a warning for each object which is still in a buggy state at the exit of the method.

2) Statement Impact Propagation (Lines 10-27). In this process, the function propagates effects of five types of statements on Statesnin: method-call statements, assignment statements, return statements, NullEqualityIfCheck statements, and DirectIfNotCheck statements. The effect propagation

Fig. 6 presents the inter-procedural bug analysis algorithm. It takes as input a method under analysis M, and produces as output a list of bug warnings W. For each method under analysis M, the algorithm first performs some preprocessing to generate its control-flow graph 88

process is conducted based on the guidance of the loaded bug pattern BP. : fall-through : if-true 1

: if-false

var options = {frequency : 3000};

var watchID = navigator.accelerometer 2 .watchAcceleration(onSuccess, onError, options); 3

if (finised == true)

if (watchID)

4

5

navigator.accelerometer. clearWatch(watchID); 6

return;

Site Out2 Out34 Out36

After executing the aforementioned steps (Lines 12-15), if Statesnin has no change, the function will dive into the callee m’ to conduct an inter-procedural analysis (Lines 18-21) unless the maximum inter-procedural depth maxIter is reached (Line 17). In this step, the code of m' will be first identified and loaded with the help of Points-to. When m' have n possible candidates, the function would randomly select one to continue the process. Once the code of m' is successfully loaded, the function will conduct an inter-procedural callee analysis for m'.

States watchID : 2

watchID : 2

Out45

watchID : 2

Out46

watchID : 3

Out5 6

watchID : 3

In7

watchID : 2, 3

Out7

watchID : 2, 3

If s is a return statement, the function constructs a return event e, and then uses it to update the states of all objects in Statesnin (Lines 22-23). If s is an if statement which makes an equality check between a variable and null, the function constructs a NullEqualityIfCheck event e, and then uses it to update the states of its involved objects in Statesnin (Lines 24-25). If s is an if statement which directly prefixes a variable with a negation operator, the function constructs a DirectIfNotCheck event e, and then uses it to update the states of its involved objects in Statesnin (Lines 26-27). Example 2. As shown in Fig. 7, when impacting the effect of the statement in Block 2, the function will construct an assignment event e and uses it to update the usage states of the assignee object OwatchID and the invoker object. According to the bug pattern specification, the current event e would only impact the usage state of the assignee object. Therefore, based on e, the function transits the usage state of OwatchID from State 1, an initial state, to State 2, a suspicious buggy state. When analyzing the if statement in Block 4, the function will construct a DirectIfNotCheck event e to impact its effects on usage states of its involved objects along the false branch of the if statement. Based on such DirectIfNotCheck event, the function would transfer the usage state of OwatchID from State 2 to State 3 at the false-branch side of Block 4. When analyzing the method-call statement in Block 5, the function will construct a method-call event e and uses it to update the usage states of the invoker object and the input parameter object OwatchID. According to the corresponding bug pattern specification, the current event e would only impact the usage state of the first input parameter object. Therefore, based on e, the function transits the usage state of OwatchID from State 2 to State 3 along this path. When analyzing the exit block, the function first merges analysis results from different incoming edges as States6in, then constructs a return event to update states of all involved objects in States6in, and finally ouputs the updated States6in as States6out (In this example, the exit block makes no change to States7in ). Based on States6out, the function would report a warning on OwatchID since it could still be in a buggy state at the exit of the method under analysis when the if condition in Block 3 does not hold.

Fig. 7. The bug analysis process on the example code in Fig. 1.

If the statement under analysis s contains a method call (e.g., calling a method m’), the function first checks whether s is a method-call statement (Line 12). If yes, the function constructs a method-call event e based on s (if the invoker of the method call has aliases, the function would also construct a method-call event for each alias of the invoker in this step). Next, the function retrieves usage states of the involved objects (e.g., the invoker object and all input parameter objects) of the method call based on points-to information. After that, the function tries to impact the effect of each constructed methodcall event e on the usage states of the involved objects. During the effect impacting process for any involved object (e.g., the object pointed by the first input parameter Oinput1) in the whole analysis, the function first retrieves all candidate state-transition events the object can accept under its current usage state based on BP. Second, the function checks whether the current method-call event satisfies any of its accepting state-transition events. If yes, the function further checks whether or not the involved object is the specified object the matched accepting event should impact on based on the CurrentObject setting of the accepting event specified in the bug pattern (e.g., whether the state of the first input parameter would be impacted by the accepting event). If yes, the function transits the usage state of the involved object to a new destination state indicated by the matched accepting event. If s is an assignment statement containing a method call expression (Line 14), the function constructs a statement event e based on s (if the invoker of the method call has aliases, the function would also construct a different assignment event for each alias of the invoker in this step). Next, the function retrieves the usage states of the involved objects (e.g., the assignee object, the invoker object, and all input parameter objects) of the assignment statement based on points-to information. After that, the function tries to impact the effect of each constructed assignment event e on the usage states of the involved objects.

3) Further Analysis for Escaped Objects (Lines 32-33). It is common in mobile apps that some native components need to be used over a long period of time (e.g., an electronic map application needs to keep GPS on to reflect the realtime geographical location of a mobile user when the application keeps in the foreground of a mobile system). In such cases, the native components accessed in a function may be released in some other functions or some certain event handlers. During 89

the mobile app development process, it has become a recommended practice that the acquired native components should be safely released when a mobile app is exited or switched as a background app to save energy of mobile devices. As shown in Fig. 8, the accessed accelerometer component is released in the function onPause, which is specified to be triggered when the application is switched to the background. In our approach, we call such methods or event handlers that should explicitly play the role of energy-wasting terminator in mobile apps as energy-saving methods.

the evaluation, we first predefine three different temporal bug patterns into PatBugs, including the bug pattern shown in Fig. 3 (P1), the bug pattern about “WL.EncryptedCache should be used after opened and be closed after used in time” (P2), and the bug pattern about “Geolocation service should be slept after watched in time” (P3). We then apply PatBugs to detect related temporal bugs for three anonymous real-world projects (A, B, and C) which are developed within IBM. Table II shows basic information about each project under analysis (e.g., the number of their included JavaScript files and JavaScript code lines).

In our proposed bug analysis process, after analyzing a method under analysis (Lines 2-31), for those escaped objects which are still in buggy states, the function would further dive into the traditional energy-saving methods (e.g., the event handlers onPause and onBackbutton) to check whether these objects are safely released there. For the example code shown in Fig. 8, after analyzing the method startWatch, the function would further analyze the event handler onPause to check whether OwatchID is safely released in it. Only when the handler misses releasing OwatchID, the function would report a no-sleep warning on OwatchID .

Table III shows the statistical result of the warnings PatBugs reports. In each table cell, the precision of the warnings PatBugs reports for each project based on each bug pattern. The number of the corresponding true warnings and total warnings are listed as well. For example, regarding the pattern P1 for project A, PatBugs achieves a precision of 75%, since that it reports four warnings in total and three of them are confirmed as true warnings through our manual verification. In total, our detector reports nineteen warnings for all of the three projects under analysis, and among them, sixteen warnings are manually confirmed as true ones. Therefore, PatBugs achieves an average precision of 84%, which shows that our approach is effective in detecting temporal bugs for cross-platform applications.

var finished = false; var watchID = null; function wlCommonInit() { document.addEventListener("deviceready", onDeviceReady, false); } function onDeviceReady() { document.addEventListener("pause", onPause, false); document.addEventListener("resume", onResume, false); startWatch(); } function startWatch() { var options = {frequency : 3000}; watchID = navigator.accelerometer .watchAcceleration(onSuccess, onError, options); } function stopWatch() { if (watchID) { navigator.accelerometer.clearWatch(watchID); watchID = null; } } function onPause() { stopWatch(); } function onResume() { if (watchID == null) { startWatch(); } } function onSuccess(acceleration) { ...... } function onError() { alert('onError!'); }

Besides that, the efficiency of our detector is also measured in this evaluation. Our detector takes only about 4.8 seconds, 3.1 seconds, and 5.1 seconds to detect bugs based on the three bug patterns for the project A, B, and C, correspondingly. The evaluation is conducted in a laptop of Thinkpad T430 (CPU: Intel(R) Core(TM) i5-3380M @ 2.90GHz; RAM: 8G; OS: Windows 7 64-bit). The result shows that our detector is also efficient in detecting bugs for cross-platform applications. TABLE II.

Project A B C

# of included JS files 10 15 17

# of included JS Code Lines 3225 2117 3420

TABLE III. STATISTICAL RESULT OF THE WARNINGS EEPORTED BY PATBUGS FOR EACH PROJECT UNDER ANALYSIS . Project A B C

P1 75% (3/4) 100% (2/2) 83% (5/6)

VI.

P2 — (0/0) 100% (1/1) 67% (2/3)

P3 100% (3/3) — (0/0) — (0/0)

RELATED WORK

Survey on Mobile Applications. Ribeiro and Silva [1] provide a global view of the cross-platforms and languages for mobile apps. In their work, they compare six tools or frameworks (i.e., Rhodes, PhoneGap, DragonRAD, Titanium, mobl, and mdsl) that support the development of crossplatform apps in terms of several global aspects (e.g., general approaches, development languages, resulting app forms, supported mobile platforms, and so on). Pathak and et al. [4] present a taxonomy on the types of energy bugs in smart phones and estimates no-sleep bugs to constitute about 70% of all energy bugs in smart phone apps.

Fig. 8. A JavaScript code fragment example from a cross-platform application, which uses “energy-saving” event handlers to release the accelerometer component in mobile systems.

V.

BASIC INFO OF THE PROJECTS UNDER ANALYSIS.

EVALUATION

Based on the aforementioned approach, we implement a temporal bug detector called PatBugs for cross-platform mobile apps. In this section, we evaluate its performance. In

90

Detection and Prevention of Mobile Application Bugs. Martie et al. [2] use statistical models to identify Android’s most debated high level issues. Pathak et al. [5] make the first advances towards understanding and automatically detecting software energy bugs on android smart phones. They propose an automatic solution to detect energy bugs based on the classic reaching definitions dataflow analysis algorithm. However, the detection capability of their approach is limited (e.g., suitable only for temporal bug patterns involving two methods), and can not be directly applied to detect complex temporal bugs for cross-platform mobile apps.

To make our approach more practical, we plan to predefine more bug patterns to detect bugs for more real-world projects in our future work. During this process, we plan to keep exploring better approaches to specify bug patterns and detect temporal bugs for event-based mobile applications. REFERENCES [1]

[2]

Diagnosis of Mobile Application Bugs. MobiBug [3] is a framework for mobile debugging that focuses on how to perform lightweight logging on resource-limited smart phones. MobiBug is designed to be a traditional runtime bug tracing system, targeting bugs that usually result in app crashes. Guana et al. [17] use Android bug repository data to comprehend the architectural layers of Android, which can be used to facilitate bug diagnosis process.

[3]

[4]

Pattern-Based Bug Detection. Engler et al. [6] use a metalevel compilation to write simple, system-specific complier extensions which can automatically check subject code for rule violations. Liang et al. [7, 8] propose a pattern-based static bug detection approach for traditional Java programs. However, their proposed bug pattern specification notations cannot be used directly to specify flexible bug patterns in cross-platform mobile apps, and also their approaches are not designed to detect bugs for event-based applications.

[5]

[6] [7]

[8]

VII. CONCLUSION In this paper, we pinpointed that temporal bug patterns in cross-platform mobile apps are usually much more complex than those of traditional object-oriented applications. Based on this observation, we proposed an effective pattern-based approach to detecting temporal bugs in cross-platform mobile apps at development time. In our approach, the temporal constraints among a set of relevant APIs can be easily specified as standalone bug patterns in an app-agnostic manner via our proposed flexible bug pattern specification notation (FBPSN). Per predefined bug patterns, our bug detection process can automatically detect related temporal bugs in cross-platform mobile apps. The experimental evaluation of PatBugs using real-world cross-platform mobile apps showed the proposed approach is effective and could be realized efficiently. In our approach, the bug-pattern specification is cleanly separated from the implementation of bug detection logic, which improves the scalability and the generality of our approach. Once a new bug pattern is defined with FBPSN, our approach can automatically own the power to detect related temporal bugs in a cross-platform mobile app.

[9]

[10] [11]

[12] [13]

[14]

[15]

[16]

In the future, we would like to advance our work in term of our experience with the current PatBugs implementation. First, current FBPSN cannot be used to specify bug patterns involving multiple interacting objects (e.g., an object of java.util.ArrayList should not be updated when its internal object is being traversed via a java.util.Iterator object). Second, the scope of predefined bug patterns need be expanded. With more patterns predefined and applied, the generality of our PatBugs approach could be broadened accordingly.

[17] [18] [19]

[20]

91

André Ribeiro, and Alberto Rodrigues da Silva, “Survey on CrossPlatforms and Languages for Mobile Apps,” in Proceedings of International Conference on the Quality of Information and Communications Technology. 2012. L. Martie, V. Palepu, H. Sajnani, and C. Lopes, “Trendy bugs - topic trends in the android bug reports,” in Proceedings of MSR 2012 (9th Working Conference on Mining Software Repositories). IEEE CS Press, 2012, pp. 120–123. S. Agarwal, R. Mahajan, A. Zheng, and V. Bahl, “There’s an app for that, but it doesn’t work. diagnosing mobile applications in the wild,” in Hotnets, 2010. A. Pathak, Y. C. Hu, and M. Zhang, “Bootstrapping energy debugging for smartphones: A first look at energy bugs in mobile devices,” in Proc. of Hotnets, 2011. Abhinav Pathak, Abhilash Jindal, Y. Charlie Hu, and Samuel P. Midkiff, “What is keeping my phone awake?: characterizing and detecting nosleep energy bugs in smartphone apps,” in Proceedings of the 10th international conference on Mobile systems, applications, and services (MobiSys '12). ACM, New York, NY, USA, 267-280. D. Engler and M. Musuvathi, “Static Analysis versus Software Model Checking for Bug Finding,” in Proc. of VMCAI 2004, pp. 191-210. V. Guana, F. Rocha, A. Hindle, and E. Stroulia, “Do the stars align? multidimensional analysis of android’s layered architecture,” in Proceedings of MSR 2012. IEEE Computer Society Press, 2012. Guangtai Liang, Qianxiang Wang, Tao Xie, Hong Mei, “Inferring Project-Specific Bug Patterns for Detecting Sibling Bugs,” in Proc. of ESEC/FSE, 2013.08. Guangtai Liang, Qian Wu, Qianxiang Wang, Hong Mei, “An Effective Defect Detection and Warning Prioritization Approach for Resource Leaks,” in Proc. of COMPSAC, 2012.07. “Android proguard.” URL: http://developer.android.com/guide/developing/tools/proguard.html “Sipservice: release wake lock for cancelled tasks.” URL: https://github.com/android/platform_frameworks_base/commit/0c01e6e 060d079b0a25a44c1159db63944afce17 “Facebook 1.3 not releasing partial wake lock.” URL: http://geekfor.me/news/facebook-1-3-wakelock/ “Checkinmap: Disable location updates when checkinmap is paused.” URL:https://github.com/jmschanck/Ushahidi_Android/commit/337b48f 5f2725f3e84796fab12947ffbec3c0357 “Ensuring that the wakelock is released during exception.” URL: https://github.com/commonsguy/cwacwakeful/commit/c7d440f1150887bb9a1a3c44015c7579d7ab1970 “Ensure wake lock is released when an ioexception is thrown during a sync.” URL: https://github.com/mtuton/android_apps_email/commit/ 85fec873c4413ef86d40972cc3dbe925ee23e733 “Googlemaps holding wakelock for long.” URL: http://www.google.com/support/forum/p/maps/thread?tid=016d2cec36d 7410b E. M. Myers, “A precise inter-procedural data flow algorithm,” in Proc. of POPL. ACM, 1981. J. B. Kam and J. D. Ullman, “Global data flow analysis and iterative algorithms,” J. ACM, vol. 23, 1976. “Jolt Awards: Mobile Development Tools.” URL: http://www.drdobbs.com/joltawards/jolt-awards-mobile-developmenttools/240166387?pgno=1 S. R. Humayoun, S. Ehrhart, and A. Ebert, “Developing mobile apps using cross-platform frameworks: a case study,” In Proc. of HCI’13, Masaaki Kurosu (Ed.), Vol. Part I. Springer-Verlag, Berlin, Heidelberg.