A program slice consists of the parts of a program that (potentially)
affect the values computed at some point of interest. Such a point of
interest is referred to as a slicing criterion, and is typically speci
fied by a location in the program in combination with a subset of the
program's variables. The task of computing program slices is called pr
ogram slicing. The original definition of a program slice was presente
d by Weiser in 1979. Since then, various slightly different notions of
program slices have been proposed, as well as a number of methods to
compute them. An important distinction is that between a static and a
dynamic slice. Static slices are computed without making assumptions r
egarding a program's input, whereas the computation of dynamic slices
relies on a specific test case. This survey presents an overview of pr
ogram slicing, including the various general approaches used to comput
e slices, as well as the specific techniques used to address a variety
of language features such as procedures, unstructured control flow, c
omposite data types and pointers, and concurrency. Static and dynamic
slicing methods for each of these features are compared and classified
in terms of their accuracy and efficiency. Moreover, the possibilitie
s for combining solutions for different features are investigated. Rec
ent work on the use of compiler-optimization and symbolic execution te
chniques for obtaining more accurate slices is discussed. The paper co
ncludes with an overview of the applications of program slicing, which
include debugging, program integration, data flow testing, and softwa
re maintenance.