Abstract
Forward computing algorithms for dynamic slicing operate in tandem with program execution and generally do not require a previously stored execution trace, which make them suitable for interactive debugging and online analysis of long running programs. Both the time and space requirements of such algorithms are generally high due to the fact that they compute and maintain in memory the dynamic slices associated with all variables defined during execution. In this paper we empirically identify several characteristics of program dependences that we exploit to develop a memoization-based forward computing dynamic slicing algorithm whose runtime cost is better than that of any existing algorithm in its class. We also conduct an empirical comparative study contrasting the performance of our new algorithm to the performance of four other algorithms. One is a well known basic algorithm, and the remaining three, use reduced ordered binary decision diagrams (roBDDs) to maintain dynamic slices. Our results indicate that the new memoization-based algorithm is: (1) considerably more time and space efficient than the basic algorithm and one of the roBDD-based algorithms designed to be suitable for online analysis; and (2) comparable in terms of time efficiency but consistently more space efficient than the remaining two roBDD-based algorithms.
Similar content being viewed by others
Notes
The notion of direct dynamic control (and data) dependence becomes clear in Section 2.
This algorithm assumes that immediate postdominators are precomputed.
Assuming that sets are implemented with hash tables where primitive operations (e.g. add, contains) have unit cost on average.
Although this is a new observation, it is probably due in part to the reappearance of slices.
An essential slice is a slice that is associated with an active variable, a predicate statement or an invocation statement. In this paper, we also refer to a slice that is not essential as unessential.
Note though that it is stated in Section 3 of this paper that different variables cannot share the same slices.
It is our interest in this type of online analysis that motivated us in the first place to develop forward computing dynamic slicing algorithms.
We ran our experiments on a dual-processor machine equipped with 4GB of RAM using a 64-bit JVM and OS. The JVM was configured to allow for 8GB of maximum heap size.
It is well known that this expression only provides a rough measure of the JVM’s heap usage.
References
Agrawal H, Demillo R, Spafford E (1993) Debugging with dynamic slicing and backtracking. Softw Pract Exp 23(6):589–616
Agrawal H, Horgan J (1990) Dynamic program slicing. SIGPLAN Not 25(6):246–256
Beszedes A, Gergely T, Szabó ZM, Csirik J, Gyimothy T (2001) Dynamic slicing method for maintenance of large C Programs. 5th European Conf. on Software Maintenance and Re-engineering (Portugal, March 2001).
Beszedes A, Farago C, Szabo ZM, Csirik J, Gyimothy T (2002) Union Slices for Program Maintenance. Proceedings of the International Conference on Software Maintenance (ICSM’02).
Binkley D (1998) The application of program slicing to regression testing. Information and Software Technology (I&ST) special issue on program slicing V40 N11–12, pp 583–594
Cormen T, Leiserson C, Rivest R, Stein C (2001) Introduction to algorithms, 2nd edn. MIT, Cambridge, MA
Denning DE (1976) A lattice model of secure information flow. Commun ACM 19(5):236–242
Do H, Elbaum S, Rothermel G (2005) Supporting controlled experimentation with testing techniques: an infrastructure and its potential impact. Empirical Software Engineering International Journal 10(4):405–435
Gallagher K, Lyle J (1991) Using program slicing in software maintenance. IEEE Trans Softw Eng 17(8):751–761
Harman M, Danicic S (1995) Using program slicing to simplify testing. software testing. Verification and Reliability 5(3):143–162
Korel B (1997) Computation of dynamic program slices for unstructured programs. IEEE TSE 23(1):17–34
Korel B, Laski J (1988) Dynamic program slicing. Inf Process Lett 29:155–163
Korel B, Rilling J (1998). Program slicing in understanding of large programs. Proceedings of the 6th International Workshop on Program Comprehension
Korel B, Yalamanchili S (1994). Forward computation of dynamic program slices. ISSTA, pp 66–79
Masri W, Nahas N, Podgurski A (2006) Memoized forward computation of dynamic slices. 17th IEEE International Symposium on Software Reliability Engineering, ISSRE 2006. Raleigh, NC, USA, November 2006
Masri W, Podgurski A, Leon D (2004) Detecting and debugging insecure information flows. 15th IEEE International Symposium on Software Reliability Engineering, ISSRE 2004, St. Malo, France, Nov 2–5, 2004
Masri WB (2004) Dynamic information flow analysis, slicing and profiling. Ph.D. dissertation, 2004. http://www.lib.umi.com/dissertations/fullcit/3146448
Meinel C, Theobald T (1998) Algorithms and data structures in VLSI design: OBDD—foundations and applications. Springerp New York
Pan K, Whitehead J (2005) An investigation of program slice encoding and its applications. ISR Research Forum, June
Smith S, Thober M (2006). Refactoring programs to secure information flows. Proceedings of the 2006 workshop on Programming languages and analysis for security 75–84
The Byte Code Engineering Library (BCEL) (2003) The Apache Jakarta Project. http://jakarta.apache.org/bcel. Apache Software Foundation
Tip F (1995) A survey of program slicing techniques. J Program Lang 3(3):121–189
Weiser M (1984) Program slicing. IEEE Trans Softw Eng 10(4):352–357
Zhang X, Gupta R (2004) Cost effective dynamic program slicing, ACM SIGPLAN Conference on Programming Language Design and Implementation, pages 94–106, Washington DC, June 2004
Zhang X, Gupta R, Zhang Y (2004) Efficient forward computation of dynamic slices using reduced ordered binary decision diagrams. International Conference on Software Engineering, Edinburgh, UK, May 2004
Zhang X, Gupta R, Zhang Y (2003) Precise dynamic slicing algorithms, IEEE/ACM International Conference on Software Engineering, pp 319–329, Portland, Oregon, May 2003
Zimmermann J, Mé L, Bidan C (2003a) An improved reference flow control model for policy-based intrusion detection. 8th European Symposium on Research in Computer Security, Gjøvik, Norway, October 2003, Lecture Notes in Computer Science 2808. Springer, New York
Zimmermann J, Mé L, Bidan C (2003b) Experimenting with a policy-based HIDS based on and information flow control model. 19th Computer Security Applications Conference, Las Vegas, November 2003
Acknowledgments
Dr. Masri’s research was partially supported by a grant from the Lebanese National Council of Scientific Research to the American University of Beirut.
Author information
Authors and Affiliations
Corresponding author
Additional information
Editor: Mark Harman
This paper is a revised and extended version of Memoized Forward Computation of Dynamic Slices by W. Masri, N. Nahas N. and A. Podgurski, that appeared in the17th IEEE International Symposium on Software Reliability Engineering, ISSRE 2006.
Appendix 1
Appendix 1
We now provide a high level walkthrough of our algorithm when applied to a simple snippet of Java code. For simplicity, we use a version of our algorithm that processes pairs of slices only. We also discuss our walkthrough in the context of Java source code as opposed to byte code. Suppose we have the following program:
-
(1)
int a = 1;
-
(2)
int b = 2;
-
(3)
int c = 3;
-
(4)
int d = 4;
-
(5)
int i = 0;
-
(6)
while (i < 1000){
-
(7)
a = a + b;
-
(8)
b = b + 1;
-
(9)
if (b % 2 = = 0) {
-
(10)
a = a + c;
-
(11)
}else {
-
(12)
a = a + d;
-
(13)
}
-
(14)
i + + ;
-
(15)
}
Table 8 yields the state of the slices corresponding to each of the variables, as well as selected modifications to the main data structures during each timeslot. Time T = 0 corresponds to the state before the program begins execution, time T = 1 corresponds to the time just after the first statement (i.e. line 1) has executed, and so on. The main actions taken by our algorithm at each time slot are described below:
-
T = 0:
No slices get computed and none exist yet.
-
T = 1:
The variable a is only influenced by statement 1, so its slice is the set {1}. Since {1} is the first slice which comes up in the program, it is assigned uid 1 and its corresponding entry ({1},1) is added to sliceToUid.
-
T = 2:
The variable b is only influenced by statement 2, so its slice is the set {2}. Slice {2} is assigned uid 2 and its corresponding entry ({2},2) is added to sliceToUid.
-
T = 3, 4 and 5:
Actions similar to the above are taken when executing statements 3, 4, and 5.
-
T = 6:
The following is done when the while statement executes for the first time:
-
1.
The only direct influence on statement 6 is statement 5 which was associated with slice ({5}, 5) at T = 5.
-
2.
Since statement 6 must be included in the resulting slice, slice {6} is computed, it is assigned uid 6, and sliceToUid is updated with entry ({6},6).
-
3.
Slice {5, 6} is computed, it is assigned uid 7, and sliceToUid is updated with entry ({5, 6},7).
-
4.
uid2TupleToUid is updated with ((5,6),7) to indicate that the unioning of the two slices identified by uid 5 and uid 6 results in a slice identified by uid 7.
-
1.
-
T = 7:
The slice of the variable a defined by statement 7 is computed as follows:
-
1.
The direct influences on statement 7 are found to be statements 1, 2, and 6, which are associated with slices {1}, {2}, and {5, 6}, respectively.
-
2.
Slices {1} and {2} are merged which results in adding entry ({1, 2},8) to sliceToUid and entry ((1,2),8) to uid2TupleToUid.
-
3.
Slices {1, 2} and {5, 6} are merged which results in adding entry ({1, 2, 5, 6},9) to sliceToUid and entry ((7,8),9) to uid2TupleToUid.
-
4.
Since statement 7 defines a, entry ({7},10) is added to sliceToUid.
-
5.
Finally, {7} and {1, 2, 5, 6} are merged which results in adding entry ({1, 2, 5, 6, 7},11) to sliceToUid and entry ((9,10),11) to uid2TupleToUid
-
1.
-
T = 8:
Similarly, the slice of the variable b defined by statement 8 is computed as follows:
-
1.
The direct influences on statement 8 are found to be statements 2, and 6, which are associated with slices {2} and {5, 6}, respectively.
-
2.
Slices {2} and {5, 6} are merged which results in adding entry ({2, 5, 6}, 12) to sliceToUid and entry ((2,7),12) to uid2TupleToUid.
-
3.
Since statement 8 defines b, entry ({8}, 13) is added to sliceToUid.
-
4.
Finally, {8} and {2, 5, 6} are merged which results in adding entry ({2, 5, 6, 8},14) to sliceToUid and entry ((12,13),14) to uid2TupleToUid
-
1.
-
T = 9:
The slice of the if statement is computed as follows:
-
1.
The direct influences on statement 9 are found to be statements 6 and 8, which are associated with slices ({5, 6},7) and ({2, 5, 6, 8},14), respectively.
-
2.
The entry ({2, 5, 6, 8},14) representing the union of {5, 6} and {2, 5, 6, 8} has already been added to sliceToUid at T = 8, so there is no need to add a corresponding new entry. But entry ((7,14),14) is added to uid2TupleToUid to avoid any future unioning of {5, 6} and {2, 5, 6, 8}.
-
3.
Entry ({9}, 15) is added to sliceToUid since {9} should be part of the slice.
-
4.
Finally, {9} and {2, 5, 6, 8} are merged which results in adding entry ({2, 5, 6, 8, 9},16) to sliceToUid and entry ((14,15),16) to uid2TupleToUid.
-
1.
-
T = 10, 11, 12, 13, and 14:
Actions similar to what is described above are taken.
-
T = 15:
When statement 9 executes for the second time, no new entries are added to sliceToUid or to uid2TupleToUid, and this is why:
-
1.
The direct influences on statement 9 are statements 6 and 8, which are associated with slices ({5, 6}, 7) and ({2, 5, 6, 8}, 14), respectively.
-
2.
uid2TupleToUid already contains entry ((7,14),14), so no unioning of {5, 6} and {2, 5, 6, 8} is needed.
-
3.
sliceToUid already contains entry ({9}, 15), so there is no need to add a corresponding new entry.
-
4.
uid2TupleToUid already contains entry ((14,15),16), so no unioning of {2, 5, 6, 8} and {9} is needed.
-
1.
Similar to the case for T = 15, for T = 17, 19, 21, 23 and higher no new entries are added to sliceToUid or to uid2TupleToUid, that is no slice computation are necessary (only look ups and fetches from uid2TupleToUid are performed). Therefore, in the subsequent 996 iterations of the loop, merging pairs of slices takes constant time on average.
Rights and permissions
About this article
Cite this article
Masri, W. Exploiting the empirical characteristics of program dependences for improved forward computation of dynamic slices. Empir Software Eng 13, 369–399 (2008). https://doi.org/10.1007/s10664-008-9071-y
Published:
Issue Date:
DOI: https://doi.org/10.1007/s10664-008-9071-y