Skip to content

GNU Compiler Collection: Static Analyzer

  • Static-analysis of source code during compile time
    ⇒ A kind of extended warnings
    ⇒ No need to run the binary
  • Potentially false negative
  • Problems that can be detected
    • double memory free
    • double file close
    • use of memory after free
    • use of uninitialized values
    • ...
  • GCC Static Analyzer Options
  • Basic usage

    gcc -fanalyzer ${SOURCE}
    

Example: Static-Analyzer - Use after free

  • Source code use_after_free.c++

    #include <iostream>
    
    int main(int argc, char *argv[]) {
        char *charArray = new char[10];
        delete [] charArray;
        std::cout << charArray[0] << std::endl;
    }
    
  • Set up compiler environment

    module add compiler/gnu
    
  • Compile

    c++ -fanalyzer use_after_free.c++ -o use_after_free
    
    use_after_free.c++: In function ‘int main(int, char**)’:
    use_after_free.c++:6:29: warning: dereference of NULL ‘charArray’ [CWE-476] [-Wanalyzer-null-dereference]
        6 |     std::cout << charArray[0] << std::endl;
          |                  ~~~~~~~~~~~^
      ‘int main(int, char**)’: events 1-5
        |
        |    4 |     char *charArray = new char[10];
        |      |                                  ^
        |      |                                  |
        |      |                                  (1) allocated here
        |    5 |     delete [] charArray;
        |      |     ~~~~~~~~~~~~~~~~~~~           
        |      |     |
        |      |     (2) assuming ‘charArray’ is NULL
        |      |     (3) following ‘false’ branch (when ‘charArray’ is NULL)...
        |    6 |     std::cout << charArray[0] << std::endl;
        |      |                  ~~~~~~~~~~~~     
        |      |                             |
        |      |                             (4) ...to here
        |      |                             (5) dereference of NULL ‘charArray’
        |
    use_after_free.c++:6:29: warning: use after ‘delete[]’ of ‘charArray’ [CWE-416] [-Wanalyzer-use-after-free]
        6 |     std::cout << charArray[0] << std::endl;
          |                  ~~~~~~~~~~~^
      ‘int main(int, char**)’: events 1-6
        |
        |    4 |     char *charArray = new char[10];
        |      |                                  ^
        |      |                                  |
        |      |                                  (1) allocated here
        |    5 |     delete [] charArray;
        |      |     ~~~~~~~~~~~~~~~~~~~           
        |      |     |         |
        |      |     |         (4) ...to here
        |      |     |         (5) deleted here
        |      |     (2) assuming ‘charArray’ is non-NULL
        |      |     (3) following ‘true’ branch (when ‘charArray’ is non-NULL)...
        |    6 |     std::cout << charArray[0] << std::endl;
        |      |                  ~~~~~~~~~~~~     
        |      |                             |
        |      |                             (6) use after ‘delete[]’ of ‘charArray’; deleted at (5)
        |
    

Example: Static-Analyzer - Uninitialized values

  • Source code uninitialized_values.c++

    #include <iostream>
    
    int main(int argc, char *argv[]) {
        double x, y;
        x = y + 1.;
        std::cout << "x = " << x
                  << "y = " << y << std::endl;
    }
    
  • Set up compiler environment

    module add compiler/gnu
    
  • Compile

    c++ -fanalyzer uninitialized_values.c++ -o uninitialized_values
    
    uninitialized_values.c++: In function 'int main(int, char**)':
    uninitialized_values.c++:5:7: warning: use of uninitialized value 'y' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
        5 |     x = y + 1.;
          |     ~~^~~~~~~~
      'int main(int, char**)': events 1-3
        |
        |    4 |     double x, y;
        |      |               ^
        |      |               |
        |      |               (1) region created on stack here
        |      |               (2) capacity: 8 bytes
        |    5 |     x = y + 1.;
        |      |     ~~~~~~~~~~ 
        |      |       |
        |      |       (3) use of uninitialized value 'y' here
        |