osMemory.c 4.4 KB
Newer Older
wafwerar's avatar
wafwerar 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#define ALLOW_FORBID_FUNC
wafwerar's avatar
wafwerar 已提交
17
#include <malloc.h>
wafwerar's avatar
wafwerar 已提交
18 19
#include "os.h"

wafwerar's avatar
wafwerar 已提交
20 21
#ifdef USE_TD_MEMORY

wafwerar's avatar
wafwerar 已提交
22 23
#define TD_MEMORY_SYMBOL ('T'<<24|'A'<<16|'O'<<8|'S')

24
#define TD_MEMORY_STACK_TRACE_DEPTH 10
wafwerar's avatar
wafwerar 已提交
25

H
Haojun Liao 已提交
26
typedef struct TdMemoryInfo {
wafwerar's avatar
wafwerar 已提交
27
  int32_t symbol;
H
Haojun Liao 已提交
28
  int32_t memorySize;
29
  void *stackTrace[TD_MEMORY_STACK_TRACE_DEPTH];     // gdb: disassemble /m 0xXXX
wafwerar's avatar
wafwerar 已提交
30 31 32 33 34 35 36
} *TdMemoryInfoPtr , TdMemoryInfo;

#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)

#else

#include<execinfo.h>
wafwerar's avatar
wafwerar 已提交
37

wafwerar's avatar
wafwerar 已提交
38
#define STACKCALL __attribute__((regparm(1), noinline))
39
void **STACKCALL taosGetEbp(void) {
wafwerar's avatar
wafwerar 已提交
40 41 42 43 44 45 46
  void **ebp = NULL;
  __asm__ __volatile__("mov %%rbp, %0;\n\t"
                       : "=m"(ebp)  /* output */
                       :            /* input */
                       : "memory"); /* not affect register */
  return (void **)(*ebp);
}
wafwerar's avatar
wafwerar 已提交
47

wafwerar's avatar
wafwerar 已提交
48 49 50 51
int32_t taosBackTrace(void **buffer, int32_t size) {
  int32_t frame = 0;
  void **ebp;
  void **ret = NULL;
wafwerar's avatar
wafwerar 已提交
52
  size_t func_frame_distance = 0;
wafwerar's avatar
wafwerar 已提交
53
  if (buffer != NULL && size > 0) {
54
    ebp = taosGetEbp();
wafwerar's avatar
wafwerar 已提交
55
    func_frame_distance = (size_t)*ebp - (size_t)ebp;
wafwerar's avatar
wafwerar 已提交
56 57 58 59 60
    while (ebp && frame < size && (func_frame_distance < (1ULL << 24))  // assume function ebp more than 16M
           && (func_frame_distance > 0)) {
      ret = ebp + 1;
      buffer[frame++] = *ret;
      ebp = (void **)(*ebp);
wafwerar's avatar
wafwerar 已提交
61
      func_frame_distance = (size_t)*ebp - (size_t)ebp;
wafwerar's avatar
wafwerar 已提交
62 63 64 65
    }
  }
  return frame;
}
wafwerar's avatar
wafwerar 已提交
66

wafwerar's avatar
wafwerar 已提交
67 68
#endif

69 70 71 72 73
// char **taosBackTraceSymbols(int32_t *size) {
//   void  *buffer[20] = {NULL};
//   *size = taosBackTrace(buffer, 20);
//   return backtrace_symbols(buffer, *size);
// }
wafwerar's avatar
wafwerar 已提交
74

wafwerar's avatar
wafwerar 已提交
75 76
#endif

wafwerar's avatar
wafwerar 已提交
77
void *taosMemoryMalloc(int32_t size) {
wafwerar's avatar
wafwerar 已提交
78
#ifdef USE_TD_MEMORY
wafwerar's avatar
wafwerar 已提交
79
  void *tmp = malloc(size + sizeof(TdMemoryInfo));
wafwerar's avatar
wafwerar 已提交
80 81 82 83 84
  if (tmp == NULL) return NULL;

  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)tmp;
  pTdMemoryInfo->memorySize = size;
  pTdMemoryInfo->symbol = TD_MEMORY_SYMBOL;
85
  taosBackTrace(pTdMemoryInfo->stackTrace,TD_MEMORY_STACK_TRACE_DEPTH);
wafwerar's avatar
wafwerar 已提交
86 87

  return (char*)tmp  + sizeof(TdMemoryInfo);
wafwerar's avatar
wafwerar 已提交
88 89 90
#else
  return malloc(size);
#endif
wafwerar's avatar
wafwerar 已提交
91 92 93
}

void *taosMemoryCalloc(int32_t num, int32_t size) {
wafwerar's avatar
wafwerar 已提交
94
#ifdef USE_TD_MEMORY
wafwerar's avatar
wafwerar 已提交
95 96 97 98 99 100 101
  int32_t memorySize = num * size;
  char *tmp = calloc(memorySize + sizeof(TdMemoryInfo), 1);
  if (tmp == NULL) return NULL;

  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)tmp;
  pTdMemoryInfo->memorySize = memorySize;
  pTdMemoryInfo->symbol = TD_MEMORY_SYMBOL;
102
  taosBackTrace(pTdMemoryInfo->stackTrace,TD_MEMORY_STACK_TRACE_DEPTH);
wafwerar's avatar
wafwerar 已提交
103 104

  return (char*)tmp  + sizeof(TdMemoryInfo);
wafwerar's avatar
wafwerar 已提交
105 106 107
#else
  return calloc(num, size);
#endif
wafwerar's avatar
wafwerar 已提交
108 109 110
}

void *taosMemoryRealloc(void *ptr, int32_t size) {
wafwerar's avatar
wafwerar 已提交
111
#ifdef USE_TD_MEMORY
wafwerar's avatar
wafwerar 已提交
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
  if (ptr == NULL) return taosMemoryMalloc(size);
  
  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)((char*)ptr - sizeof(TdMemoryInfo));
  assert(pTdMemoryInfo->symbol == TD_MEMORY_SYMBOL);

  TdMemoryInfo tdMemoryInfo;
  memcpy(&tdMemoryInfo, pTdMemoryInfo, sizeof(TdMemoryInfo));

  void *tmp = realloc(pTdMemoryInfo, size + sizeof(TdMemoryInfo));
  if (tmp == NULL) return NULL;
  
  memcpy(tmp, &tdMemoryInfo, sizeof(TdMemoryInfo));
  ((TdMemoryInfoPtr)tmp)->memorySize = size;

  return (char*)tmp  + sizeof(TdMemoryInfo);
wafwerar's avatar
wafwerar 已提交
127 128 129
#else
  return realloc(ptr, size);
#endif
wafwerar's avatar
wafwerar 已提交
130 131 132 133 134
}

void taosMemoryFree(const void *ptr) {
  if (ptr == NULL) return;

wafwerar's avatar
wafwerar 已提交
135
#ifdef USE_TD_MEMORY
wafwerar's avatar
wafwerar 已提交
136 137
  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)((char*)ptr - sizeof(TdMemoryInfo));
  if(pTdMemoryInfo->symbol == TD_MEMORY_SYMBOL) {
wafwerar's avatar
wafwerar 已提交
138 139
    pTdMemoryInfo->memorySize = 0;
    // memset(pTdMemoryInfo, 0, sizeof(TdMemoryInfo));
wafwerar's avatar
wafwerar 已提交
140 141 142 143
    free(pTdMemoryInfo);
  } else {
    free((void*)ptr);
  }
wafwerar's avatar
wafwerar 已提交
144 145 146
#else
  return free((void*)ptr);
#endif
wafwerar's avatar
wafwerar 已提交
147 148 149 150
}

int32_t taosMemorySize(void *ptr) {
  if (ptr == NULL) return 0;
wafwerar's avatar
wafwerar 已提交
151 152

#ifdef USE_TD_MEMORY
wafwerar's avatar
wafwerar 已提交
153 154 155 156
  TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)((char*)ptr - sizeof(TdMemoryInfo));
  assert(pTdMemoryInfo->symbol == TD_MEMORY_SYMBOL);

  return pTdMemoryInfo->memorySize;
wafwerar's avatar
wafwerar 已提交
157 158 159
#else
  return malloc_usable_size(ptr);
#endif
L
Liu Jicong 已提交
160
}