Abstract:
A method for demand-driven symbolic analysis involves obtaining a section of code comprising an instruction from a source code file and determining a critical variable in the section of code and data dependencies related to the critical variable. The method further involves iteratively computing a symbolic value representing a range of values of the critical variable according to the data dependencies, determining a set of control predicates relevant to the critical variable at the instruction, refining the range of values according to the set of control predicates to generate a second range of values for the symbolic value, and reporting an error when the second range of values exceeds a predetermined value.

Description:
BACKGROUND 
       [0001]    Buffer overflows are a common cause of security vulnerabilities in systems code. Specifically, buffer overflow occurs when a process stores data in a buffer outside of the memory allocated for the process. The overflow can cause diverse errors including erratic program behavior, memory access errors, incorrect results, program crashes, and security breaches. A variety of techniques have been used to attempt to locate buffer overflows in code before they occur, including both dynamic and static techniques. One such technique is symbolic analysis. 
         [0002]    Symbolic analysis was originally introduced more than 30 years ago, and has been applied in a variety of manners such as parallelization, optimization, and bug detection. The symbolic expressions resulting from symbolic analysis are typically so large and complex that external mathematical libraries are needed to solve them. As expected, these complex expressions cause symbolic analysis to be of limited use when dealing with large amounts of variables and/or large amounts of code, due to the time required to process the code. While various techniques have been developed to speed up the symbolic analysis processes, the efficiencies gained from the various techniques typically come at the cost of less accurate results. 
       SUMMARY 
       [0003]    In general, in one aspect, the invention relates to a method for demand-driven symbolic analysis. The method involves obtaining, using a processor, a section of code including a first instruction from a source code file, determining, using the processor, a critical variable in the section of code, determining, using the processor, data dependencies related to the critical variable, iteratively computing, using the processor, a symbolic value representing a first range of values of the critical variable according to the data dependencies, determining, using the processor, a first set of control predicates relevant to the critical variable at the first instruction, refining, using the processor, the first range of values according to the first set of control predicates to generate a second range of values for the symbolic value, and reporting, using the processor, an error when the second range of values exceeds a predetermined value. 
         [0004]    In general, in one aspect, the invention relates to a system for demand-driven symbolic analysis. The system includes a memory, and a processor, operatively connected to the memory and having functionality to execute instructions for obtaining a section of code, including a first instruction, from a source code file, determining a critical variable in the section of code, determining data dependencies related to the critical variable, iteratively computing a symbolic value representing a first range of values of the critical variable according to the data dependencies, determining a first set of control predicates relevant to the critical variable at the first instruction, where the first instruction represents a point within the section of code where the symbolic value will be computed, refining the first range of values according to the first set of control predicates to generate a second range of values for the symbolic value, and reporting an error when the second range of values exceeds a predetermined value. 
         [0005]    In general, in one aspect, the invention relates to a computer readable storage medium storing instructions for demand-driven symbolic analysis. The instructions include functionality to obtain a section of code, including a first instruction, from a source code file, determine a critical variable in the section of code, determine data dependencies related to the critical variable, iteratively compute a symbolic value representing a first range of values of the critical variable according to the data dependencies, determine a first set of control predicates relevant to the critical variable at the first instruction, where the first instruction represents a point within the section of code where the symbolic value will be computed, refine the first range of values according to the first set of control predicates to generate a second range of values for the symbolic value, and report an error when the second range of values exceeds a predetermined value. 
         [0006]    Other aspects and advantages of the invention will be apparent from the following description and the appended claims. 
     
    
     
       BRIEF DESCRIPTION OF DRAWINGS 
         [0007]      FIG. 1  shows a diagram of a system in accordance with one or more embodiments of the invention. 
           [0008]      FIG. 2  shows a flowchart of a method in accordance with one or more embodiments of the invention. 
           [0009]      FIGS. 3A-B  show an example in accordance with one or more embodiments of the invention. 
           [0010]      FIG. 4  shows a diagram of a computer system in accordance with one or more embodiments of the invention. 
       
    
    
     DETAILED DESCRIPTION 
       [0011]    Specific embodiments of the invention will now be described in detail with reference to the accompanying figures. Like elements in the various figures are denoted by like reference numerals for consistency. 
         [0012]    In the following detailed description of embodiments of the invention, numerous specific details are set forth in order to provide a more thorough understanding of the invention. However, it will be apparent to one of ordinary skill in the art that the invention may be practiced without these specific details. In other instances, well-known features have not been described in detail to avoid unnecessarily complicating the description. 
         [0013]    In general, embodiments of the invention provide a system and method for overflow detection. Specifically, in one or more embodiments of the invention, the method analyzes code prior to execution of the code, and determines if an overflow may occur by using symbolic analysis. The symbolic analysis is performed by determining critical variables in the code, and then defining symbolic values to represent the critical variables. More specifically, both data dependencies and control dependencies are used to iteratively compute the symbolic values of the critical variables for different instructions of the code. Initially, for a given instruction, a symbolic value for a critical variable may first be computed by considering the data dependencies of the critical variable. The symbolic value may then be refined using the control dependencies that are relevant to the critical variable. 
         [0014]    Throughout this specification the terms “overflow,” “buffer overflow,” and “exception” may be used interchangeably. Broadly speaking, a buffer overflow occurs when a process stores or reads data in a buffer outside of the memory assigned to the process. When a buffer overflow occurs, the data outside the memory assigned to the process may overwrite adjacent memory. However, this invention should not be limited to detecting buffer overflows. For example, integer overflows and any other variable overflow may also be detected in one or more embodiments of the invention. It will be apparent to one of ordinary skill in the art that the present invention may be used in a variety of techniques involving a boundary computation. In addition, the invention may be used for bug checking and other suitable purposes. 
         [0015]    A symbolic value is a representation of the potential values of a program variable. In one or more embodiments of the invention, a symbolic value may represent different potential values for different instructions (i.e., the symbolic value may be [0, 5] at line 1, and [2, 3] at line 15). Typically, the symbolic value represents a range of values, and may depend on other symbolic values. An instruction is a point of execution in the program code. In other words, an instruction may correspond to a specific moment in time during execution of the program code. Because symbolic values are based on instructions, each instruction enables the symbolic value to represent the values of a critical variable at a specific moment in program execution. A critical variable may be the variable or variables to be analyzed during a symbolic analysis. It will be apparent to one of ordinary skill in the art that there are a variety of manners for determining which variables should be analyzed and, as such, the term critical variable should not be limited to any embodiment described herein. 
         [0016]    A data dependency exists when the critical variable is dependent on an instruction preceding the defining instruction of the critical variable. More specifically, data dependencies may exist for each of the incoming operands of the instruction by which the critical variable is defined. It will be apparent to one of ordinary skill in the art that there are many types of data dependencies and, as such, the invention should not be limited to the above example. 
         [0017]    A control dependency is an instruction (e.g., an if statement, a for loop, etc.) that affects the flow of the program with respect to the critical variable. Control dependencies may be directly or indirectly related to the critical variable. The term “linearly related” may be used throughout this application to describe a directly related control dependency. It will be apparent to one of ordinary skill in the art that there are many types of control dependencies, and as such, the invention should not be limited to the above examples. 
         [0018]      FIG. 1  shows a diagram of a system in accordance with one or more embodiments of the invention. As shown in  FIG. 1 , System ( 100 ) includes Data Repository ( 102 ), Source Code ( 104 ), Code Section ( 106 ), Symbolic Analysis Application ( 110 ), Symbolic Analyzer ( 112 ), Optimization Module ( 114 ), Symbol Table ( 116 ). Each of the aforementioned components of  FIG. 1  is discussed below. 
         [0019]    Data Repository ( 102 ) may be any device capable of storing data (e.g., computer, server, hard drive, memory, flash drive, etc). Data Repository ( 102 ) may store software applications, code files, or any other type of data. In one or more embodiments of the invention, Symbolic Analysis Application ( 110 ) may reside on the same device as Data Repository ( 102 ). Alternatively, Symbolic Analysis Application ( 110 ) may reside at a different location. 
         [0020]    Source Code ( 104 ) may be stored in Data Repository ( 102 ). In one or more embodiments of the invention, Source Code ( 104 ) may be in a variety of programming languages (e.g., C, C++, Java, Pascal, Visual Basic, Python, etc), and may be for any type of program. Source Code ( 104 ) contains Code Section ( 106 ), which is the specific section that will be analyzed. In one or more embodiments of the invention, Code Section ( 106 ) may be all of Source Code ( 104 ). Alternatively, Code Section ( 106 ) may only be a few lines of code. One of ordinary skill in the art will recognize that any amount of code may be analyzed and, as such, the invention should not be limited to the above examples. 
         [0021]    In one or more embodiments of the invention, Symbolic Analysis Application ( 110 ) includes Symbolic Analyzer ( 112 ), Optimization Module ( 114 ), and Symbol Table ( 116 ). Symbolic Analysis Application ( 110 ) may be, for example, a software application or module that includes instructions for performing symbolic analysis on program code. Symbolic analysis is the process of determining the potential range of values of a variable and, when the values exceed an amount, reporting an error. 
         [0022]    Symbolic Analyzer ( 112 ) may be a software module configured to perform the symbolic analysis of variables in order to determine overflows. In one or more embodiments of the invention, Symbolic Analyzer ( 112 ) may use data dependencies and/or control dependencies to calculate symbolic values. Additionally, the Symbolic Analyzer ( 112 ) may determine which control predicates are linearly related to critical variables. A control predicate is a statement that controls the flow of a program. A control predicate is linearly related to the critical variable when the control predicate controls the value flow of the critical variable and is able to be represented as a linear function of the critical variable. It will be apparent to one of ordinary skill in the art that multiple control predicates may be linearly related to the critical variable and that control dependencies that are transformed into linearly related control dependencies may also be considered. Additionally, it will be apparent to one of ordinary skill in the art that by determining which control predicates are linearly related to the critical variable, only simple linear constraints will need to be solved, thereby greatly speeding up the process of symbolic analysis while maintaining a high degree of accuracy. In one or more embodiments of the invention, the Symbolic Analyzer ( 112 ) does not rely on external mathematical libraries to solve for symbolic values (i.e., the analysis is performed using embedded functionality of the Symbolic Analyzer ( 112 )). In one or more embodiments of the invention, Symbolic Analyzer ( 112 ) may calculate an initial value of a symbolic value using the data dependencies. The initial value may be stored, for example, in Symbol Table ( 116 ). Symbolic Analyzer ( 112 ) may use the symbolic value stored in Symbol Table ( 116 ) to calculate the value of a symbolic value at an instruction on the fly by refining the stored value using control predicates. In one or more embodiments, the symbolic value may be refined using only the control predicates that are determined to be linearly related to the critical variable. 
         [0023]    Optimization Module ( 114 ) may be a software module for implementing various optimizations for Symbolic Analysis Application ( 110 ). In one or more embodiments of the invention, optimizations adjust the speed or accuracy at which the symbolic analysis is performed, the type of variables analyzed, and/or any other aspect of symbolic analysis. Specifically, in one or more embodiments of the invention, Optimization Module ( 114 ) may be configured to identify more relevant dependencies, thereby increasing the accuracy of the analysis. For example, optimizations may include changes to solving for loop induction variables, variable analysis, path sensitive analysis, index variable analysis for global constant arrays, and other suitable optimizations. For example, loop induction variable analysis attempts to represent loop induction variables as functions to the loop iteration number, thereby allowing dependencies between induction variables and loop iteration numbers to be considered when computing symbolic ranges. In another example, path sensitive analysis allows for more precise calculation of symbolic ranges. One of ordinary skill in the art will recognize that many different optimizations may be implemented and, as such, the invention should not be limited to the above examples. 
         [0024]    Symbol Table ( 116 ) may be used for storing symbolic values. For example, Symbol Table ( 116 ) may be any data structure suitable for storing symbolic values. In one or more embodiments of the invention, Symbol Table ( 116 ) may be used to store a value of a symbolic variable generated based on data dependencies. In one or more embodiments of the invention, Symbol Table ( 116 ) may not store any other data. Alternatively, Symbol Table ( 116 ) may also store a refined value of a symbolic variable generated based on control dependencies, or any intermediate value. Symbol Table ( 116 ) may be located on Data Repository ( 102 ) or at any other suitable location. 
         [0025]      FIG. 2  shows a flowchart of a method for overflow detection in accordance with one or more embodiments of the invention. The method of  FIG. 2  may be implemented, for example, using the system of  FIG. 1 . In one or more embodiments of the invention, one or more of the steps shown in  FIG. 2  may be omitted, repeated, and/or performed in a different order than the order shown in  FIG. 2 . Accordingly, the scope of the invention should not be considered limited to the specific arrangement of steps shown in  FIG. 2 . 
         [0026]    Initially, in Step  200 , a code section is obtained for analysis. The code section may be obtained from a variety of storage devices, including both local and remote storage devices. In one or more embodiments of the invention, the code section may be provided by a user. Alternatively, the code section may be automatically obtained during an analysis of source code, or any other suitable method may be used to obtain the code section. The code section may contain an instruction, where the instruction may be the point within the code section where a symbolic value is to be determined for a critical variable. 
         [0027]    In Step  202 , a critical variable is determined. A critical variable is a variable that may cause an overflow during execution of the code section. In one or more embodiments of the invention, a critical variable may include a buffer access. Alternatively, a critical variable may include any variable that may be checked for boundaries. It will be apparent to one of ordinary skill in the art that, based on configurations or optimizations used in the symbolic analysis software, many different kinds and types of variables may be determined to be critical variables and, as such, the invention should not be limited to the above examples. In addition, it will be apparent to one of ordinary skill in the art that there may be numerous critical variables in a single code section, and that these critical variables may or may not be related to one another. Further, it will also be apparent to one of ordinary skill in the art that by only analyzing variables that may potentially cause an overflow, some variables will be ignored, thereby increasing the speed at which the symbolic analysis may be performed. 
         [0028]    In Step  204 , data dependencies are determined for the critical variable. As described above, data dependencies may be all incoming operands of the instruction by which the critical variable is defined. It will be apparent to one of ordinary skill in the art that there are many kinds of data dependencies and, as such, the invention should not be limited to the above example. Additionally, it will be apparent to one of ordinary skill in the art that only data dependencies relevant to the critical variable may be considered, however, in various optimizations a broader range of data dependencies may be considered. Accordingly, the invention should not be limited to data dependencies related to the critical variable. 
         [0029]    In Step  206 , a symbolic value is iteratively computed for the critical variable based on the data dependencies. In one or more embodiments of the invention, the symbolic value is a range of potential values for the critical variable at an instruction (e.g., a specific line of code). Initially, the value range of the symbolic value may be undefined (e.g., (−∞,∞), etc). Alternatively, the value range of the symbolic value may already be defined, based on the code section (e.g., [0, ∞)). In one or more embodiments of the invention, a symbolic value may have multiple definitions associated with it, each representing a different instruction (e.g., j0, j1, j2, etc). For example, a symbolic value definition may be associated with each instruction (i.e., location) where the critical variable is accessed or modified within the code section. Symbolic values may be dependent upon one or more of other symbolic values. Alternatively, the symbolic values may be independent, or a combination of both dependent and independent symbolic values. 
         [0030]    In one or more embodiments of the invention, the range of values of the symbolic value is computed without using an external solver. In one or more embodiments of the invention, after computing the symbolic value based on the data dependencies, the symbolic value may be stored in a symbol table, as described in  FIG. 1 . It will be apparent to one of ordinary skill in the art that additional computations of the range of values for the symbolic value may be performed. By storing this computation in a symbol table, the symbolic value may be quickly accessed and refined on demand for any given instruction, based on the stored value. 
         [0031]    An example of pseudo-code for computing the symbolic value of a critical variable according to data dependencies is shown in TABLE 1. 
         [0000]    
       
         
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
           
               
                 TABLE 1 
               
               
                   
               
             
             
               
                   
                 procedure ComputeDefRange(V) 
               
             
          
           
               
                   
                 if V has an entry in SymbolTable then return 
               
               
                   
                 end if 
               
               
                   
                 NewValSet = NewValSet ∪ V 
               
               
                   
                 set SymbolTable[V] to [T, ⊥] 
               
               
                   
                 for each operand Op i  used to compute V do 
               
             
          
           
               
                   
                 ComputeUseRange(Op i , D V ) 
               
             
          
           
               
                   
                 end for 
               
               
                   
                 Compute S V   
               
               
                   
                 SymbolTable[V] = S V   
               
               
                   
                 UpdateDefRange(V) 
               
               
                   
                 NewValSet = NewValSet \ V 
               
             
          
           
               
                   
                 end procedure 
               
               
                   
                 procedure UpdateDefRange(V) 
               
             
          
           
               
                   
                 for W ∈ NewValSet do 
               
             
          
           
               
                   
                 if S W  is dependent on S V  then 
               
             
          
           
               
                   
                 for each operand Op i  to compute S W  do 
               
             
          
           
               
                   
                 ComputeUseRange(Op i , D W ) 
               
             
          
           
               
                   
                 end for 
               
               
                   
                 Compute S W   
               
               
                   
                 SymbolTable[W] = SymbolTable[w] ∩ S W   
               
               
                   
                 if SymbolTable[W] has been updated then 
               
             
          
           
               
                   
                 UpdateDefRange(W) 
               
             
          
           
               
                   
                 end if 
               
             
          
           
               
                   
                 end if 
               
             
          
           
               
                   
                 end for 
               
             
          
           
               
                   
                 end procedure 
               
               
                   
               
             
          
         
       
     
         [0032]    In the example shown in Table 1, above, it is assumed that NewValSet and SymbolTable[ ] are initially empty. Also, V is used to represent a variable, and D V  is used to represent the unique instruction where V is defined. 
         [0033]    In Step  208 , control predicates relevant to the critical variable are determined. In one or more embodiments of the invention, the control predicates may be determined in any manner well known in the art. In one or more embodiments of the invention, only directly related control predicates of the critical variable are considered to be relevant. In other embodiments, both directly and indirectly related control predicates of the critical variable are considered to be relevant. For example, any control predicate that controls the execution of an instruction operating on the critical variable and/or the value of the critical variable may be considered to be relevant. In another example, indirectly related control predicates may also be considered to be relevant. A control predicate may be indirectly related to the critical variable when the control predicate is loaded from a buffer with the index variable directly related to the critical variable, or when the critical variable is loaded from a buffer with the index variable directly related to the control predicate. In this case, indirect control predicates may be transformed into direct control predicates by examining the content of the buffer. Additionally, it will be apparent to one of ordinary skill in the art that there are a variety of manners of identifying control predicates for analysis and, as such, the invention should not be limited to the above examples. 
         [0034]    In Step  210 , the symbolic value is refined using the relevant control predicates. As described above, the relevant control predicates may be directly or indirectly related to the critical variable. In one or more embodiments of the invention, the symbolic value is retrieved from a symbol table. In another embodiment, the symbolic value may be computed or retrieved from a different location. The symbolic value may be refined by updating the symbolic value to represent the potential values of the critical variable at a particular instruction point using the relevant control predicates. In one or more embodiments of the invention, the step of refining may be performed iteratively using the relevant control predicates when there is a cyclic dependency. An example of pseudo-code for refining the range of a symbolic value is shown in TABLE 2. 
         [0000]    
       
         
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
               
               
             
           
               
                 TABLE 2 
               
               
                   
               
             
             
               
                   
                 procedure RefineDefRange(V, P) 
               
             
          
           
               
                   
                 S V,P  = SymbolTable[V] 
               
               
                   
                 Let predSet be the set of predicates that controls both the 
               
             
          
           
               
                   
                 execution of P and the value of V 
               
             
          
           
               
                   
                 for every pred=(Op 1 ~Op 2 ) in predset do 
               
             
          
           
               
                   
                 ComputeUseRange(Op2, pred) 
               
               
                   
                 Refine S V,P   
               
             
          
           
               
                   
                 end for 
               
               
                   
                 return S V,P   
               
             
          
           
               
                   
                 end procedure 
               
               
                   
               
             
          
         
       
     
         [0035]    In the example shown above in Table 2, V is again used to represent a variable, while S V,P  is used to represent the symbolic range of variable V at instruction P. 
         [0036]    Finally, in Step  212 , errors are reported. In one or more embodiments of the invention, an error may be a buffer overflow. Alternatively, the error may be an integer overflow or other error. The error may be reported with varying levels of detail. For example, the error may include information specifying the exact line of code where the error occurred, the particular type of error, and any other relevant information. The error may be reported in any manner including but not limited to: a display, printout, text file, audio file, or any other suitable means. 
         [0037]      FIG. 3A-B  show examples in accordance with one or more embodiments of the invention. Specifically, the example in  FIG. 3A  shows a code section, and  FIG. 3B  shows the relevant blocks of the code section from  FIG. 3A  in intermediate representation. The example of  FIGS. 3A-B  has been simplified to aid in the understanding of the invention and, as such, the invention should not be limited to this example. 
         [0038]      FIG. 3A  shows Code Section ( 300 ), which contains Critical Variable ( 302 ) and Linearly Related Control Predicate ( 304 ). For the purposes of this example, Code Section ( 300 ) contains code written in the C programming language, but the invention is not limited to the C programming language, and may be used to analyze code from any programming language.  FIG. 3A  also shows that the Critical Variable ( 302 ) is the integer j at line 11. In one or more embodiments of the invention, depending on the optimizations used, other variables may also be determined to be critical variables. However, for ease of explanation, this example will focus on the integer j. In one or more embodiments of the invention, a symbolic value may be defined at each point where j is modified, accessed, or is the join point of two or more different value paths. It will be apparent to one of ordinary skill in the art that this is not an exhaustive list of all the points where a critical variable may be assigned a symbolic value.  FIG. 3A  also shows Linearly Related Control Predicate ( 304 ). Specifically, Linearly Related Control Predicate ( 304 ) shows the three instructions (i.e., line 8, 9, and 12) where a control predicate affects the flow of the integer j. It will be apparent to one of ordinary skill in the art that program controls besides if and for may be a linearly related control predicate. 
         [0039]    In general, when executed, the code in Code Section ( 300 ) takes an input string (i.e., (char*str), at line 1) and adds a letter (i.e., ESPCHAR, at line 10) in front of every capital letter of the input string. Specifically, the addition of the letter is accomplished by first creating a new string buf of size n at lines 5-6. Then, in the for loop (i.e., lines 8-13) each character of the input string is processed and copied to buf. If the character is an uppercase letter, then a new letter (i.e., ESPCHAR) is inserted into buf before the uppercase letter is copied to buf. Finally, in lines 14-16, a string terminator is appended to the end of buf. 
         [0040]      FIG. 3B  shows the Code Section ( 300 ) of  FIG. 3A  in intermediate representation. To aid in understanding of the invention, only the portions of Code Section ( 300 ) relevant to integer j are displayed in intermediate representation. In one or more embodiments of the invention, one or more of the boxes shown in  FIG. 3B  may be omitted, repeated, and/or performed in a different order than the order shown in  FIG. 3B . Accordingly, the scope of the invention should not be considered limited to the specific arrangement shown in  FIG. 3B . The elements of  FIG. 3B  will first be explained, and an example symbolic analysis, performed on the elements of  FIG. 3A-B , will be explained. 
         [0041]    Initially, the integer n is defined and buf is assigned an amount of memory (box  330 ). In box  332 , symbolic values are defined for integer i and integer j, i0 and j0, respectively. Both i0 and j0 are defined as phi nodes. A phi node is a definition of a symbolic value that represents the join point of two distinct paths that the value of the variable could take. In this case, i0 is defined as phi(0,i1), while j0 is defined as phi(0,j3). In this case, the phi nodes are used to represent the different values that i and j may have during the execution of the for loop (e.g., starts at 0 but after each loop it is incremented by 1, where the for loop may run multiple times). Further, in box  332 , pred0 is defined as i0&lt;strlen(str). In this case, pred0 is a linearly related control predicate (i.e., the for loop on line 8) and, when true, the flow of execution proceeds to box  334 . When false, the flow of execution proceeds to box  342 . 
         [0042]    In box  334 , pred1 is defined as isupper(str[i0]) (i.e., pred1 represents the if statement on line 9). If pred1 is true, the flow of execution proceeds to box  336 . If pred1 is false, the flow of execution proceeds to box  338 . In box  336 , ESPCHAR is added to buf[j0], and j1 is defined as j0+1. j1 is a new definition of the symbolic value of j. A new definition of the symbolic value of j is needed because box  336  represents a distinct path that the value of j may take (i.e., the if statement of line 9). Next, the flow of execution proceeds to box  338 . 
         [0043]    In box  338 , a new definition of the symbolic value of j, j2, is defined as phi(j1,j0), and the buffer has the character at str[i0] added to it. This phi node represents the join point of the distinct paths that the value of j may take to reach this instruction (i.e., whether or not the if statement applied). Additionally, j3 is defined as j2+1, and is then used in pred2, which is defined as (j3&gt;=n). When pred2 is false, the flow of execution proceeds to box  340 , and when it is true, the flow of execution proceeds to box  342 . In box  340 , a new definition of the symbolic value of i, i1, is defined as i0+1, and the flow of execution proceeds back to box  332 . 
         [0044]    In box  342 , a new definition of the symbolic value of j, j4, is defined as phi(j3, j0), and j4 is then used to define pred3 as (j4+1&lt;n). When pred3 is true, the flow of execution proceeds to box  344 , when it is false, the flow of execution proceeds to box  346 . In box  344 , j5 is defined as n−1, after which the flow of execution proceeds to box  346 . In box  346 , j6 is defined as phi(j4,j5) and is then used to add the string terminator to buf. Finally, in box  348 , buf is returned. 
         [0045]    Having described the elements of  FIG. 3B , an example symbolic analysis will now be described. Initially, the symbolic range of j0 is computed. By default, a symbolic range is initialized to (−∞,∞). In one or more embodiments of the invention, an optimization may be used to initialized j0 to [0, ∞). This may be done because j0 is a loop induction variable with an initial value of 0, where the loop has a positive stride. However, the symbolic range of j0 depends on the symbolic range of j3, which depends on the symbolic ranges of j2 and j1, forming a cyclic dependency. Because of this, the symbolic ranges of j0, j1, j2, and j3 will be iteratively computed. In the first iteration, based on j0=[0, ∞), j1 and j2 are equal to [1, ∞), while j3 is equal to [2, ∞). 
         [0046]    Next, the symbolic range of j0 needs to be computed based on the symbolic range of j3. If pred2, defined as j3&gt;=n in box  338 , is false, the execution of the program flows back to the phi node where j0 is defined, and accordingly it is known that the definition of j3=[2, n−1] at this instruction. In this case, the symbolic range of j0 is [0, n−1]. At this stage, the symbolic ranges of j1, j2, and j3 should be updated based on the new symbolic range of j0. Updating the symbolic ranges of j0, j1, j2, j3 may repeat as many times as is needed to reach a fixed point. One of ordinary skill in the art will recognize that there are a variety of manners for determining when to stop iteratively computing the symbolic ranges of cyclically related variables. At the end of the iterative computations, the value for j0 is [0, n−1], the value for j1 and j2 is [1, n], and the value for j3 is [2, n+1]. Thus, a buffer overflow is detected in line 11, because the maximum value for j2 (i.e., n) is greater than the size of buf. 
         [0047]    Additionally, another buffer access at line 16 should be examined. Without path-sensitive analysis, a buffer overflow will be detected at line 16, because j6 is based on phi(j4, j5), and the symbolic range of j4 is [0, n+1]. Thus, the value of j6 may exceed the size of buf. However, with path-sensitive analysis, it can be determined that the value of j4 may only reach the point where j6 is defined when j4 is less than n−1 (i.e., j4 does not go through the if statement at line 14-15). In this case, the range of j6 will be [0, n−1], which is within the bounds of buf; thus, no false buffer overflow will be reported. 
         [0048]    In one or more embodiments of the invention, in the above described example, each definition of a symbolic value may be stored in a symbol table. Alternatively, the first definition may be stored in the symbol table, and the other definitions may be generated based off of the first definition. The symbol table may be updated each time a new value is calculated for a definition of a symbolic value, such that future calculations will always have the most recent calculation available to them. It will be apparent to one of ordinary skill in the art that by saving the value range of each definition of a symbolic value in a symbol table, the speed at which symbolic analysis may be performed is greatly increased. 
         [0049]    After reading this specification, it will be apparent to one of ordinary skill in the art that this invention was created with the dual purposes of being efficient and accurate. More specifically, overflow detection as described above may be configured to be practical for analyzing vast amounts of source code rapidly. For example, overflow detection as described above may be executed for 8.6 million lines of code in 11 minutes while detecting hundreds of buffer overflows with a false positive rate of 10% using an INTEL E8600 dual core 3.33 Gigahertz processor with 8 Gigabytes of memory. Intel is a registered trademark of the Intel Corporation of Santa Clara, Calif. It will be apparent to one of ordinary skill in the art that speed and false positive rates may vary greatly depending on the code analyzed and the optimizations used and, as such, the invention should not be limited to a particular speed, accuracy, or configuration. Additionally, it will be apparent to one of ordinary skill in the art that there are many optimizations that may alter the performance of the invention in a desired way and still be within the scope of the present invention. 
         [0050]    Embodiments of the invention may be implemented on virtually any type of computer regardless of the platform being used. For example, as shown in  FIG. 4 , a computer system ( 400 ) includes one or more processor(s) ( 402 ), associated memory ( 404 ) (e.g., random access memory (RAM), cache memory, flash memory, etc.), a storage device ( 406 ) (e.g., a hard disk, an optical drive such as a compact disk drive or digital video disk (DVD) drive, a flash memory stick, etc.), and numerous other elements and functionalities typical of today&#39;s computers (not shown). The computer system ( 400 ) may also include input means, such as a keyboard ( 408 ), a mouse ( 410 ), or a microphone (not shown). Further, the computer system ( 400 ) may include output means, such as a monitor ( 412 ) (e.g., a liquid crystal display (LCD), a plasma display, or cathode ray tube (CRT) monitor). The computer system ( 400 ) may be connected to a network ( 414 ) (e.g., a local area network (LAN), a wide area network (WAN) such as the Internet, or any other similar type of network) via a network interface connection (not shown). Those skilled in the art will appreciate that many different types of computer systems exist, and the aforementioned input and output means may take other forms, now known or later developed. Generally speaking, the computer system ( 400 ) includes at least the minimal processing, input, and/or output means necessary to particularly practice embodiments of the invention. 
         [0051]    Further, those skilled in the art will appreciate that one or more elements of the aforementioned computer system ( 400 ) may be located at a remote location and connected to the other elements over a network ( 414 ). Further, embodiments of the invention may be implemented on a distributed system having a plurality of nodes, where each portion of the invention may be located on a different node within the distributed system. In one embodiment of the invention, the node corresponds to a computer system. Alternatively, the node may correspond to a processor with associated physical memory. The node may alternatively correspond to a processor with shared memory and/or resources. Further, software instructions to perform embodiments of the invention may be stored on a computer readable medium such as a compact disc (CD), a diskette, a tape, or any other computer readable storage device. 
         [0052]    While the invention has been described with respect to a limited number of embodiments, those skilled in the art, having benefit of this disclosure, will appreciate that other embodiments can be devised which do not depart from the scope of the invention as disclosed herein. Accordingly, the scope of the invention should be limited only by the attached claims.