Oracle® Solaris Studio 12.4: Code Analyzer User's Guide

Exit Print View

Updated: October 2014
 
 

Errors Analyzed by Code Analyzer

The compilers, discover, and uncover find static code issues, dynamic memory access issues, and coverage issues in your code. This appendix describes the specific error types that are found by these tools and analyzed by Code Analyzer.

Code Coverage Issues

Code coverage checking determines which functions are uncovered. In the results, code coverage issues found are labeled as Uncovered Function, with a potential coverage percentage, indicating the percentage of coverage that will be added to the total coverage for the application if a test covering the relevant function is added.

Possible Causes: No test might execute your function or you might have forgotten to delete dead or old code.

Static Code Issues

Static code checking finds the following types of errors:

  • ABR: beyond array bounds read

  • ABW: beyond array bounds write

  • DFM: double freeing memory

  • ECV: explicit type cast violation

  • FMR: freed memory read

  • FMW: freed memory write

  • INF: infinite empty loop

  • MLK: memory leak

  • MFR: missing function return

  • MRC: missing malloc return value check

  • NFR: uninitialized function return

  • NUL: null pointer dereference, leaky pointer check

  • RFM: return freed memory

  • UMR: uninitialized memory read, uninitialized memory read bit operation

  • URV: unused return value

  • VES: out-of-scope local variable usage

This section describes possible causes of the error and a code example of when the error might occur.

Beyond Array Bounds Read (ABR)

Possible causes: Attempting to read memory beyond the array bounds.

Example:

    int a[5];
    . . .
    printf("a[5] = %d\n",a[5]);  // Reading memory beyond array bounds

Beyond Array Bounds Write (ABW)

Possible causes: Attempting to write memory beyond the array bounds.

Example:

    int a [5];
     . . .
     a[5] = 5; // Writing to memory beyond array bounds

Double Freeing Memory (DFM)

Possible Causes: Calling free()() more than once with the same pointer. In C++, using the delete operator more than once on the same pointer.

Example:

    int *p = (int*) malloc(sizeof(int));
     free(p);
     . . .       // p was not signed a new value between the free statements
     free(p); // Double freeing memory

Freed Memory Read (FMR)

Example:

    int *p = (int*) malloc(sizeof(int));
    free(p);
    . . .  // Nothing assigned to p in between
    printf("p = 0x%h\n",p); // Reading from freed memory 

Freed Memory Write (FMW)

Example:

    int *p = (int*) malloc(sizeof(int));
     free(p);
     . . .        // Nothing assigned to p in between
     *p = 1; // Writing to freed memory 

Infinite Empty Loop (INF)

Example:

    int x=0;
    int i=0;
    while (i200) {
      x++; } // Infinite loop 

Memory Leak

Possible causes: Memory is allocated but not freed before exit or escaping from the function.

Example:

    int foo()
    {
     int *p = (int*) malloc(sizeof(int));
     if (x) {
      p = (int *) malloc(5*sizeof(int));  // will cause a leak of the 1st malloc
      }  
    }                                      // The 2nd malloc leaked here

Missing Function Return (MFR)

Possible causes: Missing return values along some paths to exit.

Example:

    #include <stdio.h>
    int foo (int a, int b) 
    {
      if (a) 
        { 
           return b; 
        }
    }            // If foo returns here, the return is uninitialized
    int main ( )
    {
        printf("%d\n", foo(0,30));
    }

Missing Malloc Return Value Check (MRC)

Possible causes: Accessing a return value from malloc in C or a new operator in C++ without checking against null.

Example:

    #include <stdlib.h>
    int main()
    {
     int *p3 = (int*) malloc(sizeof(int)); // Missing null-pointer check after malloc.
     *p3 = 0;
    }  

Leaky Pointer Checker: Null Pointer Dereference (NUL)

Possible causes: Accessing a pointer that might equal to null, or redundant checking against null in case the pointer is never null.

Example:

    #include <stdio.h>
    #include <stdlib.h>
    int gp, ctl;
    int main()
    {
     int *p = gp;
     if (ctl)
      p = 0;
     printf ("%c\n", *p); // May be null pointer dereference
     if (!p)
      *p = 0; // Surely null pointer dereference

    int *p2 = gp;
    *p2 = 0; // Access before checking against NULL. 
    assert (p2!=0);

    int *p3 = gp;
    if (p3) {
      printf ("p3 is not zero.\n");
    }
    *p3 = 0; // Access is not protected by previous check against NULL. 
    }

Return Freed Memory (RFM)

Example:

    #include <stdlib.h>
    int *foo ()
    {
     int *p = (int*) malloc(sizeof(int));
     free(p);
     return p; // Return freed memory is dangerous
    }
    int main()
    {
     int *p = foo();
     *p = 0;
    }

Uninitialized Memory Read (UMR)

Possible causes: Reading local or heap data that has not been initialized.

Example:

    #include <stdio.h>
    #include <stdlib.h>
     struct ttt {
        int a: 1;
        int b: 1;
     };

     int main()
     {
       int *p = (int*) malloc(sizeof(int));
       printf("*p = %d\n",*p); // Accessing uninitialized data 

       struct ttt t;
       extern void foo (struct ttt *);

       t.a = 1;
       foo (&t); // Access uninitialized bitfield data "t.b"
     }

Unused Return Value (URV)

Possible causes: Reading local or heap data that has not been initialized.

Example:

    int foo();
   int main()
   {
      foo(); // Return value is not used.
   }

Out-of-Scope Local Variable Usage (VES)

Possible causes: Reading local or heap data that has not been initialized.

Example:

    int main() 
   {
      int *p = (int *)0;
      void bar (int *);
      {
        int a[10];
        p = a;
      } // local variable 'a' leaked out
      bar(p);
    }

Dynamic Memory Access Errors

Dynamic memory access checking finds the following types of errors:

  • ABR: beyond array bounds read

  • ABW: beyond array bounds write

  • BFM: bad free memory

  • BRP: bad realloc address parameter

  • CGB: corrupted guard block

  • DFM: double freeing memory

  • FMR: freed memory read

  • FMW: freed memory write

  • FRP: freed realloc parameter

  • IMR: invalid memory read

  • IMW: invalid memory write

  • MLK: memory leak

  • OLP: overlapping source and destination

  • PIR: partially initialized read

  • SBR: beyond stack bounds read

  • SBW: beyond stack bounds write

  • UAR: unallocated memory read

  • UAW: unallocated memory write

  • UMR: uninitialized memory read

This sections describes the possible causes of the error and a code example of when the error would occur.

Beyond Array Bounds Read (ABR)

Possible causes: Attempting to read memory beyond the array bounds.

Example:

    int a[5];
    . . .
    printf("a[5] = %d\n",a[5]);  // Reading memory beyond array bounds

Beyond Array Bounds Write (ABW)

Possible causes: Attempting to write memory beyond the array bounds.

Example:

    int a [5];
     . . .
     a[5] = 5; // Writing to memory beyond array bounds

Bad Free Memory (BFM)

Possible Causes: Passing a non-heap data pointer to free()() or realloc()().

Example:

    #include <stdlib.h>
    int main()
    {
     int *p = (int*) malloc(sizeof(int));
     free(p+1); // Freeing wrong memory block
    }

Bad Realloc Address Parameter (BRP)

Example:

    #include <stdlib.h>
    int main()
    {
     int *p = (int*) realloc(0,sizeof(int));
     int *q = (int*) realloc(p+20,sizeof(int[2])); // Bad address parameter for realloc 
    }

Corrupted Guard Block (CGB)

Possible Causes: Writing past the end of a dynamically allocated array, or being in the "red zone".

Example:

    #include <stdio.h>
    #include <stdlib.h>

    int main() {
     int *p = (int *) malloc(sizeof(int)*4);
     *(p+5) = 10; //  Corrupted array guard block detected (only when the code is not annotated)
     free(p);

     return 0;
    }

Double Freeing Memory (DFM)

Possible Causes: Calling free()() more than once with the same pointer. In C++, using the delete operator more than once on the same pointer.

Example:

    int *p = (int*) malloc(sizeof(int));
     free(p);
     . . .       // p was not assigned a new value between the free statements
     free(p); // Double freeing memory

Freed Memory Read (FMR)

Example:

    int *p = (int*) malloc(sizeof(int));
     free(p);
     . . .  // Nothing assigned to p in between
     printf("p = 0x%h\n",p); // Reading from freed memory

Freed Memory Write (FMW)

Example:

    int *p = (int*) malloc(sizeof(int));
     free(p);
     . . .        // Nothing assigned to p in between
     *p = 1; // Writing to freed memory 

Freed Realloc Parameter (FRP)

Example:

   #include <stdlib.h>

   int main() {
     int *p = (int *) malloc(sizeof(int));
     free(0);
     int *q = (int*) realloc(p,sizeof(it[2])); //Freed pointer passed to realloc
   }

Invalid Memory Read (IMR)

Possible causes: Reading 2, 4, or 8 bytes from an address that is not half-word aligned, word aligned, or double-word aligned, respectively.

Example:

    #include <stdlib.h>
    int main()
    {  
      int *p = 0;
      int i = *p;   // Read from invalid memory address 
    }

Invalid Memory Write (IMW)

Possible causes: Writing 2, 4, or 8 bytes from an address that is not half-word aligned, word aligned, or double-word aligned, respectively. Writing to a text address, writing to a read-only data section (.rodata), or writing to a page that mmap has made read-only.

Example:

     int main()
   {
     int *p = 0;
     *p = 1;  // Write to invalid memory address 
   }

Memory Leak

Possible causes: Memory is allocated but not freed before exit or escaping from the function.

Example:

       int foo()
   {
     int *p = (int*) malloc(sizeof(int));
     if (x) {
      p = (int *) malloc(5*sizeof(int));  // will cause a leak of the 1st malloc
     }  
   }                                      // The 2nd malloc leaked here

Overlapping Source and Destination (OLP)

Possible causes: Incorrect source, destination, or length is specified. When the source and destination overlap, the behavior of the program is undefined.

Example:

    #include <stlib.h>
    #include <string.h>
    int main() {
      char *s=(char *) malloc(15);
      memset(s, 'x', 15);
      memcpy(s, s+5, 10);
      return 0;
    }

Partially Initialized Read (PIR)

Example:

    #include <stdio.h>
   #include <stdlib.h>
    int main()
   { 
     int *p = (int*) malloc(sizeof(int));
     *((char*)p) = 'c';
     printf("*(p = %d\n",*(p+1)); // Accessing partially initialized data 
   }

Beyond Stack Bounds Read (SBR)

Possible causes: Reading a local array past the end or before the start.

Example:

    #include <stdio.h>

   int main() {
     int a[2] = {0, 1};
     printf("a[-10]=%d\n",a[-10]); //  Read is beyond stack frame bounds

     return 0;
   }

Beyond Stack Bounds Write (SBW)

Possible causes: Writing to a local array past the end or before the start.

Example:

    #include <stdio.h>

    int main() {
     int a[2] = {0, 1};
     a[-10] = 2; //  Write is beyond stack frame bounds

     return 0;
   }

Unallocated Memory Read (UAR)

Possible causes: A stray pointer, overflowing the bounds of a heap block, or accessing a heap block that has already been freed.

Example:

    #include <stdio.h>
    #include <stdlib>
   int main()
   {
     int *p = (int*) malloc(sizeof(int));
     printf("*(p+1) = %d\n",*(p+1)); // Reading from unallocated memory
   }

Unallocated Memory Write (UAW)

Possible causes: A stray pointer, overflowing the bounds of a heap block, or accessing a heap block that has already been freed.

Example:

    #include <stdio.h>
    #include <stdlib>
   int main()
   {
    int *p = (int*) malloc(sizeof(int)); 
     *(p+1) = 1; // Writing to unallocated memory 
  }

Uninitialized Memory Read (UMR)

Possible causes: Reading local or heap data that has not been initialized.

Example:

    #include <stdio.h>
    #include <stdlib>
   int main()
   {
    int *p = (int*) malloc(sizeof(int));
    printf("*p = %d\n",*p); // Accessing uninitialized data
  }

Dynamic Memory Access Warnings

Dynamic memory access checking finds the following types of warnings:

  • AZS: allocating zero size

  • Memory leak

  • SMR: speculative uninitialized memory read

This section describes the possible causes of the warning and a code example of when the warning might occur.

Allocating Zero Size (AZS)

Example:

    #include <stdlib>
    int main()
    {
      int *p = malloc(); // Allocating zero size memory block
    }

Memory Leak (MLK)

Possible causes: Memory is allocated but not freed before exit or escaping from the function.

Example:

    int foo()
    {
     int *p = (int*) malloc(sizeof(int));
     if (x) {
      p = (int *) malloc(5*sizeof(int));  // will cause a leak of the 1st malloc
     }  
    }                                     // The 2nd malloc leaked here

Speculative Memory Read (SMR)

Example:

    int i;
    if (foo(&i) != 0)  /* foo returns nonzero if it has initialized i */
    printf("5d\n", i);

The compiler might generate the following equivalent code for the above source:

    int i;
    int t1, t2'
    t1 = foo(&i);
    t2 = i; /* value in i is loaded. So even if t1 is 0, we have uninitialized read due to speculative load */
    if (t1 != 0) 
    printf("%d\n", t2);