deb_c.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <omp.h>
#include <fenv.h>
/* Do not remove*/
/* Benoit Leveugle, CINES - ASA*/
/* This small program try to regroup most encountered bugs in HPC related work*/
/* Use -cpp for preprocessing with gcc and nothing with icc*/
 
 /* ############################################################################################
    ## Subroutines
    ############################## */
 
#ifdef leak
void function_add(void) {
 
    double *d1 = malloc(sizeof(double) * 100); // allocate an array of 100 doubles
    int i;
    for(i=0;i<100;i++)
    {
       d1[i]=d1[i]+1.0;
    }
    // forget to free the d1 memory which was allocated inside a function
}
#endif
 
 
main()
{
feenableexcept(FE_DIVBYZERO| FE_INVALID|FE_OVERFLOW);
#ifdef hello
    // hello world
    printf("Hello World\n");
#endif
 
 
 
 
 /* ############################################################################################
    ## Floating point exceptions
    ############################## */
 
#ifdef divzero 
// divided by zero, fpe
 
 double d1,d2,d3;
 
 d2 = 10.0;
 d3 = 0.0;
 d1 = d2 / d3;
 printf(" %f %f %f \n",d1,d2,d3);
 
#endif
 
#ifdef nan 
// generate a nan, fpe
 
 double d1,d2;
 
 d2 = 10.0;
 d1 = acos(d2);
 printf(" %f %f \n",d1,d2);
 
#endif
 
#ifdef overflow 
// generate an overflow, same as underflow, fpe
 
 double d1,d2;
 
 d2 = 10e10;
 d1 = exp(d2);
 printf(" %f %f \n",d1,d2);
 
#endif
 
 
 
 
 /* ############################################################################################
    ## uninitialized
    ############################## */
 
#ifdef uninitstatic
// use a non initialized value, static
 
 double d1,d2;
 
 d1 = d2*10.0;
 printf(" %f %f \n",d1,d2);
 
#endif
 
#ifdef uninitdynamic
// use a non initialized value, dynamic
 
 double *d1 = malloc(sizeof(double)*10);
 double *d2 = malloc(sizeof(double)*10);
 
 d1[3] = d2[4]*10.0;
 printf(" %f %f \n",d1[3],d2[4]);
 free(d1);
 free(d2);
 
#endif
 
#ifdef uninitalloc
// use a non initialized value, not allocated
 
 double *d1 = malloc(sizeof(double)*10);
 double *d2;
 
 d1[3] = d2[4]*10.0;
 printf(" %f %f \n",d1[3],d2[4]);
 free(d1);
 
#endif
 
 
 
 
 /* ############################################################################################
    ## allocations
    ############################## */
 
#ifdef unalloc
// try do free an non allocated variable
 
 double *d1;
 double *d2;
 
 free(d1);
 
#endif
 
#ifdef allocalloc
// try do allocate an already allocated variable
 
 double *d1;
 d1 = malloc(sizeof(double)*10);
 d1 = malloc(sizeof(double)*100);
 free(d1);
 
#endif
 
#ifdef nonfree
// detect not freed memory
 
 double *d1 = malloc(sizeof(double)*10);
 double *d2 = malloc(sizeof(double)*100);
 int i;
 for(i=0;i<100;i++)
 {
   d2[i] = 100.0;
 }
 d1[3] = d2[4]*10.0;
 printf(" %f %f \n",d1[3],d2[4]);
 
 free(d1);
 
#endif
 
 
 
 
 /* ############################################################################################
    ## arrays
    ############################## */
 
#ifdef outofbound
// out of array bounds, read or write
 
 double *d1 = malloc(sizeof(double)*10);
 int i;
 for(i=0;i<10;i++)
 {
   d1[i] = 10.0;
 }
 printf(" %f %f \n",d1[1],d1[10]);
 free(d1);
 
#endif
 
 
 
 
 /* ############################################################################################
    ## io
    ############################## */
 
#ifdef ionotopen
 
 char str1[10], str2[10], str3[10];
 int year;
 FILE * fp;
 
 fp = fopen ("file.txt", "w+"); // not a good practice, prefer w and r, and play with r, r+, w, w+, a, a+, x, x+ to secure file operations
 
 if (fp == NULL)
 {
    printf("Error opening file!\n");
    exit(1);
 }
 
 fputs("We are in 2014 \n", fp);
 
 rewind(fp);
 if( fscanf(fp, "%s %s %s %d", str1, str2, str3, &year) != EOF)
 {
 printf("Read String1 |%s|\n", str1 );
 printf("Read String2 |%s|\n", str2 );
 printf("Read String3 |%s|\n", str3 );
 printf("Read Integer |%d|\n", year );
 }
 else
 {
 printf("Could not read file");
 }
 
 fclose(fp);
 
#endif
 
 
 
 
 /* ############################################################################################
    ## memory leak
    ############################## */
 
#ifdef leak
 
 function_add();
 // the pointer 'd1' no longer exists, but the memory is still allocated. Leak.
 function_add();
 
#endif
 
 
 
 
 /* ############################################################################################
    ## stack overflow
    ############################## */
 
#ifdef stackover
 double U1[1000000];
 
  #pragma omp parallel default(none) private(U1)
  {
     U1[0]=1.0;
     printf("Hello World\n");
  }
 
#endif
 
 
 
 
 /* ############################################################################################
    ## buffer overflow
    ############################## */
 
#ifdef bufferover
 
 char           A[8] = {};
 unsigned short B    = 1979;
 
 strcpy(A, "excessive"); // 'excessiv' go to A, remaining 'e' goes to B which follows in stack memory : buffer overflow
 
#endif
 
 printf("\nEnd\n");
 
}