Home | History | Annotate | Download | only in tests
      1 #define _GLIBCXX_USE_CXX11_ABI 0
      2 #define __STDC_FORMAT_MACROS
      3 #include <inttypes.h>
      4 #include <stdio.h>
      5 #include <unistd.h>
      6 #include <stdint.h>
      7 #include <stdlib.h>
      8 #include <string>
      9 #include <sstream>
     10 #include "../memcheck.h"
     11 // Derived from test provided by Timur Iskhodzhanov (bug 280271)
     12 
     13 class MyClass
     14 {
     15    char m1;
     16    int  m2;
     17 public:
     18    ~MyClass()
     19    { fprintf(stderr, "destruct MyClass\n");
     20    }
     21 };
     22 
     23 // Two hierarchies using MI, one with no fields,
     24 // the other one with some data.
     25 struct Ae
     26 {
     27    virtual ~Ae()
     28    { fprintf(stderr, "destruct Ae\n");
     29    }
     30 };
     31 struct Be
     32 {
     33    virtual ~Be()
     34    { fprintf(stderr, "destruct Be\n");
     35    }
     36 };
     37 struct Ce : public Ae, public Be
     38 {
     39    virtual ~Ce()
     40    { fprintf(stderr, "destruct Ce\n");
     41    }
     42 };
     43 
     44 struct A
     45 {
     46    char a;
     47    A()
     48    { a = 'a';
     49    }
     50    virtual ~A()
     51    { fprintf(stderr, "destruct A\n");
     52    }
     53 };
     54 struct B
     55 {
     56    char b;
     57    B()
     58    { b = 'b';
     59    }
     60    virtual ~B()
     61    { fprintf(stderr, "destruct B\n");
     62    }
     63 };
     64 struct C : public A, public B
     65 {
     66    char c;
     67    C()
     68    { c = 'c';
     69    }
     70    virtual ~C()
     71    { fprintf(stderr, "destruct C\n");
     72    }
     73 };
     74 
     75 void* wrap64_malloc(int size)
     76 {
     77   uint64_t *p = (uint64_t*)malloc(size + 8);
     78   *p = size;
     79   ++p;
     80   return p;
     81 }
     82 
     83 void wrap64_free(void *p)
     84 {
     85   uint64_t *p2 = (uint64_t*)p;
     86   if (p2 == NULL)
     87     return;
     88   --p2;
     89   free(p2);
     90 }
     91 
     92 std::string str;
     93 std::string str2;
     94 MyClass *ptr;
     95 MyClass *ptr2;
     96 Be *ptrBCe;
     97 Ae *ptrACe;
     98 B *ptrBC;
     99 A *ptrAC;
    100 void* ptr64;
    101 
    102 char who_points_at_cmd[100];
    103 
    104 void doit(void)
    105 {
    106   str = "Valgrind"; // interior ptr.
    107   str2 = str;
    108   ptr = new MyClass[3]; // interior ptr.
    109   ptr64 = wrap64_malloc(23);
    110 
    111   // prepare the who_points_at cmd we will run.
    112   // Do it here to avoid having ptr or its exterior ptr kept in a register.
    113   sprintf(who_points_at_cmd, "who_points_at %#" PRIxPTR " 20",
    114           (uintptr_t) (char*)ptr - sizeof(void*));
    115 
    116   ptr2 = new MyClass[0]; // "interior but exterior ptr".
    117   // ptr2 points after the chunk, is wrongly considered by memcheck as definitely leaked.
    118 
    119   ptrBCe = new Ce;  // interior ptr.
    120   ptrACe = new Ce;  // not an interior pointer.
    121   ptrBC = new C;  // interior ptr.
    122   ptrAC = new C;  // not an interior pointer.
    123 
    124 
    125   str2 += " rocks (str2)\n"; // interior ptr.
    126 }
    127 
    128 
    129 int main() {
    130 
    131    doit();
    132    (void) VALGRIND_MONITOR_COMMAND("v.set log_output");
    133 
    134    fprintf(stderr, "VALGRIND_DO_LEAK_CHECK\n");
    135    VALGRIND_DO_LEAK_CHECK; // All possible leaks should be detected, giving only reachable data.
    136 
    137    // Check individually each heuristic
    138    fprintf(stderr, "leak_check summary heuristics multipleinheritance\n");
    139    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance");
    140    fprintf(stderr, "leak_check summary any heuristics newarray\n");
    141    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics newarray");
    142    fprintf(stderr, "leak_check summary heuristics length64\n");
    143    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics length64");
    144    fprintf(stderr, "leak_check summary heuristics stdstring\n");
    145    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics stdstring");
    146 
    147    // check all and none
    148    fprintf(stderr, "leak_check summary heuristics multipleinheritance,newarray,stdstring,length64\n");
    149    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance,newarray,stdstring,length64");
    150    fprintf(stderr, "leak_check summary heuristics all\n");
    151    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics all");
    152    fprintf(stderr, "leak_check summary heuristics none\n");
    153    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics none");
    154 
    155    // Test the who_points_at when the block is pointed to with an interior ptr.
    156    (void) VALGRIND_MONITOR_COMMAND(who_points_at_cmd);
    157 
    158    delete [] ptr;
    159    delete [] ptr2;
    160    delete ptrBCe;
    161    delete ptrACe;
    162    delete ptrBC;
    163    delete ptrAC;
    164    wrap64_free(ptr64);
    165    fprintf(stderr, "Finished!\n");
    166    return 0;
    167 }
    168 
    169