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