DepOwl: Detecting Dependency Bugs to Prevent Compatibility Failures
Zhouyang Jia, Shanshan Li, Tingting Yu, Chen Zeng, Erci Xu, Xiaodong Liu, Ji Wang, Xiangke Liao
DDepOwl : Detecting Dependency Bugs to PreventCompatibility Failures
Zhouyang Jia ∗† , Shanshan Li ∗‡ , Tingting Yu † , Chen Zeng ∗ , Erci Xu ∗ , Xiaodong Liu ∗‡ , Ji Wang ∗ , Xiangke Liao ∗∗ College of Computer ScienceNational University of Defense Technology
Changsha, China{jiazhouyang, shanshanli, zengchen15, xuerci, liuxiaodong,wj, xkliao}@nudt.edu.cn † Department of Computer ScienceUniversity of Kentucky
Lexington, [email protected]
Abstract —Applications depend on libraries to avoid reinvent-ing the wheel. Libraries may have incompatible changes duringevolving. As a result, applications will suffer from compatibilityfailures. There has been much research on addressing detectingincompatible changes in libraries, or helping applications co-evolve with the libraries. The existing solution helps the latestapplication version work well against the latest library version asan afterthought. However, end users have already been sufferingfrom the failures and have to wait for new versions. In thispaper, we propose
DepOwl , a practical tool helping users preventcompatibility failures. The key idea is to avoid using incompatibleversions from the very beginning. We evaluated
DepOwl on 38known compatibility failures from StackOverflow, and
DepOwl can prevent 35 of them. We also evaluated
DepOwl using thesoftware repository shipped with Ubuntu-19.10.
DepOwl detected77 unknown dependency bugs, which may lead to compatibilityfailures.
Index Terms —Software dependency, Library incompatibility,Compatibility failure.
I. I
NTRODUCTION
Applications reuse as much existing code as possible forcost savings. Existing code is often in the form of libraries,which keep evolving and may introduce incompatible changes(e.g., changing interface signatures). Misuses of library ver-sions containing incompatible changes may lead to failuresin applications. We refer to these failures as compatibilityfailures , or
CFailures .A CFailure involves three roles: library developers, appli-cation developers, and end users ( library and application arerelative concepts as an application itself may be a library foranther application). As shown in Figure 1, library developersrelease two versions containing incompatible changes. Thechanges are classified into two types: backward incompatiblechange (BIC) (e.g., removing an interface), and forward in-compatible change (FIC) (e.g., adding an interface). The solid
We thank the anonymous reviewers for their insightful comments. We alsothank Xin Peng, Bihuan Chen and Kaifeng Huang for their suggestions. Thiswork was supported in part by NSFC No. 61872373; National Key R&DProgram of China No. 2018YFB0204301; NSFC No. 61872375, U19A2060,61802416; NSF grant CCF-1909085; and China Scholarship Council. ‡ Shanshan Li and Xiaodong Liu are the corresponding authors.
Old library version New library versionApplication code Application binary
FICBIC Library developerApplication developer End user
Develop InstallRelease
Fig. 1: Incompatible changes cause
CFailures . The solid anddashed lines show how BIC (backward incompatible changes) andFIC (forward incompatible changes) cause CFailures, respectively. (dashed) lines show how a
BIC (an
FIC ) causes
CFailures :if application developers develop an application based on theold (new) library version, end users may suffer from
CFailures when linking the application to the new (old) library version.In either case, the incompatible change causes
CFailures .When incompatible changes happened, the three roles canprevent
CFailures with different solutions: 1) library develop-ers can undo the changes in the latest version; 2) applicationdevelopers can update the application to adapt the changes;3) end users can avoid using the incompatible library versions.There has been some research on detecting library changes[1]–[6]. These techniques focus on suggesting incompatiblechanges for library developers (i.e., the first solution). Therehas also been some work on detecting incompatible APIusages in applications [7]–[10], or helping applications adaptlibrary changes [11]–[14]. These techniques focus on helpingapplication developers update the application (i.e., the secondsolution). In either of the above solutions, end users may havealready suffered from
CFailures and have to wait for newlibrary/application versions. The third solution, on the otherhand, is more light-weighted — end users can avoid
CFailures from the very beginning without having to see the
CFailures occur. However, there exists no research that can achieve thisgoal by helping users automatically select compatible libraryversions.Some industrial settings use dependency management sys- a r X i v : . [ c s . S E ] F e b ems ( DMSs ) that can help users select right library versions.Examples include dnf [15] in RPM-based Linux distributionsand apt [16] in Debian-based Linux distributions. However,
DMSs have several practical limitations (more details in Sec-tion II):1)
DMSs require manual inputs from either applicationor library developers, which can be tedious and error-prone. For example, dnf requires application developersto specify version ranges of required libraries. apt askslibrary developers to maintain a symbol list provided bythe library.2) Manual inputs provided by developers may be outdatedas the libraries evolve. For example, application de-velopers specified the version range libfoo>=1.0 , afterwhich libfoo-2.0 is released and backward incompatibleto libfoo-1.0 . The version range should have been updatedto .3) Developers may not comply with the requirements of the
DMSs . For example, apt requires libraries not to breakbackward compatibility in a package, but library develop-ers may unintentionally introduce incompatibilities sincethere is no mechanism to guarantee the requirement.Since
DMSs depend on version ranges specified in specifi-cation files (e.g., the control file used by apt , or the .spec fileused by dnf ) to resolve dependencies, the above limitationsmay introduce incompatible versions being included in theversion ranges. In this case, we say there are dependency bugs (or
DepBugs ) in the specification files.To address the limitations within
DMSs , we propose a newapproach,
DepOwl , to detect
DepBugs and prevent
CFailures . DepOwl works at the binary level to check compatibilitybetween libraries and applications instead of analyzing the APIusage in source code of applications (e.g., compilers ) . This isadvantageous for end users who prefer to install binary fileswithout having to compile the source code. For example, endusers often use the command apt install to download binaryfiles. The source-code level compatibility can not guaranteethe compatibility of the binary files installed by the users.Specifically, given the binaries of a library and an ap-plication, DepOwl automatically checks if the application iscompatible to each version of the library, so it can help usersselect the right library versions to prevent
CFailures . DepOwl contains three major steps. In the first step,
DepOwl collectsall potentially incompatible changes (e.g., add/remove/changeinterfaces) during the evolution of the library (from an oldversion to a new version), including both
BICs and
FICs .Next,
DepOwl checks if the API usage in the target applicationmatches the API definitions in either of the old and new libraryversions. If the change is a
BIC ( FIC ) and the API usagematches the old (new) library version, the new (old) libraryversion is regarded as an incompatible version. In the thirdstep,
DepOwl compares the incompatible version to all otherlibrary versions. Any version that is both backward and for-ward compatible to the incompatible version is also identified The current design of
DepOwl focuses on C/C++ applications and libraries. as an incompatible version. Users can prevent
CFailures byavoiding using the reported incompatible versions.A common usage scenario of
DepOwl is to serve as aplugin for
DMSs . Taking apt as an example, in Debian-based Linux distributions, apt helps users manage applicationdependencies. Each application contains a control file indi-cating its required libraries and version ranges. These ranges,however, may contain incompatible versions.
DepOwl is ableto detect incompatible versions, so that apt can avoid usingincompatible versions when resolving dependencies, and userswill be free of
CFailures .We evaluated
DepOwl ’s ability in preventing both knownand unknown
CFailures . We first evaluated
DepOwl on 38real-world known
CFailures from StackOverflow, and
DepOwl can prevent 35 of them. We also applied
DepOwl to thesoftware repository shipped with Ubuntu-19.10, the latestUbuntu stable version at the time of writing.
DepOwl detected77 unknown
DepBugs , which may cause
CFailures .In summary, the contributions of this paper are as follows:1) We propose a lightweight solution to prevent
CFailures when incompatible changes happened in libraries. Exist-ing research work mainly focuses on fixing
CFailures innew versions, but can not prevent the
CFailures . Industrial
DMSs can help users resolve dependencies, but still havelimitations.2) We design and implement
DepOwl , a practical tool todetect
DepBugs and prevent
CFailures . DepOwl cancollect incompatible changes in libraries, detect
DepBugs in applications, and suggest incompatible versions to helpusers prevent
CFailures .3)
DepOwl can prevent 35 out of 38
CFailures selected fromStackOverflow. and detect 77
DepBugs in the repositoryshipped with Ubuntu-19.10.
DepOwl is more accuratecompared with baseline methods, and requires no humanefforts.II. E
XISTING
DMSs
AND T HEIR L IMITATIONS
Manual management of software dependencies is time-consuming and sometimes even error-prone, since an appli-cation may depend on many libraries, which keep evolving allthe time. In this regard, a common approach, especially in theopen-source community, is to use a dependency managementsystem (
DMS ), e.g., pip [17] for Python,
Maven [18] forJava, npm [19] for JavaScript, apt [16] and dnf [15] in Linuxdistributions.These
DMSs provide interfaces for developers to specifydependencies (i.e., the required libraries and correspondingversions), as well as repositories that contain all libraries.Developers manually specify dependencies, then the
DMSs can automatically download and install the libraries from therepositories. For a required library, developers can specifya fixed version or a version range. Using a fixed versionis a reliable solution because it has little to virtually zero
CFailures , but it lacks flexibility because critical fixes in laterversions of the library cannot be automatically included [20].While using a version range increases flexibility since it can2 //cockpit-202.1/src/bridge/cockpitpipechannel.c id = g_strdup_printf ("internal-stream-%" ... inserted = g_hash_table_replace (..., id, ...); g_assert (inserted); //homebank-5.2.2/src/hb-transaction.c if( g_hash_table_lookup(...) == NULL ){ retval = g_hash_table_insert (...); } return retval;
Fig. 2: Example usages of library incompatible changes.
Bothcockpit-202.1 and homebank-5.2.2 use return values of glib functions,which return void in some glib versions. automatically include critical fixes in later versions of thelibrary, but decreases its reliability because the later versionsmay also introduce
CFailures . There is a tradeoff betweenflexibility and reliability in these two approaches. Developersstruggle to find the sweet spot [21].Most
DMSs leave this choice to application developers, whocan manually limit the version range of each required library.Taking dnf as an example, dnf is the
DMS used in RPM-based Linux distributions like Fedora. dnf requires applicationdevelopers to specify the required libraries and version ranges(e.g., ocaml>=3.08 ), which may be outdated: 1) The versionranges may be too large as libraries evolve. For example,developers specify libfoo>=1.0 at first, after which libfoo-2.0 is released and backward incompatible with libfoo-1.0 . In thiscase, the version range should be updated to .2) The version ranges may be too small as libraries evolve.For example, developers specify libfoo<=1.0 at first, afterwhich libfoo-2.0 is released and backward compatible with libfoo-1.0 . In this case, the version range should be updatedto libfoo<=2.0 .To avoid these limitations, another solution is to maintain a symbols file by library developers. This solution is applied in apt , the
DMS in Debian-based Linux distributions like Ubuntu.According to Debian policy [22]: 1) "ABI (Application BinaryInterface) changes that are not backward-compatible requirechanging the soname [23] of the library"; 2) "A sharedlibrary must be placed in a different package whenever its soname changes". It means that two library versions shouldbe placed in two library packages, when the versions arebackward incompatible. These two packages, to some degree,can be regarded as two different libraries, e.g., libssl1.0.0 and libssl1.1 . Library developers are required to maintaina symbols file [22], in which each line contains a symbolprovided by the library, as well as the minimal version that thesymbol is introduced. Then, the version range of this librarycan be inferred automatically by extracting symbols used byan application. The minimal version of the version range is themaximum value of introducing versions of all used symbols.The maximum version is not necessary since all versionsare backward compatible in one package. Finally, the versionrange is used by apt to help users manage dependencies.The above solution, however, is still limited since: 1) Thereis no mechanism to guarantee that library developers comply ver-1.0ver-1.1ver-2.0 Incomp.library changes Version rangesSource codeBinary files DepBug ver-1.0ver-1.1ver-2.0 Incomp. library versions
Collect incompatible changes Detect dependency bugs Suggest incompatible versions
ApplicationLibrary Library
Fig. 3: Overview of
DepOwl . DepOwl contains three major steps:collect incompatible changes, detect dependency bugs, and suggestincompatible versions. with the policy. Library developers may unintentionally intro-duce ABI incompatibilities between two versions, which havethe same soname . Existing studies [6], [24] show 26%-33% oflibrary versions violate semantic versioning, meaning librariesfrequently introduce incompatibilities during minor versionchanges. 2) This solution only works for binary packages,since apt needs to analyze binary files to extract symbols usedby the application. Application developers have to manuallyspecify version ranges for source packages, which do nothave binary files. In this case, apt will suffer from the samelimitations as dnf . 3) Library developers need to manuallyupdate the symbols file when introducing forward incompatiblechanges. For example, when a struct type adds a field in a newlibrary version, the introducing version of all symbols usingthe struct must be increased to the version at which the new field was introduced. Otherwise, a binary built against the newversion of the library may be installed with a library versionthat does not support the new field . This is a common changeduring library evolutions, failing to update the introducingversion of any symbol will lead to
DepBugs . We will show areal-world example in Section III.In summary, the
DMSs supporting version ranges may intro-duce
DepBugs — the ranges contain incompatible versions. Inthis paper, we focus on detecting and fixing
DepBugs in therange-based
DMSs , so that applications can achieve higherreliability without affecting flexibility.III. M
OTIVATION AND O VERVIEW OF
DepOwl
In this section, we show a
DepBug example which motivatesus to design
DepOwl . Based on the example, we introduce how
DepOwl works at a high level.
Motivating example.
From glib-2.39.1 to glib-2.39.2 , thereturn types of some functions (e.g., g_hash_table_replace , g_hash_table_insert ) changed from void to gboolean . Thesechanges are: 1) backward compatible — a binary compliedagainst the old version will ignore the return value of the newversion, and there is no error; 2) forward incompatible — abinary complied against the new version may use the returnvalue, where the old version returns void.These changes may cause DepBugs in many applications(e.g., cockpit-202.1 , homebank-5.2.2 ), where the return valuesof the changed functions are used. Figure 2 shows code3ABLE I: Examples of DepOwl results. (a) Collecting incompatible changes in libraries.
Library Change Versions Change Contentglib <2.39.1, 2.39.2> g_hash_table_replace adds return valuesglib <2.39.1, 2.39.2> g_hash_table_insert adds return values (b) Detecting
DepBugs and suggesting incompatible library versions.
Application Library
DepBug
Incompatible Versionscockpit-202.1 glib>=2.37.6 2.39.1 2.37.6<=glib<=2.39.1homebank-5.2.2 glib>=2.37.3 2.39.1 2.37.3<=glib<=2.39.1 snippets of two applications. The usage of return valuesindicates any glib version returning void will be incompatibleto the applications. However, in Ubuntu-19.10, cockpit-202.1 depends on glib>=2.37.6 , and homebank-5.2.2 depends on glib>=2.37.3 . Both the version ranges contain the incompat-ible version glib-2.39.1 . Therefore, we say cockpit-202.1 and homebank-5.2.2 contain
DepBugs since their version rangescontain incompatible versions.The root cause of the
DepBugs is that library developers donot update the introducing versions of the changed functionsin the symbols file of the library.
The
DepOwl approach.
DepOwl can detect
DepBugs inthe above example, and prevent
CFailures caused by the bugs.Figure 3 shows the overview of
DepOwl , which contains threemajor steps. First, the root causes of
CFailures are incom-patible changes in libraries.
DepOwl collects incompatiblechanges from any two successive library versions, includingboth
BICs and
FICs . For example, the above example containstwo incompatible changes as shown in Table Ia.Second, one incompatible change may or may not result in
CFailures . DepOwl analyzes usages of the changed element(e.g., g_hash_table_replace ) in each application, and detectswhether the old or new library version of the change is incom-patible to the application. If yes,
DepOwl reports a
DepBug when the incompatible version is included in the requiredversion range of the application. For the above example, thethird column of Table Ib shows the incompatible versions thatcause
DepBugs .Third, one incompatible change may cause multiple incom-patible versions.
DepOwl suggests all incompatible versionscaused by each incompatible change. Users can prevent
CFail-ures by avoiding using the incompatible versions. In this step,any version that is both backward and forward compatibleto the version reported by the second step (e.g., glib-2.39.1 for cockpit-202.1 ) will also be regarded as an incompatibleversion. In our example, the changed functions return voidin glib-2.39.1 and previous versions. Thus, the incompatibleversion range is glib<=2.39.1 . Then,
DepOwl calculates theintersection between the incompatible version range and therequired version range. For example, the intersection for cockpit-202.1 is .There are three challenges in the design of DepOwl : • DepOwl collects library changes that break either back-ward or forward compatibility, whereas existing toolsmainly focus on detecting backward incompatibilities. To int foo(); int foo(); int foo(); int main(){ foo();} mylib.hv1.0mylib.hv2.0mylib.hv3.0 myapp.c(1)(1) (2)(2)(2) mylib.sov1.0mylib.sov2.0mylib.sov3.0myapp (4)(4) (3)(3)(3)
Source-code compatibility Binary compatibility
This paper
Fig. 4: Difference between
DepOwl and existing tools.
Thisfigure includes source-code level (1, 2) and binary level (3, 4)compatibility between libraries and applications (2, 3), or crossdifferent library versions (1, 4). Existing tools focus on (1, 2, 4),while DepOwl addresses (3). achieve this, we propose a heuristic rule to help
DepOwl detect changes breaking forward compatibilities. • DepOwl detects if incompatible changes will cause
Dep-Bugs . This is challenging because the changes can involvedifferent types (e.g., add a function, remove a parameter).To address this, we categorize the changes and derive aset of rules to detect
DepBugs for each type. • DepOwl suggests all incompatible versions caused byeach incompatible change. This is non-trivial becausemultiple changes may affect the same element. In this re-gard,
DepOwl performs a global check across all versionsto suggest incompatible ones for a changed element.IV.
DepOwl A PPROACH
There have been some existing techniques (e.g. compilers)on analyzing API usages in applications to check if theapplication is compatible with a given library version. Theywork at the source-code level. However, end users oftenprefer to install binary files directly, instead of downloadingsource-code files and compiling the applications themselves.Therefore, the users often care more about the binary levelcompatibility. There has also been some work (e.g. ABITracker [25]) on detecting incompatibilities cross differentlibrary versions at both source-code and binary levels. Thiswork does not analyze the API usages in applications. Asshown in Figure 4, in this paper, we focus on detectingbinary level compatibility between libraries and applications.The compatibility at the source-code level cannot guaranteethe compatibility at the binary level, such as modificationof virtual tables of classes, change of type sizes of functionparameters, change of values of enumeration elements, changeof orders of struct fields, change of compilation directives, andso on.Figure 5 shows two real-world examples that applicationsand libraries are compatible at the source-code level, butincompatible at the binary level. In the first example, three4 //openssl-1.0.1s/ssl/ssl.h
Fig. 5: Examples of source-code compatible but binary incom-patible dependency between libraries and applications.APIs in the library openssl depend on the compilation direc-tive OPENSSL_NO_SSL2. In openssl-1.0.1s , the directive isenabled; thus, the APIs are not available in library binaries.While in other versions, the directive is disabled by default.In this case, the source code of openssl-1.0.1s is the same asthe source code of other versions, but applications using theAPIs only fail when linking to openssl-1.0.1s . In the secondexample, the application ruby-2.5.5 depends on the library zlib , which defines z_crc_t as unsigned int after zlib-1.2.7 .When compiling ruby against zlib-1.2.6 , the compilation direc-tive HAVE_TYPE_Z_CRC_T is not defined; thus, z_crc_t is unsigned long . When compiling ruby-2.5.5 against zlib-1.2.7 ,the compilation directive is defined; thus, z_crc_t is unsignedint . The application ruby-2.5.5 is source-code compatible withboth zlib-1.2.6 and zlib-1.2.7 . However, when the applicationis compiled against one version, it will be incompatible toanother version at runtime.Algorithm 1 shows how DepOwl suggests incompatibleversions for each pair of library and application < lib , app > ina software repository (line 1). DepOwl first collects the set ofincompatible changes IC from lib (line 2). Table Ia illustratestwo examples of incompatible changes. Each incompatiblechange ic is a three-tuple:
The first component of
DepOwl takes the library lib asinput, and collects its incompatible changes IC . As shownin Figure 1, both BICs and
FICs may result in
CFailures . DepOwl needs to collect both kinds of library changes. Thereare existing tools of detecting compatibility problems in li-braries, e.g.,
ABI-Tracker [25], a tool for checking backwardcompatibility of a C/C++ library. However, the existing toolsmainly focus on backward compatibility problems.
DepOwl transfers the forward problems into backward problems.
Algorithm 1
Pseudo-code of the
DepOwl
Approach.
Require:
Library set
Lib , application set
App
Ensure:
Incompatible version sets V
FICs from v old to v new . DepOwl applies a heuristic rule:forward incompatibility from v old to v new is equivalent tobackward incompatibility from v new to v old , formalized as: F IC ( v old , v new ) = BIC ( v new , v old ) . (2) According to Equation 1 and Equation 2, we can get: IC ( v old , v new ) = BIC ( v old , v new ) ∪ BIC ( v new , v old ) . (3) Then,
DepOwl collects both
BIC ( v old , v new ) and BIC ( v new , v old ) by using the ABI-Tracker tool. For alibrary with N versions, DepOwl calculates all incompatiblechanges IC of lib : IC = ∪ i =1 i = N − IC ( v i , v i +1 ) . (4) During collecting library changes,
DepOwl also considerthe following factors: 1) Library soname [23].
DepOwl willskip the library changes between v old and v new , if v old and v new have different sonames . Library versions with different sonames will be packaged into different packages; thus willnot lead to DepBugs . 2) Symbol versioning [26]. Symbolversioning supports multiple symbol versions in one libraryversion. For example, in glibc-2.27 , the symbol glob hastwo versions: glob@@GLIBC_2.27 and glob@GLIBC_2.2.5 (‘ @@ ’ means the default version). DepOwl regards symbolswith different versions as different symbols.For each library version,
DepOwl requires its binaries com-piled with debug symbols. When the input is not available,
DepOwl takes source code as input, and compiles the librarywith debug symbols itself (we provide compiling scripts toachieve this).
DepOwl uses default compilation directivesduring the compiling process, and accepts custom directivesprovided by users at the same time.
B. Detecting Dependency Bugs
The second component of
DepOwl is to analyze usages ofthe changed element of each ic in app , and detect whether v old or v new is incompatible to app . If yes, DepOwl reports a
DepBug when the incompatible version (i.e., v old or v new ) is5ncluded in the version range required by app . When app doesnot specify any version range, DepOwl assumes it accepts allversions. As a common usage scenario of
DepOwl is to detect
DepBugs in a software repository. In this case,
DepOwl takesthe repository as input, and for each application package inthe repository,
DepOwl detects whether the change can leadto a
DepBug . It is time consuming to analyze all applicationpackages since a software repository may contain tens ofthousands of application packages. In this regard,
DepOwl splits the detecting process into two phases: filtering phaseand detecting phase.
Filtering phase . DepOwl first filters out the applicationpackage that does not accept the library versions where ic happened. For example, app requires libfoo>=3.0 , while the ic happened from libfoo-1.0 to libfoo-2.0 . To achieve this, DepOwl analyzes the dependencies of app (e.g. from control file in Ubuntu or .spec file in Fedora), and extracts the librariesrequired by app , as well as corresponding required versionranges.
DepOwl checks if the library (where ic happens) isincluded in the required libraries, and if v old and v new of ic are included in the corresponding version range. When eitherof the above two conditions is not satisfied, it means ic cannever affect app . In this case, DepOwl reports no
DepBugs and stops analyzing.Then,
DepOwl filters out the application package that doesnot use the changed element in ic . For example, the libraryadds a parameter for a symbol, which is not used in app .In general, ic can be classified into two types according tothe changed element: change a symbol (e.g., from " foo() "to " foo(node a) ") and change a data type (e.g., from " structnode {int i;} " to " struct node {float f;} "). DepOwl analyzesthe binary files contained in app . When ic changes a symbol, DepOwl checks if any binary file requires the symbol by usingthe readelf [27] tool. When ic changes a data type, DepOwl collects all symbols that use the data type in the library, andchecks if any binary file requires any symbol. If yes, it means ic can potentially lead to CFailures , and
DepOwl starts thenext phase. Otherwise,
DepOwl stops analyzing, and reportsno
DepBugs . Detecting phase . DepOwl analyzes the usage of thechanged element and determines whether v old or v new isincompatible to app . If the change is a BIC ( FIC ) and theusage matches v old ( v new ), then v new ( v old ) will be regarded asthe incompatible version. DepOwl takes the application binaryfile with debug symbols as input. When ic changes a symbol, DepOwl extracts the symbol signature from the binary file.When ic changes a data type, DepOwl extracts the data-typedefinition from the binary file. After that,
DepOwl compares ifthe signature or definition is the same as that of v old or v new .If the above input is not available, DepOwl can also extractsthe usage from source code. For example, when working ona software repository, many applications are released withoutdebug symbols. In this case,
DepOwl automatically downloadsthe source code of each application package.When using the application source code, it is hard to extractsymbol signatures or data-type definitions, since the header files are not available.
DepOwl has to apply different rulesto determine the incompatible version. For example, when ic adds a field in a struct , DepOwl needs to check if the additionalfield is used in the source code. When ic changes the type ofa return value from void to non-void , DepOwl needs to checkif the return value is used in the source code.In this regard, we enumerate all types of incompatiblechanges in C/C++ libraries and define determination rulesfor each type. The classification and rules are shown inTable II. We classify library changes into 18 types relatedto enum (1-3), struct (4-7), variable (8-10), and function (11-18). The struct and enum types are data-type changes,while the variable and function types are symbol changes.For data-type changes (1-7),
DepOwl needs to confirm thatthe application uses the changed element in source code, e.g.,member for enum or field for struct . For symbol changes (8-18),
DepOwl has already confirmed that the application usesthe changed symbol in the filtering phase. For changes relatedto "add" or "remove" (1-2, 4-5, 8-9, 11-14, 16-17), once theapplication uses the changed element,
DepOwl determinesthe incompatible version is v old or v new , respectively. Forchanges related to "change type" (6, 10, 15, 18), DepOwl analyzes the usages of changed element, and infers the type insource code. For example, from zlib-1.2.6.1 to zlib-1.2.7 , thereturn type of the function get_crc_table changed from long to int . In the source code of package unalz-0.65 , DepOwl finds"long *CRC_TABLE = get_crc_table();", i.e., the return typematches version 1.2.6.1. Thus,
DepOwl determines 1.2.7 is theincompatible version. As for change type 3 and 7, it is hard toinfer the member value or field order from source code. Thus,
DepOwl cannot determine the incompatible version.We tried to build a complete table with our best effort.We referenced online resources during the enumeration pro-cess [28]–[30]. For example, changing an inherited class inC++ will generate two totally different symbols in binaries dueto name mangling. In this case,
DepOwl will report functionadd and function remove . Also,
DepOwl is designed to beflexible to incorporate new rules.
DepOwl uses srcML [31], a source-code analysis infrastruc-ture, to achieve the above analyzing. The source code cannotbe compiled since the lack of header files, while srcML pro-vides lexical analysis and syntax analysis for non-compilablesource code.
DepOwl returns a two-tuple: < v old , v new > in thisstep. If the old (new) version in ic is incompatible to app andincluded in the version range required by app , v old ( v new )returns the old (new) version number, otherwise v old ( v new )returns -1. C. Suggesting Incompatible Versions
We refer to the incompatible version reported in the abovestep (i.e., v old or v new ) as v bug . A library change may leadto multiple incompatible versions beyond v bug . In this compo-nent, DepOwl detects all library versions that are incompatibleto app caused by ic . To achieve this, DepOwl cannot simplyassume the versions less than or greater than v bug as incom-patible versions, since the changed element in ic may change6ABLE II: Rules for determining DepBugs . ID Types of Incompatible Changes
DepOwl
Rules Incomp.Version1 Enum adds member Use the member v old v new † Use the field v old v new v o. / v n. v old v new
10 Global variable changes type Match the var type v o. / v n.
11 Function adds - v old
12 Function removes - v new
13 Function adds para Use the para v old
14 Function removes para Use the para v new
15 Function changes para type Match the para type v o. / v n.
16 Function adds return value Use the function ret v old
17 Function removes return value Use the function ret v new
18 Function changes return type Match the ret type v o. / v n. † The struct related rules (4-7) also apply for union or class . again in another ic . For example, in zlib , developers removethe function gzgetc (change gzgetc to a macro for speed) from zlib-1.2.5.1 to zlib-1.2.5.2 . After that, the developers restore gzgetc for compatibility from zlib-1.2.5.2 to zlib-1.2.5.3 [32].In this regard, DepOwl checks compatibilities of the changedelement of ic across all versions of lib , and any version thatis both backward and forward compatible to v bug will beregarded as an incompatible version.We refer to the changed element in ic as ele . Supposethere are N library versions. For ∀ i ∈ [1 , N ] , DepOwl calculates isIV ( v i ) , a Boolean value indicating whether v i is an incompatible version: isIV ( v i ) = ¬ bbc ( v bug , v i , ele ) ∧ ¬ bfc ( v bug , v i , ele ) , (5) where bbc ( v bug , v i , ele ) and bf c ( v bug , v i , ele ) return Booleanvalues, meaning if ele breaks backward compatibility or breaksforward compatibility from v bug to v i , respectively. If yes,return 1, otherwise return 0. Similar to Section IV-A, we have: bfc ( v bug , v i , ele ) = bbc ( v i , v bug , ele ) . (6) Therefore,
DepOwl transforms the above two equations to: isIV ( v i ) = ¬ bbc ( v bug , v i , ele ) ∧ ¬ bbc ( v i , v bug , ele ) . (7) Then,
DepOwl outputs a list of Boolean values
ISIV , eachof them indicates whether a version is incompatible (i.e., 1)or not (i.e., 0):
ISIV = [ isIV ( v ) , isIV ( v ) , ..., isIV ( v N )] . (8) For each element (e.g. isIV ( v i ) ) in ISIV , if isIV ( v i ) equals to 1, and v i belongs to the version range required by app , DepOwl regards v i as an incompatible version. Takingthe application cockpit-202.1 as an example, the requiredversion range is glib>=2.37.6 ; while for ∀ j ∈ ( glib<=2.39.1 ), isIV ( v j ) equals to 1. DepOwl suggests the incompatibleversions are . For an application that is not managed in a software repository,
DepOwl assumes thatit accepts all library versions since there is no version ranges.For the given app and lib , DepOwl reports a set of incom-patible versions for each ic : IV
To evaluate
DepOwl , we consider three research questions:
RQ1:
How effective is
DepOwl at preventing known
CFail-ures ? This question examines the recall of DepOwl by calcu-lating the percentage of
CFailures that can be prevented by
DepOwl among all known
CFailures . RQ2:
How effective is
DepOwl at preventing unknown
CFail-ures ? This question evaluates the precision of DepOwl bycalculating the percentage of correct results among all resultsreported by
DepOwl . RQ3:
How does
DepOwl compare with existing methods?This question compares
DepOwl with two widely used
DMSs (i.e., apt and dnf ), as well as the dependencies declared in thebuild systems (e.g., autoconf or cmake ) by developers . A. Datasets and Experiment Designs
For each research question, we introduce the preparation ofdatasets, and the measurements used during the evaluation.
RQ1: Preventing known
CFailures . We collected known
CFailures from StackOverflow by using keyword search.However, simple keywords (e.g., library, dependency, version,etc) may result in tens of thousands of issues, and introducemassive manual efforts in the following analysis. Instead, weused the error messages when users came across compatibilityproblems as keywords. For example, when a library removesa symbol, the application will echo "symbol lookup error" atruntime. When a library symbol adds or removes a parameter,the complier will complain "too few/many parameter to func-tion" at compiling time. In total, we collected 529 issues byusing error-message searching.We then manually analyzed root causes of these issues andfound 69 issues involve incompatible changes in libraries.These changes lead to
CFailures through misuses of libraryversions. While others are mainly caused by dependencyproblems but not related to compatibility. Among the 69issues, 38 of them involve C/C++ programs. Since the currentversion of
DepOwl handles C/C++ programs, we used the38 issues to answer RQ1. The applications of 23 issues arecode snippets provided by the original posters, while otherissues involved 12 mature projects including servers (e.g.,Httpd, MongoDB) and clients (e.g., Eclipse, Qt) from differentdomains. The data and source code in this paper are publicly available inhttps://github.com/ZhouyangJia/DepOwl.
DepBugs in the software repository shipped with Ubuntu-19.10 † . Application and Library Information Results of
DepOwl
Application Package Library Package Change Versions Change Symbol/Data-type Incompatible Versionsqgis-providers_3.4.10 libsqlite3-0>=3.5.9 <3.7.6.3, 3.7.7> struct sqlite3_module adds xSavepoint [3.5.9, 3.7.6.3]unalz_0.65-7 zlib1g>=1.1.4 <1.2.6.1, 1.2.7> get_crc_table changes return value from long to int [1.2.7, V last ]elisa_1.1 libkf5i18n5>= 5.15.0 <5.16.0, 5.17.0> Add KLocalizedContext(QObject*) [5.16.0]gammaray_2.9.0 libqt5core5a>=5.12.2 <5.13.2, 5.14.0> qt_register_signal_spy_callbacks() changes para type [5.14.0, V last ]geeqie_1:1.5.1-1 libglib2.0-0>=2.51.0 <2.51.0, 2.52.0> g_utf8_make_valid() adds parameter gssize [ V init , 2.51.0]alsa-utils_1.1.9 libasound2>=1.1.1 <1.1.9, 1.2.1> Remove snd_tplg_new@ALSA_0.9 [1.2.1, V last ]rkward_0.7.0b-1.1 libkf5coreaddons5>=5.19.0 <5.19.0, 5.20.0> Add KCoreAddons::versionString() [5.19.0] † We illustrate one bug for each library package. The complete
DepBug list is available in our supplementary materials.
Since the 38 issues were selected by searching error mes-sages, they may not cover certain types of compatibilitybreaking changes (Table II) that do not produce observablesymptoms. For example, in Table II, “changing member valuesin a enum type (ID 3)" and “changing field orders in a structtype (ID 7)" may result in errors in a program, but willnot generate error messages. Therefore, the 38 issues cannotcover the changes of ID 3 and ID 7. It is hard to collectincompatibilities that have no observable failures, since userscannot be sure if they are actual bugs, thus may not reportissues.We measured the effectiveness of preventing known
CFail-ures in terms of whether
DepOwl can prevent the
CFailures in the 38 C/C++ related issues. To achieve this,
DepOwl needs to detect
DepBugs in these issues.
DepBugs happenwhen the version ranges required by applications containincompatible versions. Fixing the
DepBugs helps users avoidusing incompatible versions and prevent
CFailures . When anapplication does not specify a version range,
DepOwl assumesthat the application accepts all library versions.
RQ2: Preventing unknown
CFailures . We used the soft-ware repository shipped with Ubuntu-19.10 (the latest sta-ble version at the time of writing) to evaluate
DepOwl ,since Ubuntu uses apt , which can resolve dependencies au-tomatically, while other
DMSs mainly depend on applicationdevelopers to manually input dependencies. The repositoryincludes 61,068 packages; each package can be either anapplication package or a library package. There are 32,069library packages, which are depended by at least one otherpackage. For each library package, we count the number ofapplication packages that depend on it. We choose the top1 (cid:104) (i.e., 32) library packages, which are from 26 differentlibraries (one library may generate multiple packages, e.g.,the qt library generates libqt5core5a , libqt5gui5 etc.). For eachchosen library, we collect its versions released during aboutlast ten years, and get 841 versions in total (i.e., 32.2 versionsfor each library on average).It is hard to directly measure the effectiveness of preventingunknown CFailures , since the unknown
CFailures do nothappen as yet. Instead, we measure the effectiveness in termsof whether
DepOwl can detect unknown
DepBugs in thesoftware repository, and prevent potential
CFailures causedby the
DepBugs . In specific, for each application packagefrom the software repository,
DepOwl detects whether there are
DepBugs with regard to the chosen library packages,i.e., the version ranges required by the application packagecontain incompatible versions. If yes,
DepOwl suggests theincompatible versions that may cause
CFailures . RQ3: Comparing with existing methods.
We used thesame dataset in RQ1 to compare
DepOwl with existingmethods, and calculated the percentage of issues that can beprevented if the original posters use existing methods.We first compared
DepOwl with two
DMSs used in industry:1) dnf , used in RPM-based Linux distributions, where appli-cation developers manually specify version ranges of requiredlibraries; 2) apt , used in DEB-based Linux distributions,where library developers maintain a symbols file. We thencompared
DepOwl with building scripts (e.g., configure.ac orCMakeList.txt) shipped with application source code, sincedevelopers often declare version ranges in the scripts.
B. Results and Analysis
RQ1: Preventing known
CFailures . Two authors manuallyevaluated whether
DepOwl can prevent the 38 known
CFail-ures by analyzing if the incompatible versions suggested by
DepOwl contain the incompatible version used by the originalposter. The result shows
DepOwl successfully suggests incom-patible versions for 35 of the 38 C/C++ related issues. Thecomplete list of these issues is available in our supplementarymaterials. Each issue in the list contains the issue ID, theapplication name, the library name, and the incompatibleversions suggested by
DepOwl . Taking issue 27561492 asan example, library libpcre adds function pcrecpp::RE::Init from libpcre-5.0 to libpcre-6.0 , and changes its parameter typefrom libpcre-6.7 to libpcre-7.0 . Therefore, DepOwl reports twolibrary changes. Meanwhile, the application mongodb-2.4 uses pcrecpp::RE::Init , and the parameter type is the same as thetype from libpcre-6.0 to libpcre-6.7 . Thus, DepOwl reports[ V init , 5.0] ∪ [7.0, V last ] as the incompatible versions.On the other hand, DepOwl reported three false negatives.Two cases were caused by compilation directives, e.g., theoriginal poster executed and compiled an application on dif-ferent OS, where the libraries may be compiled with differentdirectives.
DepOwl cannot infer such directives, and thus gen-erates false negatives. The last case missed version informationand might have used a very old library version.
DepOwl can V init and V last stand for the first and the last library version that havethe same soname . CFailures in 35 out of the 38 issues. This resultindicates
DepOwl can effectively prevent real-world
CFailures in terms of recall.
RQ2: Preventing unknown
CFailures . DepOwl collected27,413 incompatible changes from the 841 versions of the26 libraries. For each change,
DepOwl detects if the changecan cause a
DepBug for each application package.
DepOwl detected 77
DepBugs , of which 49 are caused by backwardincompatible changes and 28 are caused by forward incompat-ible changes. These
DepBugs involve 69 application packagesand 7 library packages. Table III illustrates one bug for eachlibrary package. The complete
DepBug list is available inour supplementary materials. For example, in the first bug,the application qgis-providers_3.4.10 depends on the library libsqlite3-0>=3.5.9 , which adds the filed xSavepoint in structsqlite3_module from 3.7.6.3 to 3.7.7. The application used thenew filed; thus 3.7.6.3 is an incompatible version. DepOwl then suggests all incompatible versions: [3.5.9, 3.7.6.3].We searched evidence from new library versions, newapplication versions, or software repositories to evaluate if the77
DepBugs have been handled in different ways. If not, wefurther reported them to the repository maintainers. Amongthe 77
DepBugs , library developers undo the library changesof 37 cases in later library version. It means applications mayhave
CFailures when using the library versions before undoingthe changes. Application developers update the application toadapt the changes in 3 cases, meaning the old applicationversion may have
CFailures . Besides, 24
DepBugs are fixedin the latest version of Ubuntu or Debian. Although thesebugs have been handled in different ways, they had been inthe system for a long period of time, posing threats to thesystem reliability. For example, library developers fixed anincompatible version, which had already been released andaffected applications.
DepOwl is able to prevent these impactsfrom the very beginning.For the other 13 cases, we report them to the Ubuntucommunity, 4 of them have been confirmed by developers,and 8 are pending for response. So far, we only found onepotential false-positive case.
DepOwl reported that the library kcoreaddons-5.19 is incompatible to the application rkward ,which depends on kcoreaddons>=5.19 . The developer agreedthat the incompatibility may exist, but kcoreaddons-5.19 is notactually used in any Ubuntu release (Xenial uses kcoreaddons-5.18, Bionic uses kcoreaddons-5.40), thus has zero impact.This result indicates
DepOwl can effectively detect real-world
DepBugs in terms of precision.This experiment took about 30 hours in a virtual machinewith a dual-core CPU and 4G memory. The filtering anddetection phases took about five hours (excluding downloadingpackages). The majority of time was spent on collecting librarychanges of history versions. This process is one-time effort,since the latest library version can be analyzed incrementally.The execution time of each library depends on its scale andtype. When analyzing large C++ libraries like Qt,
DepOwl mayneed dozens of minutes for each pair of versions. Meanwhile,some other libraries only need several seconds.
BuildRequires: libsoup-devel >= 2.33.6
BuildRequires: libicu-devel libsoup2.4-1 (>= 2.29.90), libsqlite3-0 (>= 3.7.3),
LIBSOUP_REQUIRED_VERSION=2.33.6
CAIRO_REQUIRED_VERSION=1.6
Fig. 6: Version ranges of different baselines.
RQ3: Comparing with existing methods.
We compared
DepOwl with three existing methods, i.e., dnf for .rpm pack-ages, apt for .deb packages, and the building system. Foreach StackOverflow issue used in RQ1, two authors manuallyevaluated if the
CFailure can be prevented by using existingmethods when the original poster used the existing methods atfirst. Taking issue 30594269 as an example, webkit has "sym-bol lookup error" when linking to libsoup . The incompatibleversion range of libsoup is [ V init , 2.29.6]. The version rangesof libsoup in three baselines accepted by webkit are [2.33.6, V last ], [2.29.90, V last ], [2.33.6, V last ], respectively. Thus, allthe three baselines can prevent the failure in this issue. Figure 6lists the files where we get these version ranges, including the webkitgtk.spec file in the .rpm package, the control file in the .deb package, and the configure.ac file in the building systemof source code.Figure 7 shows the results regarding the comparison among DepOwl and the three baselines.
DepOwl can prevent
CFail-ures in 35 issues whereas the baselines can prevent
CFailures in 3, 7, 5 issues, respectively. Besides,
DepOwl does not reportany problems in 3 issues (i.e., 3 false negatives), while thebaselines do not report any problems in 27, 27, 26 issues.This is because 23 issues were caused by code snippetsprovided by the original posters. These code snippets are notmanaged in any
DMSs or build systems. Last but not theleast, the baselines report
DepBugs in 8, 4, 7 issues (i.e.,the version range contains incompatible versions).
DepOwl successfully prevents 35
CFailures , whereas the best baselineprevents 7
CFailures . The detailed results are available in oursupplementary materials. This result indicates
DepOwl is moreaccurate than the three baselines. In the mean time,
DepOwl requires no human efforts, while the baselines require manualinputs from either library developers or application developers.VI. D
ISCUSSION AND F UTURE W ORKS
In this section, we discuss limitations in the design of
DepOwl , as well as future works with regard to the limitations.
Debug symbols of libraries.
To collect incompatiblechanges (in Section IV-A),
DepOwl requires all versions ofthe library as inputs. Each version should be in the sourcecode form or the binary form with debug symbols. Forthe binary form, most libraries are released without debugsymbols, and do not meet the requirement of
DepOwl . As9
Fig. 7: The comparison among
DepOwl and baselines.for the source code form, we need to compile the sourcecode so that
DepOwl can collect Application Binary Interface(ABI) changes.
DepOwl provides scripts to automate thecompiling process. This is still limited since
DepOwl usesthe default compilation directives; thus cannot collect ABIchanges triggered by other directives. As a result, developershave to provide the compilation directives, or
DepOwl maycause false negatives.•
Future work:
The most convenient way to avoid this lim-itation is to suggest library developers to release binaries withdebug symbols when releasing new versions. This practiceactually has been applied in some libraries. For example, in thesoftware repository of Ubuntu-19.10, there are 753 packageswith the suffix ‘-dbg’ containing debug symbols.
Code analysis in applications.
When detecting dependencybugs (in Section IV-B),
DepOwl requires application binariescompiled with debug symbols. This input is not available inmost applications managed in existing
DMSs . Alternatively,
DepOwl has to use source code as input, but correct usages insource code do not indicate the application is free of
CFailures in the binary form. For example, the second example ofFigure 5 shows the usage of get_crc_table in ruby-2.5.5 , whichworks well against both zlib-1.2.6 and zlib-1.2.7 in sourcecode level: when ruby-2.5.5 is compiled against zlib-1.2.7 , thereturn type z_crc_t is int ; when ruby-2.5.5 is compiled against zlib-1.2.6 , the return type z_crc_t is long . However, ruby-2.5.5 may have CFailures when compiled against one version andlinked to another version at runtime. This limitation will leadto false negatives.•
Future work: DepOwl will provide an interface for applica-tion developers to indicate a fixed version for each library. Thismanual effort is the same to most
DMSs like pip or Maven .Thus,
DepOwl can compile the source code against the fixedlibrary version.
Limitations when using ABI-Tracker.
DepOwl uses ABI-Tracker to collect incompatible changes of a target library.ABI-Tracker takes source code of the library history versionsas inputs and compiles each version with default directives.This process may introduce both false positives and falsenegatives. For example, in the first example of Figure 5, ABI-Tracker reports that openssl-1.0.1s removes three symbols.However, users will not encounter failures when disablingOPENSSL_NO_SSL2. In this case,
DepOwl may report false positives, although no false positives directly related to ABI-Tracker are generated in our experiment. On the other hand,when incompatible changes can only be triggered by specificdirectives, ABI-Tracker may generate false negatives and thuscause
DepOwl to report false negatives. For example, two outof three false negatives in RQ1 are caused by compilationdirectives not correctly identified by ABI-Tracker.
Impacts of compilation directives.
The compilation direc-tives of a target library may affect the symbols and data typesprovided by the library, and further affect the results of
De-pOwl . Since ABI-Tracker uses default compilation directivesto compile each library version, it may cause
DepOwl to reportfalse negatives (as discussed in the above paragraph). We havemitigated this impact by directly analyzing the binaries ofthe target libraries without the need of providing compilationdirectives. In the case where binaries are not available,
De-pOwl accepts the directives from users for compiling. In ourevaluation, we manually input the directives in most cases. Forthe two cases that we cannot obtain the directives in RQ1,
DepOwl reports two false negatives, since the directives arehard to be inferred automatically.VII. R
ELATED W ORKS
We briefly classify the existing works into three types:
Library changes.
Many works are targeted at librarychanges. Bagherzadeh et al. [33] studied the size, type andbug fixes in 8,770 changes that were made to Linux systemcalls. Brito et al. [34] identified 59 breaking changes and askedthe developers to explain the reasons behind their decision tochange the APIs. Dig et al. [35], [36] discovered that over 80%of changes that break existing applications are refactorings.Li et al. [37] investigated the Android framework source code,and found inaccessible APIs are common and neither forwardnor backward compatible. Li et al. [38] and Wang et al. [39]studied API deprecation in the Android ecosystem and Pythonlibraries. McDonnell et al. [40] found Android updates 115API per month, and 28% usages in client applications areoutdated with a median lagging of 16 months. Sawant etal. [41] investigated why API producers deprecate features,whether they remove deprecated features, and how they expectconsumers to react. Brito et al. [1] identified API breakingand non-breaking changes between two versions of a Javalibrary. Foo et al. [6] presented a static analysis to check ifa library upgrade introduces an API incompatibility. Meng etal. [4] aggregated the revision-level rules to obtain framework-evolution rules. Mezzetti et al. [5] proposed type regressiontesting to determine whether a library update affects its publicinterfaces. Ponomarenko et al. [2] presented a new methodfor automatic detection of backward compatibility problemsat the binary level. Wu et al. [3] proposed a hybrid approachto identify framework evolution rules.These works are targeted at detecting changes, refactoringsand rules during library evolutions. While
DepOwl is targetedat preventing failures caused by the results of these works.
Application failures.
Some works focus on
CFailures inapplications. Cai et al. [42] studied compatibility issues in102,894 Android app to understand the symptoms and causesof these issues. Cossette et al. [43] studied techniques to helpmigrate client code between library versions with incompatibleAPIs. Dietrich et al. [44] studied partially upgrading systems,and found some crucial verification steps are skipped in thisprocess. Jezek et al. [45] studied the compatibility of APIchanges, and the impact on programs using these libraries.Lamothe et al. [46] reported their experience migrating the useof Android APIs based on documentation and historical codechanges. Linares-Vásquez et al. [47] studied how the fault-and change-proneness of APIs relates to applications’ lackof success. Xavier et al. [48] conducted a large-scale studyon historical and impact analysis of API breaking changes.Balaban et al. [11] presented an approach to support clientrefactoring for class library migration. He et al. [7] and Xia etal. [49] studied API compatibility in Android. Henkel etal. [12] captured API refactoring actions, and users of theAPI can then replay the refactorings to bring their clientsoftware components up to date. Jezek et al. [10] proposed anapproach that analyses the byte-code of Java classes to findtype inconsistencies cross components. Li et al. [8] proposeda approach for modeling the lifecycle of the Android APIs,and analyzing app that can lead to potential compatibilityissues. Perkins et al. [13] proposed a technique to generateclient refactorings, by replacing calls to deprecated methods bytheir bodies. Wang et al. [9] proposed an automated approachthat generates tests and collects crashing stack traces forJava projects subject to risk of dependency conflicts. Xing etal. [14] recognized the API changes of the reused framework,and proposed plausible replacements to the obsolete API basedon working examples.These works focus on detecting incompatible API usagesand helping applications co-evolve with library evolutions, sothat the latest application version works well. While
DepOwl can prevent
CFailures for users’ in-use versions.
Application-library dependencies.
There are many worksaddress application-library dependencies. Bavota et al. [50]studied the evolution of dependencies between projects inthe Java subset of the Apache ecosystem. Bogart et al. [51]studied three software ecosystems to understand how devel-opers make decisions about change and change-related costs.Decan et al. [52] compared semantic-versioning complianceof four software packaging ecosystems, and studied how thiscompliance evolves over time. Decan et al. [53] analyzed thesimilarities and differences between the evolution of pack-age dependency networks. Derr et al. [20] studied libraryupdatability in 1,264,118 apps, and found 85.6% librariescould be upgraded by at least one version. Dietrich et al. [21]studied developers’ choices between fixed version and versionrange from 17 package managers. Jezek et al. [54] providedevidences that four types of problems caused by resolvingtransitive dependencies do occur in practice. Kikas et al. [55]analyzed the dependency network structure and evolution ofthe JavaScript, Ruby, and Rust ecosystems. Kula et al. [56]studied 4,600 GitHub projects and 2,700 library dependenciesto understand if developers update their library. Mirhosseini et al. [57] studied 7,470 GitHub projects to understand if auto-mated pull requests help to upgrade out-of-date dependencies.Pashchenko et al. [58] studied whether dependencies of 200OSS Java libraries are affected by vulnerabilities. Raemaek-ers et al. [24] investigated semantic versioning, and found onethird of all releases introduce at least one breaking change.Xian et al. [59] conducted an experience paper to evaluateexisting third-party library detection tools. Wang et al. [60]conducted an empirical study on dependency conflict issuesto study their manifestation and fixing patterns. Zerouali etal. [61] analyzed the package update practices and technicallag for the npm distributions.These works mainly assist people in understandingapplication-library dependencies. While
DepOwl is the firstresearch work to help users avoid incompatible application-library dependency automatically. Huang et al. [62] andWang et al. [63] designed tools to detect dependency conflictsfor Maven and PyPI ecosystems. These tools focused on thediamond dependency problem, which detects conflicts amongdifferent dependencies. They assume each dependency itselfis correct, whereas
DepOwl detects bugs within dependencies.VIII. C
ONCLUSION
In this paper, we find
CFailures are caused by using incom-patible library versions, which are hard to be prevented by theexisting research works or industrial
DMSs . To fill this gap,we design and implement
DepOwl , a practical tool to prevent
CFailures by avoiding incompatible versions.
DepOwl candetect unknown
DepBugs in the software repository shippedwith Ubuntu-19.10, and prevent
CFailures in real-world issuescollected from StackOverflow. However,
DepOwl still has lim-itations in practice. With limited helps from library developers(release binaries with debug symbols) and application devel-opers (provide one required library version),
DepOwl couldachieve higher accuracy. As a result, applications could beboth flexible for library evolutions and reliable for
CFailures .R EFERENCES[1] A. Brito, L. Xavier, A. Hora, and M. T. Valente, “Apidiff: Detectingapi breaking changes,” in , March 2018,pp. 507–511.[2] A. Ponomarenko and V. Rubanov, “Backward compatibility of softwareinterfaces: Steps towards automatic verification,”
Programming andComputer Software , vol. 38, no. 5, pp. 257–267, Sep 2012. [Online].Available: https://doi.org/10.1134/S0361768812050052[3] W. Wu, Y. Guéhéneuc, G. Antoniol, and M. Kim, “Aura: a hybridapproach to identify framework evolution,” in , vol. 1, May 2010,pp. 325–334.[4] S. Meng, X. Wang, L. Zhang, and H. Mei, “A history-based matchingapproach to identification of framework evolution,” in
Proceedings ofthe 34th International Conference on Software Engineering , ser. ICSE12. IEEE Press, 2012, pp. 353–363.[5] G. Mezzetti, A. Moller, and M. T. Torp, “Type regression testingto detect breaking changes in node.js libraries,” in , ser.Leibniz International Proceedings in Informatics (LIPIcs), T. Millstein,Ed., vol. 109. Dagstuhl, Germany: Schloss Dagstuhl–Leibniz-Zentrum fuer Informatik, 2018, pp. 7:1–7:24. [Online]. Available:http://drops.dagstuhl.de/opus/volltexte/2018/9212
6] D. Foo, H. Chua, J. Yeo, M. Y. Ang, and A. Sharma, “Efficient staticchecking of library updates,” in
Proceedings of the 2018 26th ACM JointMeeting on European Software Engineering Conference and Symposiumon the Foundations of Software Engineering , ser. ESEC/FSE 2018.New York, NY, USA: Association for Computing Machinery, 2018, pp.791–796. [Online]. Available: https://doi.org/10.1145/3236024.3275535[7] D. He, L. Li, L. Wang, H. Zheng, G. Li, and J. Xue, “Understandingand detecting evolution-induced compatibility issues in android apps,”in
Proceedings of the 33rd ACM/IEEE International Conference onAutomated Software Engineering , ser. ASE 2018. New York, NY,USA: Association for Computing Machinery, 2018, pp. 167–177.[Online]. Available: https://doi.org/10.1145/3238147.3238185[8] L. Li, T. F. Bissyandé, H. Wang, and J. Klein, “Cid: Automatingthe detection of api-related compatibility issues in android apps,” in
Proceedings of the 27th ACM SIGSOFT International Symposium onSoftware Testing and Analysis , ser. ISSTA 2018. New York, NY, USA:Association for Computing Machinery, 2018, pp. 153–163. [Online].Available: https://doi.org/10.1145/3213846.3213857[9] Y. Wang, M. Wen, R. Wu, Z. Liu, S. H. Tan, Z. Zhu, H. Yu, andS. Cheung, “Could i have a stack trace to examine the dependencyconflict issue?” in , May 2019, pp. 572–583.[10] K. Jezek, L. Holy, A. Slezacek, and P. Brada, “Software componentscompatibility verification based on static byte-code analysis,” in , Sep. 2013, pp. 145–152.[11] I. Balaban, F. Tip, and R. Fuhrer, “Refactoring support for classlibrary migration,” in
Proceedings of the 20th Annual ACM SIGPLANConference on Object-Oriented Programming, Systems, Languages, andApplications , ser. OOPSLA 05. New York, NY, USA: Associationfor Computing Machinery, 2005, pp. 265–279. [Online]. Available:https://doi.org/10.1145/1094811.1094832[12] J. Henkel and A. Diwan, “Catchup! capturing and replaying refactoringsto support api evolution,” in
Proceedings. 27th International Conferenceon Software Engineering, 2005. ICSE 2005. , May 2005, pp. 274–283.[13] J. H. Perkins, “Automatically generating refactorings to support apievolution,” in
Proceedings of the 6th ACM SIGPLAN-SIGSOFTWorkshop on Program Analysis for Software Tools and Engineering ,ser. PASTE’05. New York, NY, USA: Association for ComputingMachinery, 2005, pp. 111–114. [Online]. Available: https://doi.org/10.1145/1108792.1108818[14] Z. Xing and E. Stroulia, “Api-evolution support with diff-catchup,”
IEEETransactions on Software Engineering
Proceedings of the 2017 ACM SIGSAC Conference on Computerand Communications Security , ser. CCS 17. New York, NY, USA:Association for Computing Machinery, 2017, pp. 2187–2200. [Online].Available: https://doi.org/10.1145/3133956.3134059[21] J. Dietrich, D. J. Pearce, J. Stringer, A. Tahir, and K. Blincoe,“Dependency versioning in the wild,” in
Proceedings of the 16thInternational Conference on Mining Software Repositories
EmpiricalSoftware Engineering , vol. 23, no. 3, pp. 1519–1551, Jun 2018.[Online]. Available: https://doi.org/10.1007/s10664-017-9551-z[34] A. Brito, L. Xavier, A. Hora, and M. T. Valente, “Why and how javadevelopers break apis,” in , March 2018,pp. 255–265.[35] D. Dig and R. Johnson, “How do apis evolve? a story of refactoring,”
Journal of Software Maintenance and Evolution: Research andPractice , vol. 18, no. 2, pp. 83–107, 2006. [Online]. Available:https://onlinelibrary.wiley.com/doi/abs/10.1002/smr.328[36] D. Dig and R. Johnson, “The role of refactorings in api evolu-tion,” in , Sep. 2005, pp. 389–398.[37] L. Li, T. F. Bissyandé, Y. L. Traon, and J. Klein, “Accessing inaccessibleandroid apis: An empirical study,” in , Oct 2016, pp.411–422.[38] L. Li, J. Gao, T. F. Bissyandé, L. Ma, X. Xia, and J. Klein,“Characterising deprecated android apis,” in
Proceedings of the 15thInternational Conference on Mining Software Repositories , ser. MSR 18.New York, NY, USA: Association for Computing Machinery, 2018, pp.254–264. [Online]. Available: https://doi.org/10.1145/3196398.3196419[39] J. Wang, L. Li, K. Liu, and H. Cai, “Exploring how deprecatedpython library apis are (not) handled,” in
Proceedings of the 28thACM SIGSOFT International Symposium on Foundations of SoftwareEngineering , ser. FSE, 2020.[40] T. McDonnell, B. Ray, and M. Kim, “An empirical study of api stabilityand adoption in the android ecosystem,” in , Sep. 2013, pp. 70–79.[41] A. A. Sawant, M. Aniche, A. van Deursen, and A. Bacchelli, “Under-standing developers’ needs on deprecation as a language feature,” in , May 2018, pp. 561–571.[42] H. Cai, Z. Zhang, L. Li, and X. Fu, “A large-scale study ofapplication incompatibilities in android,” in
Proceedings of the 28thACM SIGSOFT International Symposium on Software Testing andAnalysis , ser. ISSTA 2019. New York, NY, USA: Associationfor Computing Machinery, 2019, pp. 216–227. [Online]. Available:https://doi.org/10.1145/3293882.3330564[43] B. E. Cossette and R. J. Walker, “Seeking the ground truth: Aretroactive study on the evolution and migration of software libraries,”in
Proceedings of the ACM SIGSOFT 20th International Symposium onthe Foundations of Software Engineering , ser. FSE 12. New York, NY,USA: Association for Computing Machinery, 2012. [Online]. Available:https://doi.org/10.1145/2393596.2393661[44] J. Dietrich, K. Jezek, and P. Brada, “Broken promises: An empiricalstudy into evolution problems in java programs caused by libraryupgrades,” in , Feb 2014, pp. 64–73.[45] K. Jezek, J. Dietrich, and P. Brada, “How java apis break - an empiricalstudy,”
Information and Software Technology
Proceedings of the 15th International Conference on Mining SoftwareRepositories , ser. MSR 18. New York, NY, USA: Associationfor Computing Machinery, 2018, pp. 503–514. [Online]. Available:https://doi.org/10.1145/3196398.3196420
47] M. Linares-Vásquez, G. Bavota, C. Bernal-Cárdenas, M. Di Penta,R. Oliveto, and D. Poshyvanyk, “Api change and fault proneness:A threat to the success of android apps,” in
Proceedings of the2013 9th Joint Meeting on Foundations of Software Engineering ,ser. ESEC/FSE 2013. New York, NY, USA: Association forComputing Machinery, 2013, pp. 477–487. [Online]. Available:https://doi.org/10.1145/2491411.2491428[48] L. Xavier, A. Brito, A. Hora, and M. T. Valente, “Historical and impactanalysis of api breaking changes: A large-scale study,” in , Feb 2017, pp. 138–147.[49] H. Xia, Y. Zhang, Y. Zhou, X. Chen, Y. Wang, X. Zhang, S. Cui,G. Hong, X. Zhang, M. Yang, and Z. Yang, “How android developershandle evolution-induced api compatibility issues: A large-scale study,”in
Proceedings of the 42th IEEE/ACM International Conference onSoftware Engineering , ser. ICSE, 2020.[50] G. Bavota, G. Canfora, M. Di Penta, R. Oliveto, and S. Panichella, “Howthe apache community upgrades dependencies: an evolutionary study,”
Empirical Software Engineering , vol. 20, no. 5, pp. 1275–1317, Oct2015. [Online]. Available: https://doi.org/10.1007/s10664-014-9325-9[51] C. Bogart, C. Kästner, J. Herbsleb, and F. Thung, “How to break an api:Cost negotiation and community values in three software ecosystems,”in
Proceedings of the 2016 24th ACM SIGSOFT InternationalSymposium on Foundations of Software Engineering , ser. FSE 2016.New York, NY, USA: Association for Computing Machinery, 2016, pp.109–120. [Online]. Available: https://doi.org/10.1145/2950290.2950325[52] A. Decan and T. Mens, “What do package dependencies tell us aboutsemantic versioning?”
IEEE Transactions on Software Engineering , pp.1–1, 2019.[53] A. Decan, T. Mens, and P. Grosjean, “An empirical comparison ofdependency network evolution in seven software packaging ecosystems,”
Empirical Software Engineering , vol. 24, no. 1, pp. 381–416, Feb2019. [Online]. Available: https://doi.org/10.1007/s10664-017-9589-y[54] K. Jezek and J. Dietrich, “On the use of static analysis to safeguardrecursive dependency resolution,” in , Aug 2014,pp. 166–173.[55] R. Kikas, G. Gousios, M. Dumas, and D. Pfahl, “Structure andevolution of package dependency networks,” in
Proceedings of the14th International Conference on Mining Software Repositories , ser.MSR 17. IEEE Press, 2017, pp. 102–112. [Online]. Available:https://doi.org/10.1109/MSR.2017.55[56] R. G. Kula, D. M. German, A. Ouni, T. Ishio, and K. Inoue,“Do developers update their library dependencies?”
Empirical SoftwareEngineering , vol. 23, no. 1, pp. 384–417, Feb 2018. [Online]. Available:https://doi.org/10.1007/s10664-017-9521-5[57] S. Mirhosseini and C. Parnin, “Can automated pull requests encouragesoftware developers to upgrade out-of-date dependencies?” in
Proceed-ings of the 32nd IEEE/ACM International Conference on AutomatedSoftware Engineering , ser. ASE 2017. IEEE Press, 2017, pp. 84–94.[58] I. Pashchenko, H. Plate, S. E. Ponta, A. Sabetta, and F. Massacci,“Vulnerable open source dependencies: Counting those that matter,”in
Proceedings of the 12th ACM/IEEE International Symposium onEmpirical Software Engineering and Measurement , ser. ESEM 18.New York, NY, USA: Association for Computing Machinery, 2018.[Online]. Available: https://doi.org/10.1145/3239235.3268920[59] Z. Xian, L. Fan, T. Liu, S. Chen, L. Li, H. Wang, Y. Xu, X. Luo, andY. Liu, “Automated third-party library detection for android applications:Are we there yet?” in
Proceedings of the 35th ACM/IEEE InternationalConference on Automated Software Engineering , ser. ASE, 2020.[60] Y. Wang, M. Wen, Z. Liu, R. Wu, R. Wang, B. Yang, H. Yu, Z. Zhu,and S.-C. Cheung, “Do the dependency conflicts in my project matter?”in
Proceedings of the 2018 26th ACM Joint Meeting on EuropeanSoftware Engineering Conference and Symposium on the Foundationsof Software Engineering , ser. ESEC/FSE 2018. New York, NY, USA:Association for Computing Machinery, 2018, pp. 319–330. [Online].Available: https://doi.org/10.1145/3236024.3236056[61] A. Zerouali, E. Constantinou, T. Mens, G. Robles, and J. González-Barahona, “An empirical analysis of technical lag in npm packagedependencies,” in
New Opportunities for Software Reuse , R. Capilla,B. Gallina, and C. Cetina, Eds. Cham: Springer International Publish-ing, 2018, pp. 95–110.[62] K. Huang, B. Chen, B. Shi, Y. Wang, C. Xu, and X. Peng, “Interactive,effort-aware library version harmonization,” in
Proceedings of the 28th ACM SIGSOFT International Symposium on Foundations of SoftwareEngineering , ser. FSE, 2020.[63] Y. Wang, M. Wen, Y. Liu, Y. Wang, Z. Li, C. Wang, H. Yu, S.-C. Cheung,C. Xu, and Z. Zhu, “Watchman: Monitoring dependency conflicts forpython library ecosystem,” in
Proceedings of the 42th IEEE/ACMInternational Conference on Software Engineering , ser. ICSE, 2020., ser. ICSE, 2020.