… | |
… | |
48 | #include <arpa/inet.h> |
48 | #include <arpa/inet.h> |
49 | static int debug_socket=-1; |
49 | static int debug_socket=-1; |
50 | static struct sockaddr_in debug_sin; |
50 | static struct sockaddr_in debug_sin; |
51 | #endif |
51 | #endif |
52 | |
52 | |
53 | |
|
|
54 | int debug_level=0; |
53 | int debug_level = 0; |
55 | int segv_level=0; |
54 | int segv_level = 0; |
56 | int timestamp_prefix=0; |
55 | int timestamp_prefix = 0; |
57 | |
56 | |
58 | static int dummy; |
57 | static int dummy; |
59 | static GHashTable *debug_hash; |
58 | static GHashTable *debug_hash; |
60 | static gchar *gdb_program; |
59 | static gchar *gdb_program; |
61 | |
60 | |
… | |
… | |
79 | system(buffer); |
78 | system(buffer); |
80 | exit(1); |
79 | exit(1); |
81 | } |
80 | } |
82 | #endif |
81 | #endif |
83 | |
82 | |
84 | void |
|
|
85 | debug_init(const char *program_name) |
83 | void debug_init(const char *program_name) |
86 | { |
84 | { |
87 | gdb_program=g_strdup(program_name); |
85 | gdb_program = g_strdup(program_name); |
88 | signal(SIGSEGV, sigsegv); |
86 | signal(SIGSEGV, sigsegv); |
89 | debug_hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); |
87 | debug_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free_func, NULL); |
90 | debug_fp = stderr; |
88 | debug_fp = stderr; |
91 | } |
89 | } |
92 | |
90 | |
93 | |
|
|
94 | static void |
|
|
95 | debug_update_level(gpointer key, gpointer value, gpointer user_data) |
91 | static void debug_update_level(gpointer key, gpointer value, gpointer user_data) |
96 | { |
92 | { |
97 | if (debug_level < GPOINTER_TO_INT(value)) |
93 | if (debug_level < GPOINTER_TO_INT(value)) |
98 | debug_level = GPOINTER_TO_INT(value); |
94 | debug_level = GPOINTER_TO_INT(value); |
99 | } |
95 | } |
100 | |
96 | |
101 | void |
|
|
102 | debug_level_set(const char *name, int level) |
97 | void debug_level_set(const char *name, int level) |
103 | { |
98 | { |
104 | if (!strcmp(name, "segv")) { |
99 | if (!strcmp(name, "segv")) |
|
|
100 | { |
105 | segv_level=level; |
101 | segv_level = level; |
106 | if (segv_level) |
102 | if (segv_level) |
107 | signal(SIGSEGV, sigsegv); |
103 | signal(SIGSEGV, sigsegv); |
108 | else |
104 | else |
109 | signal(SIGSEGV, NULL); |
105 | signal(SIGSEGV, NULL); |
|
|
106 | } |
110 | } else if (!strcmp(name, "timestamps")) { |
107 | else if (!strcmp(name, "timestamps")) |
|
|
108 | { |
111 | timestamp_prefix=level; |
109 | timestamp_prefix = level; |
112 | } else { |
110 | } |
|
|
111 | else |
|
|
112 | { |
113 | debug_level=0; |
113 | debug_level = 0; |
114 | g_hash_table_insert(debug_hash, g_strdup(name), GINT_TO_POINTER(level)); |
114 | g_hash_table_insert(debug_hash, g_strdup(name), GINT_TO_POINTER(level)); |
115 | g_hash_table_foreach(debug_hash, debug_update_level, NULL); |
115 | g_hash_table_foreach(debug_hash, debug_update_level, NULL); |
116 | } |
116 | } |
117 | } |
117 | } |
118 | |
118 | |
119 | struct debug * |
119 | struct debug * |
120 | debug_new(struct attr *parent, struct attr **attrs) |
120 | debug_new(struct attr *parent, struct attr **attrs) |
121 | { |
121 | { |
122 | struct attr *name,*level; |
122 | struct attr *name, *level; |
123 | name=attr_search(attrs, NULL, attr_name); |
123 | name = attr_search(attrs, NULL, attr_name); |
124 | level=attr_search(attrs, NULL, attr_level); |
124 | level = attr_search(attrs, NULL, attr_level); |
125 | #ifdef HAVE_SOCKET |
125 | #ifdef HAVE_SOCKET |
126 | if (!name && !level) { |
126 | if (!name && !level) |
|
|
127 | { |
127 | struct attr *socket_attr=attr_search(attrs, NULL, attr_socket); |
128 | struct attr *socket_attr=attr_search(attrs, NULL, attr_socket); |
128 | char *p,*s; |
129 | char *p,*s; |
129 | if (!socket_attr) |
130 | if (!socket_attr) |
130 | return NULL; |
131 | return NULL; |
131 | s=g_strdup(socket_attr->u.str); |
132 | s=g_strdup(socket_attr->u.str); |
132 | p=strchr(s,':'); |
133 | p=strchr(s,':'); |
133 | if (!p) { |
134 | if (!p) |
|
|
135 | { |
134 | g_free(s); |
136 | g_free(s); |
135 | return NULL; |
137 | return NULL; |
136 | } |
138 | } |
137 | *p++='\0'; |
139 | *p++='\0'; |
138 | debug_sin.sin_family=AF_INET; |
140 | debug_sin.sin_family=AF_INET; |
139 | if (!inet_aton(s, &debug_sin.sin_addr)) { |
141 | if (!inet_aton(s, &debug_sin.sin_addr)) |
|
|
142 | { |
140 | g_free(s); |
143 | g_free(s); |
141 | return NULL; |
144 | return NULL; |
142 | } |
145 | } |
143 | debug_sin.sin_port=ntohs(atoi(p)); |
146 | debug_sin.sin_port=ntohs(atoi(p)); |
144 | if (debug_socket == -1) |
147 | if (debug_socket == -1) |
145 | debug_socket=socket(PF_INET, SOCK_DGRAM, 0); |
148 | debug_socket=socket(PF_INET, SOCK_DGRAM, 0); |
146 | g_free(s); |
149 | g_free(s); |
147 | return (struct debug *)&dummy; |
150 | return (struct debug *)&dummy; |
148 | } |
151 | } |
149 | #endif |
152 | #endif |
150 | if (!name || !level) |
153 | if (!name || !level) |
151 | return NULL; |
154 | return NULL; |
152 | debug_level_set(name->u.str, level->u.num); |
155 | debug_level_set(name->u.str, level->u.num); |
153 | return (struct debug *)&dummy; |
156 | return (struct debug *) &dummy; |
154 | } |
157 | } |
155 | |
158 | |
156 | |
|
|
157 | int |
|
|
158 | debug_level_get(const char *name) |
159 | int debug_level_get(const char *name) |
159 | { |
160 | { |
160 | if (!debug_hash) |
161 | if (!debug_hash) |
161 | return 0; |
162 | return 0; |
162 | return GPOINTER_TO_INT(g_hash_table_lookup(debug_hash, name)); |
163 | return GPOINTER_TO_INT(g_hash_table_lookup(debug_hash, name)); |
163 | } |
164 | } |
… | |
… | |
177 | struct timeval tv; |
178 | struct timeval tv; |
178 | |
179 | |
179 | if (gettimeofday(&tv, NULL) == -1) |
180 | if (gettimeofday(&tv, NULL) == -1) |
180 | return; |
181 | return; |
181 | /* Timestamps are UTC */ |
182 | /* Timestamps are UTC */ |
182 | sprintf(buffer, |
183 | sprintf(buffer, "%02d:%02d:%02d.%03d|", (int) (tv.tv_sec / 3600) % 24, (int) (tv.tv_sec / 60) % 60, (int) tv.tv_sec % 60, (int) tv.tv_usec / 1000); |
183 | "%02d:%02d:%02d.%03d|", |
|
|
184 | (int)(tv.tv_sec/3600)%24, |
|
|
185 | (int)(tv.tv_sec/60)%60, |
|
|
186 | (int)tv.tv_sec % 60, |
|
|
187 | (int)tv.tv_usec/1000); |
|
|
188 | #endif |
184 | #endif |
189 | } |
185 | } |
190 | |
186 | |
191 | void |
|
|
192 | debug_vprintf(int level, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, va_list ap) |
187 | void debug_vprintf(int level, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, va_list ap) |
193 | { |
188 | { |
194 | #if defined HAVE_API_WIN32_CE || defined _MSC_VER |
189 | #if defined HAVE_API_WIN32_CE || defined _MSC_VER |
195 | char buffer[4096]; |
190 | char buffer[4096]; |
196 | #else |
191 | #else |
197 | char buffer[mlen+flen+3]; |
192 | char buffer[mlen + flen + 3]; |
198 | #endif |
193 | #endif |
199 | FILE *fp=debug_fp; |
194 | FILE *fp = debug_fp; |
200 | |
195 | |
201 | sprintf(buffer, "%s:%s", module, function); |
196 | sprintf(buffer, "%s:%s", module, function); |
202 | if (debug_level_get(module) >= level || debug_level_get(buffer) >= level) { |
197 | if (debug_level_get(module) >= level || debug_level_get(buffer) >= level) |
|
|
198 | { |
203 | #if defined(DEBUG_WIN32_CE_MESSAGEBOX) |
199 | #if defined(DEBUG_WIN32_CE_MESSAGEBOX) |
204 | wchar_t muni[4096]; |
200 | wchar_t muni[4096]; |
205 | #endif |
201 | #endif |
206 | char xbuffer[4096]; |
202 | char xbuffer[4096]; |
207 | xbuffer[0]='\0'; |
203 | xbuffer[0] = '\0'; |
208 | if (prefix) { |
204 | if (prefix) |
|
|
205 | { |
209 | if (timestamp_prefix) |
206 | if (timestamp_prefix) |
210 | debug_timestamp(xbuffer); |
207 | debug_timestamp(xbuffer); |
211 | strcpy(xbuffer+strlen(xbuffer),buffer); |
208 | strcpy(xbuffer + strlen(xbuffer), buffer); |
212 | strcpy(xbuffer+strlen(xbuffer),":"); |
209 | strcpy(xbuffer + strlen(xbuffer), ":"); |
213 | } |
210 | } |
214 | vsprintf(xbuffer+strlen(xbuffer),fmt,ap); |
211 | vsprintf(xbuffer + strlen(xbuffer), fmt, ap); |
215 | #ifdef DEBUG_WIN32_CE_MESSAGEBOX |
212 | #ifdef DEBUG_WIN32_CE_MESSAGEBOX |
216 | mbstowcs(muni, xbuffer, strlen(xbuffer)+1); |
213 | mbstowcs(muni, xbuffer, strlen(xbuffer)+1); |
217 | MessageBoxW(NULL, muni, TEXT("Navit - Error"), MB_APPLMODAL|MB_OK|MB_ICONERROR); |
214 | MessageBoxW(NULL, muni, TEXT("Navit - Error"), MB_APPLMODAL|MB_OK|MB_ICONERROR); |
218 | #else |
215 | #else |
219 | #ifdef HAVE_API_ANDROID |
216 | #ifdef HAVE_API_ANDROID |
|
|
217 | /* |
|
|
218 | * Android log priority values, in ascending priority order. |
|
|
219 | */ |
|
|
220 | /* |
|
|
221 | typedef enum android_LogPriority |
|
|
222 | { |
|
|
223 | ANDROID_LOG_UNKNOWN = 0, |
|
|
224 | ANDROID_LOG_DEFAULT, // only for SetMinPriority() |
|
|
225 | ANDROID_LOG_VERBOSE, |
|
|
226 | ANDROID_LOG_DEBUG, |
|
|
227 | ANDROID_LOG_INFO, |
|
|
228 | ANDROID_LOG_WARN, |
|
|
229 | ANDROID_LOG_ERROR, |
|
|
230 | ANDROID_LOG_FATAL, |
|
|
231 | ANDROID_LOG_SILENT, // only for SetMinPriority(); must be last |
|
|
232 | } android_LogPriority; |
|
|
233 | */ |
|
|
234 | |
220 | __android_log_print(ANDROID_LOG_ERROR,"navit", "%s", xbuffer); |
235 | __android_log_print(ANDROID_LOG_DEBUG,"navit", "%s", xbuffer); |
221 | #else |
236 | #else |
222 | #ifdef HAVE_SOCKET |
237 | #ifdef HAVE_SOCKET |
223 | if (debug_socket != -1) { |
238 | if (debug_socket != -1) |
|
|
239 | { |
224 | sendto(debug_socket, xbuffer, strlen(xbuffer), 0, (struct sockaddr *)&debug_sin, sizeof(debug_sin)); |
240 | sendto(debug_socket, xbuffer, strlen(xbuffer), 0, (struct sockaddr *)&debug_sin, sizeof(debug_sin)); |
225 | return; |
241 | return; |
226 | } |
242 | } |
227 | #endif |
243 | #endif |
228 | if (! fp) |
244 | if (!fp) |
229 | fp = stderr; |
245 | fp = stderr; |
230 | fprintf(fp,"%s",xbuffer); |
246 | fprintf(fp, "%s", xbuffer); |
231 | fflush(fp); |
247 | fflush(fp); |
232 | #endif |
248 | #endif |
233 | #endif |
249 | #endif |
234 | } |
250 | } |
235 | } |
251 | } |
236 | |
252 | |
237 | void |
|
|
238 | debug_printf(int level, const char *module, const int mlen,const char *function, const int flen, int prefix, const char *fmt, ...) |
253 | void debug_printf(int level, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, ...) |
239 | { |
254 | { |
240 | #ifdef _DEBUG_BUILD_ |
255 | #ifdef _DEBUG_BUILD_ |
241 | va_list ap; |
256 | va_list ap; |
242 | va_start(ap, fmt); |
257 | va_start(ap, fmt); |
243 | debug_vprintf(level, module, mlen, function, flen, prefix, fmt, ap); |
258 | debug_vprintf(level, module, mlen, function, flen, prefix, fmt, ap); |
244 | va_end(ap); |
259 | va_end(ap); |
245 | #endif |
260 | #endif |
246 | } |
261 | } |
247 | |
262 | |
248 | void |
|
|
249 | debug_printf2(int level, const char *module, const int mlen,const char *function, const int flen, int prefix, const char *fmt, ...) |
263 | void debug_printf2(int level, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, ...) |
250 | { |
264 | { |
251 | va_list ap; |
265 | va_list ap; |
252 | va_start(ap, fmt); |
266 | va_start(ap, fmt); |
253 | debug_vprintf(level, module, mlen, function, flen, prefix, fmt, ap); |
267 | debug_vprintf(level, module, mlen, function, flen, prefix, fmt, ap); |
254 | va_end(ap); |
268 | va_end(ap); |
255 | } |
269 | } |
256 | |
270 | |
257 | void |
|
|
258 | debug_assert_fail(const char *module, const int mlen,const char *function, const int flen, const char *file, int line, const char *expr) |
271 | void debug_assert_fail(const char *module, const int mlen, const char *function, const int flen, const char *file, int line, const char *expr) |
259 | { |
272 | { |
260 | debug_printf2(0,module,mlen,function,flen,1,"%s:%d assertion failed:%s\n", file, line, expr); |
273 | debug_printf2(0, module, mlen, function, flen, 1, "%s:%d assertion failed:%s\n", file, line, expr); |
261 | abort(); |
274 | abort(); |
262 | } |
275 | } |
263 | |
276 | |
264 | void |
|
|
265 | debug_destroy(void) |
277 | void debug_destroy(void) |
266 | { |
278 | { |
267 | if (!debug_fp) |
279 | if (!debug_fp) |
268 | return; |
280 | return; |
269 | if (debug_fp == stderr || debug_fp == stdout) |
281 | if (debug_fp == stderr || debug_fp == stdout) |
270 | return; |
282 | return; |
… | |
… | |
274 | |
286 | |
275 | void debug_set_logfile(const char *path) |
287 | void debug_set_logfile(const char *path) |
276 | { |
288 | { |
277 | FILE *fp; |
289 | FILE *fp; |
278 | fp = fopen(path, "a"); |
290 | fp = fopen(path, "a"); |
279 | if (fp) { |
291 | if (fp) |
|
|
292 | { |
280 | debug_destroy(); |
293 | debug_destroy(); |
281 | debug_fp = fp; |
294 | debug_fp = fp; |
282 | fprintf(debug_fp, "Navit log started\n"); |
295 | fprintf(debug_fp, "Navit log started\n"); |
283 | fflush(debug_fp); |
296 | fflush(debug_fp); |
284 | } |
297 | } |
285 | } |
298 | } |
286 | |
299 | |
287 | struct malloc_head { |
300 | struct malloc_head |
|
|
301 | { |
288 | int magic; |
302 | int magic; |
289 | int size; |
303 | int size; |
290 | char *where; |
304 | char *where; |
291 | void *return_address[8]; |
305 | void *return_address[8]; |
292 | struct malloc_head *prev; |
306 | struct malloc_head *prev; |
293 | struct malloc_head *next; |
307 | struct malloc_head *next; |
294 | } *malloc_heads; |
308 | }*malloc_heads; |
295 | |
309 | |
296 | struct malloc_tail { |
310 | struct malloc_tail |
|
|
311 | { |
297 | int magic; |
312 | int magic; |
298 | }; |
313 | }; |
299 | |
314 | |
300 | int mallocs,malloc_size,malloc_size_m; |
315 | int mallocs, malloc_size, malloc_size_m; |
301 | |
316 | |
302 | void |
|
|
303 | debug_dump_mallocs(void) |
317 | void debug_dump_mallocs(void) |
304 | { |
318 | { |
305 | struct malloc_head *head=malloc_heads; |
319 | struct malloc_head *head = malloc_heads; |
306 | int i; |
320 | int i; |
307 | dbg(0,"mallocs %d\n",mallocs); |
321 | dbg(0, "mallocs %d\n", mallocs); |
308 | while (head) { |
322 | while (head) |
|
|
323 | { |
309 | fprintf(stderr,"unfreed malloc from %s of size %d\n",head->where,head->size); |
324 | fprintf(stderr, "unfreed malloc from %s of size %d\n", head->where, head->size); |
310 | for (i = 0 ; i < 8 ; i++) |
325 | for (i = 0; i < 8; i++) |
311 | fprintf(stderr,"\tlist *%p\n",head->return_address[i]); |
326 | fprintf(stderr, "\tlist *%p\n", head->return_address[i]); |
312 | #if 0 |
327 | #if 0 |
313 | fprintf(stderr,"%s\n",head+1); |
328 | fprintf(stderr,"%s\n",head+1); |
314 | #endif |
329 | #endif |
315 | head=head->next; |
330 | head = head->next; |
316 | } |
331 | } |
317 | } |
332 | } |
318 | |
333 | |
319 | void * |
334 | void * |
320 | debug_malloc(const char *where, int line, const char *func, int size) |
335 | debug_malloc(const char *where, int line, const char *func, int size) |
… | |
… | |
322 | struct malloc_head *head; |
337 | struct malloc_head *head; |
323 | struct malloc_tail *tail; |
338 | struct malloc_tail *tail; |
324 | if (!size) |
339 | if (!size) |
325 | return NULL; |
340 | return NULL; |
326 | mallocs++; |
341 | mallocs++; |
327 | malloc_size+=size; |
342 | malloc_size += size; |
328 | if (malloc_size/(1024*1024) != malloc_size_m) { |
343 | if (malloc_size / (1024 * 1024) != malloc_size_m) |
|
|
344 | { |
329 | malloc_size_m=malloc_size/(1024*1024); |
345 | malloc_size_m = malloc_size / (1024 * 1024); |
330 | dbg(0,"malloced %d kb\n",malloc_size/1024); |
346 | dbg(0, "malloced %d kb\n", malloc_size / 1024); |
331 | } |
347 | } |
332 | head=malloc(size+sizeof(*head)+sizeof(*tail)); |
348 | head = malloc(size + sizeof(*head) + sizeof(*tail)); |
333 | head->magic=0xdeadbeef; |
349 | head->magic = 0xdeadbeef; |
334 | head->size=size; |
350 | head->size = size; |
335 | head->prev=NULL; |
351 | head->prev = NULL; |
336 | head->next=malloc_heads; |
352 | head->next = malloc_heads; |
337 | malloc_heads=head; |
353 | malloc_heads = head; |
338 | if (head->next) |
354 | if (head->next) |
339 | head->next->prev=head; |
355 | head->next->prev = head; |
340 | head->where=g_strdup_printf("%s:%d %s",where,line,func); |
356 | head->where = g_strdup_printf("%s:%d %s", where, line, func); |
341 | #if !defined (__GNUC__) |
357 | #if !defined (__GNUC__) |
342 | #define __builtin_return_address(x) NULL |
358 | #define __builtin_return_address(x) NULL |
343 | #endif |
359 | #endif |
344 | head->return_address[0]=__builtin_return_address(0); |
360 | head->return_address[0] = __builtin_return_address(0); |
345 | head->return_address[1]=__builtin_return_address(1); |
361 | head->return_address[1] = __builtin_return_address(1); |
346 | head->return_address[2]=__builtin_return_address(2); |
362 | head->return_address[2] = __builtin_return_address(2); |
347 | head->return_address[3]=__builtin_return_address(3); |
363 | head->return_address[3] = __builtin_return_address(3); |
348 | head->return_address[4]=__builtin_return_address(4); |
364 | head->return_address[4] = __builtin_return_address(4); |
349 | head->return_address[5]=__builtin_return_address(5); |
365 | head->return_address[5] = __builtin_return_address(5); |
350 | head->return_address[6]=__builtin_return_address(6); |
366 | head->return_address[6] = __builtin_return_address(6); |
351 | head->return_address[7]=__builtin_return_address(7); |
367 | head->return_address[7] = __builtin_return_address(7); |
352 | head++; |
368 | head++; |
353 | tail=(struct malloc_tail *)((unsigned char *)head+size); |
369 | tail = (struct malloc_tail *) ((unsigned char *) head + size); |
354 | tail->magic=0xdeadbef0; |
370 | tail->magic = 0xdeadbef0; |
355 | return head; |
371 | return head; |
356 | } |
372 | } |
357 | |
|
|
358 | |
373 | |
359 | void * |
374 | void * |
360 | debug_malloc0(const char *where, int line, const char *func, int size) |
375 | debug_malloc0(const char *where, int line, const char *func, int size) |
361 | { |
376 | { |
362 | void *ret=debug_malloc(where, line, func, size); |
377 | void *ret = debug_malloc(where, line, func, size); |
363 | if (ret) |
378 | if (ret) |
364 | memset(ret, 0, size); |
379 | memset(ret, 0, size); |
365 | return ret; |
380 | return ret; |
366 | } |
381 | } |
367 | |
382 | |
368 | void * |
383 | void * |
369 | debug_realloc(const char *where, int line, const char *func, void *ptr, int size) |
384 | debug_realloc(const char *where, int line, const char *func, void *ptr, int size) |
370 | { |
385 | { |
371 | void *ret=debug_malloc(where, line, func, size); |
386 | void *ret = debug_malloc(where, line, func, size); |
372 | if (ret && ptr) |
387 | if (ret && ptr) |
373 | memcpy(ret, ptr, size); |
388 | memcpy(ret, ptr, size); |
374 | debug_free(where, line, func, ptr); |
389 | debug_free(where, line, func, ptr); |
375 | return ret; |
390 | return ret; |
376 | } |
391 | } |
377 | |
392 | |
378 | char * |
393 | char * |
379 | debug_strdup(const char *where, int line, const char *func, const char *ptr) |
394 | debug_strdup(const char *where, int line, const char *func, const char *ptr) |
380 | { |
395 | { |
381 | int size; |
396 | int size; |
382 | char *ret; |
397 | char *ret; |
383 | |
398 | |
384 | if (!ptr) |
399 | if (!ptr) |
385 | return NULL; |
400 | return NULL; |
386 | size=strlen(ptr)+1; |
401 | size = strlen(ptr) + 1; |
387 | ret=debug_malloc(where, line, func, size); |
402 | ret = debug_malloc(where, line, func, size); |
388 | memcpy(ret, ptr, size); |
403 | memcpy(ret, ptr, size); |
389 | return ret; |
404 | return ret; |
390 | } |
405 | } |
391 | |
406 | |
392 | char * |
407 | char * |
393 | debug_guard(const char *where, int line, const char *func, char *str) |
408 | debug_guard(const char *where, int line, const char *func, char *str) |
394 | { |
409 | { |
395 | char *ret=debug_strdup(where, line, func, str); |
410 | char *ret = debug_strdup(where, line, func, str); |
396 | g_free(str); |
411 | g_free(str); |
397 | return ret; |
412 | return ret; |
398 | } |
413 | } |
399 | |
414 | |
400 | void |
|
|
401 | debug_free(const char *where, int line, const char *func, void *ptr) |
415 | void debug_free(const char *where, int line, const char *func, void *ptr) |
402 | { |
416 | { |
403 | struct malloc_head *head; |
417 | struct malloc_head *head; |
404 | struct malloc_tail *tail; |
418 | struct malloc_tail *tail; |
405 | if (!ptr) |
419 | if (!ptr) |
406 | return; |
420 | return; |
407 | mallocs--; |
421 | mallocs--; |
408 | head=(struct malloc_head *)((unsigned char *)ptr-sizeof(*head)); |
422 | head = (struct malloc_head *) ((unsigned char *) ptr - sizeof(*head)); |
409 | tail=(struct malloc_tail *)((unsigned char *)ptr+head->size); |
423 | tail = (struct malloc_tail *) ((unsigned char *) ptr + head->size); |
410 | malloc_size-=head->size; |
424 | malloc_size -= head->size; |
411 | if (head->magic != 0xdeadbeef || tail->magic != 0xdeadbef0) { |
425 | if (head->magic != 0xdeadbeef || tail->magic != 0xdeadbef0) |
|
|
426 | { |
412 | fprintf(stderr,"Invalid free from %s:%d %s\n",where,line,func); |
427 | fprintf(stderr, "Invalid free from %s:%d %s\n", where, line, func); |
413 | } |
428 | } |
414 | head->magic=0; |
429 | head->magic = 0; |
415 | tail->magic=0; |
430 | tail->magic = 0; |
416 | if (head->prev) |
431 | if (head->prev) |
417 | head->prev->next=head->next; |
432 | head->prev->next = head->next; |
418 | else |
433 | else |
419 | malloc_heads=head->next; |
434 | malloc_heads = head->next; |
420 | if (head->next) |
435 | if (head->next) |
421 | head->next->prev=head->prev; |
436 | head->next->prev = head->prev; |
422 | free(head->where); |
437 | free(head->where); |
423 | free(head); |
438 | free(head); |
424 | } |
439 | } |
425 | |
440 | |
426 | void |
|
|
427 | debug_free_func(void *ptr) |
441 | void debug_free_func(void *ptr) |
428 | { |
442 | { |
429 | debug_free("unknown",0,"unknown",ptr); |
443 | debug_free("unknown", 0, "unknown", ptr); |
430 | } |
444 | } |
431 | |
445 | |
432 | clock_t |
|
|
433 | debug_measure_start(void) |
446 | clock_t debug_measure_start(void) |
434 | { |
447 | { |
435 | clock_t start = clock(); |
448 | clock_t start = clock(); |
436 | return start; |
449 | return start; |
437 | } |
450 | } |
438 | |
451 | |
439 | clock_t |
|
|
440 | debug_measure_end(clock_t start_time) |
452 | clock_t debug_measure_end(clock_t start_time) |
441 | { |
453 | { |
442 | clock_t diff_time = clock() - start_time; |
454 | clock_t diff_time = clock() - start_time; |
443 | return diff_time; |
455 | return diff_time; |
444 | } |
456 | } |
445 | |
457 | |
446 | int |
|
|
447 | debug_measure_end_tsecs(clock_t start_time) |
458 | int debug_measure_end_tsecs(clock_t start_time) |
448 | { |
459 | { |
449 | clock_t diff_time = clock() - start_time; |
460 | clock_t diff_time = clock() - start_time; |
450 | return (int)( ((double)diff_time / (double)CLOCKS_PER_SEC)*1000 ); |
461 | return (int) (((double) diff_time / (double) CLOCKS_PER_SEC) * 1000); |
451 | } |
462 | } |
452 | |
463 | |
453 | void |
|
|
454 | debug_measure_result_str(clock_t diff, char *buffer) |
464 | void debug_measure_result_str(clock_t diff, char *buffer) |
455 | { |
465 | { |
456 | sprintf(buffer, "elapsed: %fs\n", (diff / CLOCKS_PER_SEC)); |
466 | sprintf(buffer, "elapsed: %fs\n", (diff / CLOCKS_PER_SEC)); |
457 | } |
467 | } |
458 | |
468 | |
459 | void |
|
|
460 | debug_mrp(const char* function_name, clock_t diff) |
469 | void debug_mrp(const char* function_name, clock_t diff) |
461 | { |
470 | { |
462 | dbg(0, "el:(%s) %fs\n", function_name, (double)((double)diff / (double)CLOCKS_PER_SEC)); |
471 | dbg(0, "el:(%s) %fs\n", function_name, (double) ((double) diff / (double) CLOCKS_PER_SEC)); |
463 | } |
472 | } |
464 | |
473 | |
465 | void debug_finished(void) |
474 | void debug_finished(void) |
466 | { |
475 | { |
467 | debug_dump_mallocs(); |
476 | debug_dump_mallocs(); |