@cryptotaxi247 / netdata-1 / commits / eaa5b0f47

added memory debug to apps.plugin

box@home root committed Mar 29, 2015 at 21:39 UTC eaa5b0f47e73b040c2a6653afea866ebce008215
2 files changed +152
src/log.h
+1
@@ -23,6 +23,7 @@
23 #define D_PROCFILE 0x00010000
24 #define D_RRD_CALLS 0x00020000
25 #define D_DICTIONARY 0x00040000
26 +#define D_MEMORY 0x00080000
27
28 #define DEBUG (D_WEB_CLIENT_ACCESS|D_LISTENER|D_RRD_STATS)
29 //#define DEBUG 0xffffffff
src/plugins.d/apps_plugin.c
+151
@@ -43,6 +43,156 @@ unsigned long long file_counter = 0;
43
44 #define PROC_BUFFER 4096
45
46 +// ----------------------------------------------------------------------------
47 +// memory debugger
48 +
49 +struct allocations {
50 + size_t allocations;
51 + size_t allocated;
52 + size_t allocated_max;
53 +} allocations = { 0, 0, 0 };
54 +
55 +#define MALLOC_MARK (size_t)(0x0BADCAFE)
56 +#define MALLOC_PREFIX (sizeof(size_t) * 2)
57 +#define MALLOC_SUFFIX (sizeof(size_t))
58 +#define MALLOC_OVERHEAD (MALLOC_PREFIX + MALLOC_SUFFIX)
59 +
60 +void *mark_allocation(void *allocated_ptr, size_t size_without_overheads) {
61 + size_t *real_ptr = (size_t *)allocated_ptr;
62 + real_ptr[0] = MALLOC_MARK;
63 + real_ptr[1] = size_without_overheads;
64 +
65 + size_t *end_ptr = (size_t *)(allocated_ptr + MALLOC_PREFIX + size_without_overheads);
66 + end_ptr[0] = MALLOC_MARK;
67 +
68 + // fprintf(stderr, "MEMORY_POINTER: Allocated at %p, returning %p.\n", allocated_ptr, (void *)(allocated_ptr + MALLOC_PREFIX));
69 +
70 + return (void *)(allocated_ptr + MALLOC_PREFIX);
71 +}
72 +
73 +void *check_allocation(const char *file, int line, const char *function, void *marked_ptr, size_t *size_without_overheads_ptr) {
74 + size_t *real_ptr = (size_t *)(marked_ptr - MALLOC_PREFIX);
75 +
76 + // fprintf(stderr, "MEMORY_POINTER: Checking pointer at %p, real %p for %s/%u@%s.\n", marked_ptr, (void *)(marked_ptr - MALLOC_PREFIX), function, line, file);
77 +
78 + if(real_ptr[0] != MALLOC_MARK) fatal("MEMORY: prefix MARK is not valid for %s/%u@%s.", function, line, file);
79 +
80 + size_t size = real_ptr[1];
81 +
82 + size_t *end_ptr = (size_t *)(marked_ptr + size);
83 + if(end_ptr[0] != MALLOC_MARK) fatal("MEMORY: suffix MARK of allocation with size %zu is not valid for %s/%u@%s.", size, function, line, file);
84 +
85 + if(size_without_overheads_ptr) *size_without_overheads_ptr = size;
86 +
87 + return real_ptr;
88 +}
89 +
90 +void *malloc_debug(const char *file, int line, const char *function, size_t size) {
91 + void *ptr = malloc(size + MALLOC_OVERHEAD);
92 + if(!ptr) fatal("MEMORY: Cannot allocate %zu bytes for %s/%u@%s.", size, function, line, file);
93 +
94 + allocations.allocated += size;
95 + allocations.allocations++;
96 +
97 + debug(D_MEMORY, "MEMORY: Allocated %zu bytes for %s/%u@%s."
98 + " Status: allocated %zu in %zu allocs."
99 + , size
100 + , function, line, file
101 + , allocations.allocated
102 + , allocations.allocations
103 + );
104 +
105 + if(allocations.allocated > allocations.allocated_max) {
106 + debug(D_MEMORY, "MEMORY: total allocation peak increased from %zu to %zu", allocations.allocated_max, allocations.allocated);
107 + allocations.allocated_max = allocations.allocated;
108 + }
109 +
110 + size_t csize;
111 + check_allocation(file, line, function, mark_allocation(ptr, size), &csize);
112 + if(size != csize) {
113 + fatal("Invalid size.");
114 + }
115 +
116 + return mark_allocation(ptr, size);
117 +}
118 +
119 +void *calloc_debug(const char *file, int line, const char *function, size_t nmemb, size_t size) {
120 + void *ptr = malloc_debug(file, line, function, (nmemb * size));
121 + bzero(ptr, nmemb * size);
122 + return ptr;
123 +}
124 +
125 +void free_debug(const char *file, int line, const char *function, void *ptr) {
126 + size_t size;
127 + void *real_ptr = check_allocation(file, line, function, ptr, &size);
128 +
129 + bzero(real_ptr, size + MALLOC_OVERHEAD);
130 +
131 + free(real_ptr);
132 + allocations.allocated -= size;
133 + allocations.allocations--;
134 +
135 + debug(D_MEMORY, "MEMORY: freed %zu bytes for %s/%u@%s."
136 + " Status: allocated %zu in %zu allocs."
137 + , size
138 + , function, line, file
139 + , allocations.allocated
140 + , allocations.allocations
141 + );
142 +}
143 +
144 +void *realloc_debug(const char *file, int line, const char *function, void *ptr, size_t size) {
145 + if(!ptr) return malloc_debug(file, line, function, size);
146 + if(!size) { free_debug(file, line, function, ptr); return NULL; }
147 +
148 + size_t old_size;
149 + void *real_ptr = check_allocation(file, line, function, ptr, &old_size);
150 +
151 + void *new_ptr = realloc(real_ptr, size + MALLOC_OVERHEAD);
152 + if(!new_ptr) fatal("MEMORY: Cannot allocate %zu bytes for %s/%u@%s.", size, function, line, file);
153 +
154 + allocations.allocated += size;
155 + allocations.allocated -= old_size;
156 +
157 + debug(D_MEMORY, "MEMORY: Re-allocated from %zu to %zu bytes for %s/%u@%s."
158 + " Status: allocated %z in %zu allocs."
159 + , old_size, size
160 + , function, line, file
161 + , allocations.allocated
162 + , allocations.allocations
163 + );
164 +
165 + if(allocations.allocated > allocations.allocated_max) {
166 + debug(D_MEMORY, "MEMORY: total allocation peak increased from %zu to %zu", allocations.allocated_max, allocations.allocated);
167 + allocations.allocated_max = allocations.allocated;
168 + }
169 +
170 + return mark_allocation(new_ptr, size);
171 +}
172 +
173 +char *strdup_debug(const char *file, int line, const char *function, const char *ptr) {
174 + size_t size = 0;
175 + const char *s = ptr;
176 +
177 + while(*s++) size++;
178 + size++;
179 +
180 + char *p = malloc_debug(file, line, function, size);
181 + if(!p) fatal("Cannot allocate %zu bytes.", size);
182 +
183 + memcpy(p, ptr, size);
184 + return p;
185 +}
186 +
187 +#define malloc(size) malloc_debug(__FILE__, __LINE__, __FUNCTION__, (size))
188 +#define calloc(nmemb, size) calloc_debug(__FILE__, __LINE__, __FUNCTION__, (nmemb), (size))
189 +#define realloc(ptr, size) realloc_debug(__FILE__, __LINE__, __FUNCTION__, (ptr), (size))
190 +#define free(ptr) free_debug(__FILE__, __LINE__, __FUNCTION__, (ptr))
191 +
192 +#ifdef strdup
193 +#undef strdup
194 +#endif
195 +#define strdup(ptr) strdup_debug(__FILE__, __LINE__, __FUNCTION__, (ptr))
196
197 // ----------------------------------------------------------------------------
198 // helper functions
@@ -1692,6 +1842,7 @@ void parse_args(int argc, char **argv)
1842
1843 if(strcmp("debug", argv[i]) == 0) {
1844 debug = 1;
1845 + debug_flags = 0xffffffff;
1846 continue;
1847 }
1848