Home | History | Annotate | Download | only in malloc_debug
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      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 copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #pragma once
     30 
     31 #include <pthread.h>
     32 #include <stdint.h>
     33 #include <unistd.h>
     34 
     35 #include <atomic>
     36 #include <mutex>
     37 #include <string>
     38 
     39 #include <private/bionic_macros.h>
     40 
     41 class RecordEntry {
     42  public:
     43   RecordEntry();
     44   virtual ~RecordEntry() = default;
     45 
     46   virtual std::string GetString() const = 0;
     47 
     48  protected:
     49   pid_t tid_;
     50 
     51  private:
     52   BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordEntry);
     53 };
     54 
     55 class ThreadCompleteEntry : public RecordEntry {
     56  public:
     57   ThreadCompleteEntry() = default;
     58   virtual ~ThreadCompleteEntry() = default;
     59 
     60   std::string GetString() const override;
     61 
     62  private:
     63   BIONIC_DISALLOW_COPY_AND_ASSIGN(ThreadCompleteEntry);
     64 };
     65 
     66 class AllocEntry : public RecordEntry {
     67  public:
     68   explicit AllocEntry(void* pointer);
     69   virtual ~AllocEntry() = default;
     70 
     71  protected:
     72   void* pointer_;
     73 
     74  private:
     75   BIONIC_DISALLOW_COPY_AND_ASSIGN(AllocEntry);
     76 };
     77 
     78 class MallocEntry : public AllocEntry {
     79  public:
     80   MallocEntry(void* pointer, size_t size);
     81   virtual ~MallocEntry() = default;
     82 
     83   std::string GetString() const override;
     84 
     85  protected:
     86   size_t size_;
     87 
     88  private:
     89   BIONIC_DISALLOW_COPY_AND_ASSIGN(MallocEntry);
     90 };
     91 
     92 class FreeEntry : public AllocEntry {
     93  public:
     94   explicit FreeEntry(void* pointer);
     95   virtual ~FreeEntry() = default;
     96 
     97   std::string GetString() const override;
     98 
     99  private:
    100   BIONIC_DISALLOW_COPY_AND_ASSIGN(FreeEntry);
    101 };
    102 
    103 class CallocEntry : public MallocEntry {
    104  public:
    105   CallocEntry(void* pointer, size_t size, size_t nmemb);
    106   virtual ~CallocEntry() = default;
    107 
    108   std::string GetString() const override;
    109 
    110  protected:
    111   size_t nmemb_;
    112 
    113  private:
    114   BIONIC_DISALLOW_COPY_AND_ASSIGN(CallocEntry);
    115 };
    116 
    117 class ReallocEntry : public MallocEntry {
    118  public:
    119   ReallocEntry(void* pointer, size_t size, void* old_pointer);
    120   virtual ~ReallocEntry() = default;
    121 
    122   std::string GetString() const override;
    123 
    124  protected:
    125   void* old_pointer_;
    126 
    127  private:
    128   BIONIC_DISALLOW_COPY_AND_ASSIGN(ReallocEntry);
    129 };
    130 
    131 // aligned_alloc, posix_memalign, memalign, pvalloc, valloc all recorded with this class.
    132 class MemalignEntry : public MallocEntry {
    133  public:
    134   MemalignEntry(void* pointer, size_t size, size_t alignment);
    135   virtual ~MemalignEntry() = default;
    136 
    137   std::string GetString() const override;
    138 
    139  protected:
    140   size_t alignment_;
    141 
    142  private:
    143   BIONIC_DISALLOW_COPY_AND_ASSIGN(MemalignEntry);
    144 };
    145 
    146 class Config;
    147 
    148 class RecordData {
    149  public:
    150   RecordData();
    151   virtual ~RecordData();
    152 
    153   bool Initialize(const Config& config);
    154 
    155   void AddEntry(const RecordEntry* entry);
    156   void AddEntryOnly(const RecordEntry* entry);
    157 
    158   void SetToDump() { dump_ = true; }
    159 
    160   pthread_key_t key() { return key_; }
    161 
    162  private:
    163   void Dump();
    164 
    165   std::mutex dump_lock_;
    166   pthread_key_t key_;
    167   const RecordEntry** entries_ = nullptr;
    168   size_t num_entries_ = 0;
    169   std::atomic_uint cur_index_;
    170   std::atomic_bool dump_;
    171   std::string dump_file_;
    172 
    173   BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordData);
    174 };
    175