Home | History | Annotate | Download | only in tests
      1 /* Copyright (c) 2009, Google Inc.
      2  * All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  *
     30  * ---
     31  * Author: Craig Silverstein
     32  *
     33  * This tests the c shims: malloc_extension_c.h and malloc_hook_c.h.
     34  * Mostly, we'll just care that these shims compile under gcc
     35  * (*not* g++!)
     36  *
     37  * NOTE: this is C code, not C++ code!
     38  */
     39 
     40 #include <stdio.h>
     41 #include <stdlib.h>
     42 #include <stddef.h>   /* for size_t */
     43 #include <gperftools/malloc_extension_c.h>
     44 #include <gperftools/malloc_hook_c.h>
     45 
     46 #define FAIL(msg) do {                          \
     47   fprintf(stderr, "FATAL ERROR: %s\n", msg);    \
     48   exit(1);                                      \
     49 } while (0)
     50 
     51 static int g_new_hook_calls = 0;
     52 static int g_delete_hook_calls = 0;
     53 
     54 void TestNewHook(const void* ptr, size_t size) {
     55   g_new_hook_calls++;
     56 }
     57 
     58 void TestDeleteHook(const void* ptr) {
     59   g_delete_hook_calls++;
     60 }
     61 
     62 void TestMallocHook(void) {
     63   /* TODO(csilvers): figure out why we get:
     64    * E0100 00:00:00.000000  7383 malloc_hook.cc:244] RAW: google_malloc section is missing, thus InHookCaller is broken!
     65    */
     66 #if 0
     67   void* result[5];
     68 
     69   if (MallocHook_GetCallerStackTrace(result, sizeof(result)/sizeof(*result),
     70                                      0) < 2) {  /* should have this and main */
     71     FAIL("GetCallerStackTrace failed");
     72   }
     73 #endif
     74 
     75   if (!MallocHook_AddNewHook(&TestNewHook)) {
     76     FAIL("Failed to add new hook");
     77   }
     78   if (!MallocHook_AddDeleteHook(&TestDeleteHook)) {
     79     FAIL("Failed to add delete hook");
     80   }
     81   free(malloc(10));
     82   free(malloc(20));
     83   if (g_new_hook_calls != 2) {
     84     FAIL("Wrong number of calls to the new hook");
     85   }
     86   if (g_delete_hook_calls != 2) {
     87     FAIL("Wrong number of calls to the delete hook");
     88   }
     89   if (!MallocHook_RemoveNewHook(&TestNewHook)) {
     90     FAIL("Failed to remove new hook");
     91   }
     92   if (!MallocHook_RemoveDeleteHook(&TestDeleteHook)) {
     93     FAIL("Failed to remove delete hook");
     94   }
     95 }
     96 
     97 void TestMallocExtension(void) {
     98   int blocks;
     99   size_t total;
    100   int hist[64];
    101   char buffer[200];
    102   char* x = (char*)malloc(10);
    103 
    104   MallocExtension_VerifyAllMemory();
    105   MallocExtension_VerifyMallocMemory(x);
    106   MallocExtension_MallocMemoryStats(&blocks, &total, hist);
    107   MallocExtension_GetStats(buffer, sizeof(buffer));
    108   if (!MallocExtension_GetNumericProperty("generic.current_allocated_bytes",
    109                                           &total)) {
    110     FAIL("GetNumericProperty failed for generic.current_allocated_bytes");
    111   }
    112   if (total < 10) {
    113     FAIL("GetNumericProperty had bad return for generic.current_allocated_bytes");
    114   }
    115   if (!MallocExtension_GetNumericProperty("generic.current_allocated_bytes",
    116                                           &total)) {
    117     FAIL("GetNumericProperty failed for generic.current_allocated_bytes");
    118   }
    119   MallocExtension_MarkThreadIdle();
    120   MallocExtension_MarkThreadBusy();
    121   MallocExtension_ReleaseToSystem(1);
    122   MallocExtension_ReleaseFreeMemory();
    123   if (MallocExtension_GetEstimatedAllocatedSize(10) < 10) {
    124     FAIL("GetEstimatedAllocatedSize returned a bad value (too small)");
    125   }
    126   if (MallocExtension_GetAllocatedSize(x) < 10) {
    127     FAIL("GetEstimatedAllocatedSize returned a bad value (too small)");
    128   }
    129   if (MallocExtension_GetOwnership(x) != MallocExtension_kOwned) {
    130     FAIL("DidAllocatePtr returned a bad value (kNotOwned)");
    131   }
    132   /* TODO(csilvers): this relies on undocumented behavior that
    133      GetOwnership works on stack-allocated variables.  Use a better test. */
    134   if (MallocExtension_GetOwnership(hist) != MallocExtension_kNotOwned) {
    135     FAIL("DidAllocatePtr returned a bad value (kOwned)");
    136   }
    137 
    138   free(x);
    139 }
    140 
    141 int main(int argc, char** argv) {
    142   TestMallocHook();
    143   TestMallocExtension();
    144 
    145   printf("PASS\n");
    146   return 0;
    147 }
    148