1b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine/*
2b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * Copyright (C) 2009 The Android Open Source Project
3b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * All rights reserved.
4b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine *
5b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * Redistribution and use in source and binary forms, with or without
6b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * modification, are permitted provided that the following conditions
7b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * are met:
8b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine *  * Redistributions of source code must retain the above copyright
9b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine *    notice, this list of conditions and the following disclaimer.
10b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine *  * Redistributions in binary form must reproduce the above copyright
11b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine *    notice, this list of conditions and the following disclaimer in
12b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine *    the documentation and/or other materials provided with the
13b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine *    distribution.
14b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine *
15b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * SUCH DAMAGE.
27b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine */
28b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine
29b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine/*
30b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * Contains declarations of types and constants used by malloc leak
31b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * detection code in both, libc and libc_malloc_debug libraries.
32b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine */
33b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#ifndef MALLOC_DEBUG_COMMON_H
34b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#define MALLOC_DEBUG_COMMON_H
35b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine
36b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#define HASHTABLE_SIZE      1543
37b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#define BACKTRACE_SIZE      32
38b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine/* flag definitions, currently sharing storage with "size" */
39b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#define SIZE_FLAG_ZYGOTE_CHILD  (1<<31)
40b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#define SIZE_FLAG_MASK          (SIZE_FLAG_ZYGOTE_CHILD)
41b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine
42b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#define MAX_SIZE_T           (~(size_t)0)
43b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine
44b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine// =============================================================================
45b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine// Structures
46b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine// =============================================================================
47b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine
48b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkinestruct HashEntry {
49b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine    size_t slot;
50b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine    HashEntry* prev;
51b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine    HashEntry* next;
52b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine    size_t numEntries;
53b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine    // fields above "size" are NOT sent to the host
54b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine    size_t size;
55b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine    size_t allocations;
56b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine    intptr_t backtrace[0];
57b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine};
58b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine
59b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkinestruct HashTable {
60b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine    size_t count;
61b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine    HashEntry* slots[HASHTABLE_SIZE];
62b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine};
63b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine
64b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine/* Entry in malloc dispatch table. */
65c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughestypedef void* (*MallocDebugMalloc)(size_t);
66c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughestypedef void (*MallocDebugFree)(void*);
67c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughestypedef void* (*MallocDebugCalloc)(size_t, size_t);
68c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughestypedef void* (*MallocDebugRealloc)(void*, size_t);
69c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughestypedef void* (*MallocDebugMemalign)(size_t, size_t);
70b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkinestruct MallocDebug {
71c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes  MallocDebugMalloc malloc;
72c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes  MallocDebugFree free;
73c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes  MallocDebugCalloc calloc;
74c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes  MallocDebugRealloc realloc;
75c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes  MallocDebugMemalign memalign;
76b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine};
77b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine
78e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev/* Malloc debugging initialization and finalization routines.
79e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev *
80e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev * These routines must be implemented in .so modules that implement malloc
81e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev * debugging. The are is called once per process from malloc_init_impl and
82e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev * malloc_fini_impl respectively.
83e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev *
84e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev * They are implemented in bionic/libc/bionic/malloc_debug_common.c when malloc
8575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * debugging gets initialized for the process.
86e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev *
87e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev * MallocDebugInit returns:
88e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev *    0 on success, -1 on failure.
8975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */
90c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughestypedef int (*MallocDebugInit)();
91c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughestypedef void (*MallocDebugFini)();
92e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev
93e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev// =============================================================================
94e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev// log functions
95e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev// =============================================================================
96e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev
97e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev#define debug_log(format, ...)  \
98e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev    __libc_android_log_print(ANDROID_LOG_DEBUG, "malloc_leak_check", (format), ##__VA_ARGS__ )
99e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev#define error_log(format, ...)  \
100e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev    __libc_android_log_print(ANDROID_LOG_ERROR, "malloc_leak_check", (format), ##__VA_ARGS__ )
101e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev#define info_log(format, ...)  \
102e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev    __libc_android_log_print(ANDROID_LOG_INFO, "malloc_leak_check", (format), ##__VA_ARGS__ )
10375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine
104c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesclass ScopedPthreadMutexLocker {
105c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes public:
106c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes  explicit ScopedPthreadMutexLocker(pthread_mutex_t* mu) : mu_(mu) {
107c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes    pthread_mutex_lock(mu_);
108c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes  }
109c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes
110c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes  ~ScopedPthreadMutexLocker() {
111c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes    pthread_mutex_unlock(mu_);
112c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes  }
113c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes
114c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes private:
115c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes  pthread_mutex_t* mu_;
116c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes};
117b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine
118b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#endif  // MALLOC_DEBUG_COMMON_H
119