Home | History | Annotate | Download | only in tests
      1 #include <stdlib.h>
      2 #include <stdio.h>
      3 #include <assert.h>
      4 #include <string.h>
      5 #include "helgrind/helgrind.h"
      6 
      7 #define MAX 1000000
      8 static unsigned char shadow[MAX];
      9 
     10 
     11 #define V(cond, testline)                                               \
     12    do { if (!(cond))                                                    \
     13          fprintf (stderr, "Test at line %d Failed verif at line %d: " #cond "\n", \
     14                   testline, __LINE__); }                                \
     15    while (0)
     16 
     17 #define CHK(a1,a2,a3,a4) check(__LINE__,a1,a2,a3,a4)
     18 /* Check that [p, p+len[ has access access.
     19    If heap, check that one byte before and after is unaccessible */
     20 static void check (int testline, void *p, int len, unsigned char access, int heap)
     21 {
     22    int i;
     23    long int r;
     24 
     25    assert (len < 1000000); // Do not exceed the shadow array
     26 
     27    if (len == 0 && p == NULL)
     28       return;
     29    // malloc(0) can return a ptr or NULL.
     30    // Let's not check NULL
     31 
     32    r = VALGRIND_HG_GET_ABITS (p, shadow, len);
     33    V (r == VALGRIND_HG_GET_ABITS (p, NULL, len), testline);
     34    V (access == 0xff ? r == len : r == 0, testline);
     35    for (i = 0; i < len; i++)
     36       V(shadow[i] == access, testline);
     37    if (heap) {
     38       /* Check the range starting 1 byte before. */
     39       r = VALGRIND_HG_GET_ABITS (p-1, shadow, len+1);
     40       V (r == VALGRIND_HG_GET_ABITS (p-1, NULL, len+1), testline);
     41       V (access == 0xff ? r == len : r == 0, testline);
     42       V (shadow[0] == 0x00, testline);
     43       for (i = 1; i < len+1; i++)
     44          V (shadow[i] == access, testline);
     45       /* Same but one byte after. We need special cases for
     46          a len 0,*/
     47       r = VALGRIND_HG_GET_ABITS (p+1, shadow, len);
     48       V (r == VALGRIND_HG_GET_ABITS (p+1, NULL, len), testline);
     49       if (len == 0)
     50          V (r == 0, testline);
     51       else
     52          V (access == 0xff ? r == len-1 : r == 0, testline);
     53       for (i = 0; i < len-1; i++)
     54          V(shadow[i] == access, testline);
     55       if (len != 0)
     56          V(shadow[len-1] == 0x00, testline);
     57    }
     58 }
     59 
     60 /* return an address on the stack, with big var on the stack,
     61    to ensure it is really unaddressable when calling check. */
     62 static void* popped_stack_address(void)
     63 {
     64    char s[MAX];
     65    memcpy(s, shadow, MAX);
     66    char *p;
     67 
     68    p = &s[MAX/2-1-s[0]];
     69    CHK(p, 1, 0xFF, 0);
     70    return p;
     71 }
     72 
     73 int main ( void )
     74 {
     75    char *p;
     76 
     77    /* Basic test for an heap object */
     78    fprintf(stderr, "basic heap test\n");
     79    p = malloc (100);
     80    CHK (p, 100, 0xff, 1);
     81    free (p);
     82    CHK (p, 100, 0x00, 1);
     83 
     84    /* Basic test for some code : verify 50 bytes of check function code
     85       is accessible. */
     86    fprintf(stderr, "code test\n");
     87    CHK (check, 50, 0xff, 0);
     88 
     89    /* Check something on the stack */
     90    fprintf(stderr, "stack test\n");
     91    CHK (&p, sizeof(p), 0xff, 0);
     92 
     93 
     94    /* Now shake the heap, to verify various sizes */
     95    fprintf(stderr, "doing many heap blocks\n");
     96    int i;
     97    int j;
     98 #  define X 200
     99 #  define Y 4
    100    void *ptr[X][Y];
    101    int sz[X][Y];
    102    int f[X][Y]; // already freed or not ?
    103    for (i = 0; i < X; i++) {
    104       for (j = 0; j < Y; j++) {
    105          f[i][j] = 1;
    106          // A SecMap represents 8Kb. We test the boundaries
    107          // around such secmap (X/2 bytes before and after)
    108          // We test with blocks covering from 0 till Y-1 secmaps
    109          sz[i][j] = j * 8192 - (j == 0 ? 0 : X/2) + i;
    110          ptr[i][j] = malloc(sz[i][j]);
    111          CHK(ptr[i][j],sz[i][j], 0xff, 1);
    112       }
    113    }
    114    /* Shake and check when doing random free */
    115    fprintf(stderr, "random heap free and checks\n");
    116    for (i = 0; i < X*Y/10; i++) {
    117       int x = rand() % X;
    118       int y = rand() % Y;
    119       if (f[x][y]) {
    120          CHK(ptr[x][y],sz[x][y], 0xff, 1);
    121          free(ptr[x][y]);
    122          f[x][y] = 0;
    123       }
    124       CHK(ptr[x][y],sz[x][y], 0x00, 1);
    125    }
    126 
    127 #if 0
    128    /* Check that a use after return gives unaddressable. */
    129    CHK (popped_stack_address(), 1, 0x00, 0);
    130    /* Well well, it seems helgrind keeps the stack accessible */
    131 #endif
    132    (void) popped_stack_address();
    133 
    134    return 0;
    135 }
    136 
    137