/[zanavi_public1]/navit/navit/debug.c
ZANavi

Contents of /navit/navit/debug.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 51 - (hide annotations) (download)
Mon Jul 25 19:29:08 2016 UTC (7 years, 8 months ago) by zoff99
File MIME type: text/plain
File size: 14633 byte(s)
v2.0.52
1 zoff99 2 /**
2     * Navit, a modular navigation system.
3     * Copyright (C) 2005-2008 Navit Team
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * version 2 as published by the Free Software Foundation.
8     *
9     * This program is distributed in the hope that it will be useful,
10     * but WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     * GNU General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with this program; if not, write to the
16     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17     * Boston, MA 02110-1301, USA.
18     */
19    
20     #include <signal.h>
21     #include <stdarg.h>
22     #include <stdio.h>
23     #include <stdlib.h>
24     #include <string.h>
25     #include <time.h>
26     #include <glib.h>
27     #ifndef _MSC_VER
28     #include <sys/time.h>
29     #endif /* _MSC_VER */
30     #include "config.h"
31     #include "file.h"
32     #include "item.h"
33     #include "debug.h"
34    
35 zoff99 40 extern long global_last_spoken_base;
36    
37 zoff99 2 #ifdef HAVE_API_ANDROID
38     #include <android/log.h>
39     #endif
40    
41     #if defined HAVE_API_WIN32_CE || defined _MSC_VER
42     #include <windows.h>
43     #include <windowsx.h>
44     #endif
45    
46     #ifdef HAVE_SOCKET
47     #include <stdlib.h>
48     #include <sys/socket.h>
49     #include <netinet/in.h>
50     #include <arpa/inet.h>
51     static int debug_socket=-1;
52     static struct sockaddr_in debug_sin;
53     #endif
54    
55 zoff99 31 int debug_level = 0;
56     int segv_level = 0;
57     int timestamp_prefix = 0;
58 zoff99 2
59 zoff99 40 int global_func_indent_counter = -1;
60     const char* global_func_indent_spaces = " ";
61    
62 zoff99 2 static int dummy;
63     static GHashTable *debug_hash;
64     static gchar *gdb_program;
65    
66     static FILE *debug_fp;
67    
68 zoff99 51 // func def ------ this is bad!!
69     void android_send_generic_text(int id, char *text);
70     // func def ------ this is bad!!
71    
72 zoff99 2 #if defined(_WIN32) || defined(__CEGCC__)
73    
74     static void sigsegv(int sig)
75     {
76     }
77    
78     #else
79     #include <unistd.h>
80     static void sigsegv(int sig)
81     {
82     char buffer[256];
83     if (segv_level > 1)
84     sprintf(buffer, "gdb -ex bt %s %d", gdb_program, getpid());
85     else
86     sprintf(buffer, "gdb -ex bt -ex detach -ex quit %s %d", gdb_program, getpid());
87     system(buffer);
88     exit(1);
89     }
90     #endif
91    
92 zoff99 31 void debug_init(const char *program_name)
93 zoff99 2 {
94 zoff99 40 // gdb_program = g_strdup(program_name); // L
95     // signal(SIGSEGV, sigsegv); // L
96 zoff99 31 debug_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free_func, NULL);
97 zoff99 2 debug_fp = stderr;
98     }
99    
100 zoff99 31 static void debug_update_level(gpointer key, gpointer value, gpointer user_data)
101 zoff99 2 {
102     if (debug_level < GPOINTER_TO_INT(value))
103     debug_level = GPOINTER_TO_INT(value);
104     }
105    
106 zoff99 31 void debug_level_set(const char *name, int level)
107 zoff99 2 {
108 zoff99 31 if (!strcmp(name, "segv"))
109     {
110     segv_level = level;
111 zoff99 2 if (segv_level)
112     signal(SIGSEGV, sigsegv);
113     else
114     signal(SIGSEGV, NULL);
115 zoff99 31 }
116     else if (!strcmp(name, "timestamps"))
117     {
118     timestamp_prefix = level;
119     }
120     else
121     {
122     debug_level = 0;
123 zoff99 2 g_hash_table_insert(debug_hash, g_strdup(name), GINT_TO_POINTER(level));
124     g_hash_table_foreach(debug_hash, debug_update_level, NULL);
125     }
126     }
127    
128     struct debug *
129     debug_new(struct attr *parent, struct attr **attrs)
130     {
131 zoff99 31 struct attr *name, *level;
132     name = attr_search(attrs, NULL, attr_name);
133     level = attr_search(attrs, NULL, attr_level);
134 zoff99 2 #ifdef HAVE_SOCKET
135 zoff99 31 if (!name && !level)
136     {
137 zoff99 2 struct attr *socket_attr=attr_search(attrs, NULL, attr_socket);
138     char *p,*s;
139 zoff99 40
140 zoff99 2 if (!socket_attr)
141 zoff99 40 return NULL;
142    
143 zoff99 2 s=g_strdup(socket_attr->u.str);
144 zoff99 31 p=strchr(s,':');
145     if (!p)
146     {
147 zoff99 2 g_free(s);
148     return NULL;
149     }
150     *p++='\0';
151     debug_sin.sin_family=AF_INET;
152 zoff99 31 if (!inet_aton(s, &debug_sin.sin_addr))
153     {
154 zoff99 2 g_free(s);
155     return NULL;
156     }
157 zoff99 31 debug_sin.sin_port=ntohs(atoi(p));
158     if (debug_socket == -1)
159     debug_socket=socket(PF_INET, SOCK_DGRAM, 0);
160 zoff99 2 g_free(s);
161 zoff99 31 return (struct debug *)&dummy;
162 zoff99 2 }
163     #endif
164     if (!name || !level)
165     return NULL;
166 zoff99 40
167 zoff99 2 debug_level_set(name->u.str, level->u.num);
168 zoff99 40
169 zoff99 31 return (struct debug *) &dummy;
170 zoff99 2 }
171    
172 zoff99 31 int debug_level_get(const char *name)
173 zoff99 2 {
174     if (!debug_hash)
175     return 0;
176 zoff99 40
177 zoff99 2 return GPOINTER_TO_INT(g_hash_table_lookup(debug_hash, name));
178     }
179    
180 zoff99 40 void debug_get_timestamp_millis(long *ts_millis)
181     {
182    
183     // struct timeval
184     // {
185     // time_t tv_sec; /* seconds */
186     // suseconds_t tv_usec; /* microseconds */
187     // };
188    
189     struct timeval tv;
190    
191     if (gettimeofday(&tv, NULL) == -1)
192     {
193     ts_millis = -1;
194     return;
195     }
196    
197     if (global_last_spoken_base != 0)
198     {
199     *ts_millis = (((long)tv.tv_sec - global_last_spoken_base) * 1000) + ((int)tv.tv_usec / 1000);
200     }
201     else
202     {
203     *ts_millis = ((long)tv.tv_sec * 1000) + ((int)tv.tv_usec / 1000);
204     }
205     }
206    
207    
208 zoff99 2 static void debug_timestamp(char *buffer)
209     {
210     #if defined HAVE_API_WIN32_CE || defined _MSC_VER
211     LARGE_INTEGER counter, frequency;
212     double val;
213     QueryPerformanceCounter(&counter);
214     QueryPerformanceFrequency(&frequency);
215     val=counter.HighPart * 4294967296.0 + counter.LowPart;
216     val/=frequency.HighPart * 4294967296.0 + frequency.LowPart;
217     sprintf(buffer,"%.6f|",val);
218    
219     #else
220     struct timeval tv;
221    
222     if (gettimeofday(&tv, NULL) == -1)
223     return;
224     /* Timestamps are UTC */
225 zoff99 31 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);
226 zoff99 2 #endif
227     }
228    
229 zoff99 40 #ifdef HAVE_API_ANDROID
230    
231     /* Android log priority values, in ascending priority order. */
232     /*
233     typedef enum android_LogPriority {
234     ANDROID_LOG_UNKNOWN = 0,
235     ANDROID_LOG_DEFAULT,
236     ANDROID_LOG_VERBOSE,
237     ANDROID_LOG_DEBUG,
238     ANDROID_LOG_INFO,
239     ANDROID_LOG_WARN,
240     ANDROID_LOG_ERROR,
241     ANDROID_LOG_FATAL,
242     ANDROID_LOG_SILENT,
243     } android_LogPriority;
244     */
245    
246     static android_LogPriority
247     dbg_level_to_android(dbg_level level)
248     {
249     switch(level) {
250     case lvl_unset:
251     return ANDROID_LOG_UNKNOWN;
252     case lvl_error:
253     return ANDROID_LOG_ERROR;
254     case lvl_warning:
255     return ANDROID_LOG_WARN;
256     case lvl_info:
257     return ANDROID_LOG_INFO;
258     case lvl_debug:
259     return ANDROID_LOG_DEBUG;
260     }
261     return ANDROID_LOG_UNKNOWN;
262     }
263     #endif
264    
265 zoff99 31 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)
266 zoff99 2 {
267     #if defined HAVE_API_WIN32_CE || defined _MSC_VER
268     char buffer[4096];
269     #else
270 zoff99 31 char buffer[mlen + flen + 3];
271 zoff99 2 #endif
272    
273     sprintf(buffer, "%s:%s", module, function);
274 zoff99 31 if (debug_level_get(module) >= level || debug_level_get(buffer) >= level)
275     {
276 zoff99 2 #if defined(DEBUG_WIN32_CE_MESSAGEBOX)
277     wchar_t muni[4096];
278     #endif
279     char xbuffer[4096];
280 zoff99 31 xbuffer[0] = '\0';
281     if (prefix)
282     {
283 zoff99 2 if (timestamp_prefix)
284 zoff99 31 debug_timestamp(xbuffer);
285     strcpy(xbuffer + strlen(xbuffer), buffer);
286     strcpy(xbuffer + strlen(xbuffer), ":");
287 zoff99 2 }
288 zoff99 31 vsprintf(xbuffer + strlen(xbuffer), fmt, ap);
289 zoff99 2 #ifdef DEBUG_WIN32_CE_MESSAGEBOX
290     mbstowcs(muni, xbuffer, strlen(xbuffer)+1);
291     MessageBoxW(NULL, muni, TEXT("Navit - Error"), MB_APPLMODAL|MB_OK|MB_ICONERROR);
292     #else
293     #ifdef HAVE_API_ANDROID
294 zoff99 40 __android_log_print(dbg_level_to_android(lvl_info), "navit", "%s", xbuffer);
295     #else
296     #ifdef HAVE_SOCKET
297     if (debug_socket != -1)
298     {
299     sendto(debug_socket, xbuffer, strlen(xbuffer), 0, (struct sockaddr *)&debug_sin, sizeof(debug_sin));
300     return;
301     }
302     #endif
303     FILE *fp = debug_fp;
304 zoff99 31
305 zoff99 40 if (!fp)
306     {
307     fp = stderr;
308     }
309    
310     fprintf(fp, "%s", xbuffer);
311     fflush(fp);
312     #endif
313     #endif
314     }
315     }
316    
317    
318    
319     void debug_vprintf_func(int level, int indent, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, va_list ap)
320     {
321     #if defined HAVE_API_WIN32_CE || defined _MSC_VER
322     char buffer[4096];
323 zoff99 2 #else
324 zoff99 40 char buffer[mlen + flen + 3];
325     #endif
326    
327     sprintf(buffer, "FUNC:%.*s%s:%s", abs(2 * indent), global_func_indent_spaces, module, function);
328     if (debug_level_get(module) >= level || debug_level_get(buffer) >= level)
329     {
330     #if defined(DEBUG_WIN32_CE_MESSAGEBOX)
331     wchar_t muni[4096];
332     #endif
333     char xbuffer[4096];
334     xbuffer[0] = '\0';
335     if (prefix)
336     {
337     if (timestamp_prefix)
338     debug_timestamp(xbuffer);
339     strcpy(xbuffer + strlen(xbuffer), buffer);
340     strcpy(xbuffer + strlen(xbuffer), ":");
341     }
342     vsprintf(xbuffer + strlen(xbuffer), fmt, ap);
343     #ifdef DEBUG_WIN32_CE_MESSAGEBOX
344     mbstowcs(muni, xbuffer, strlen(xbuffer)+1);
345     MessageBoxW(NULL, muni, TEXT("Navit - Error"), MB_APPLMODAL|MB_OK|MB_ICONERROR);
346     #else
347     #ifdef HAVE_API_ANDROID
348     __android_log_print(dbg_level_to_android(lvl_info), "navit", "%s", xbuffer);
349     #else
350 zoff99 2 #ifdef HAVE_SOCKET
351 zoff99 31 if (debug_socket != -1)
352     {
353 zoff99 2 sendto(debug_socket, xbuffer, strlen(xbuffer), 0, (struct sockaddr *)&debug_sin, sizeof(debug_sin));
354     return;
355     }
356     #endif
357 zoff99 40 FILE *fp = debug_fp;
358    
359 zoff99 31 if (!fp)
360 zoff99 40 {
361 zoff99 2 fp = stderr;
362 zoff99 40 }
363    
364 zoff99 31 fprintf(fp, "%s", xbuffer);
365 zoff99 2 fflush(fp);
366     #endif
367     #endif
368     }
369     }
370    
371 zoff99 40
372 zoff99 51 void debug_for_tests_vprintf(int level, const char *fmt, va_list ap)
373     {
374     #ifdef _CIDEBUG_BUILD_
375     #ifdef HAVE_API_ANDROID
376     char *xbuffer = g_malloc(40960);
377     xbuffer[0] = '\0';
378     vsprintf(xbuffer, fmt, ap);
379     android_send_generic_text(32, xbuffer);
380     g_free(xbuffer);
381     #endif
382     #endif
383     }
384 zoff99 40
385 zoff99 51
386     void debug_for_tests_printf(int level, const char *fmt, ...)
387     {
388     #ifdef _CIDEBUG_BUILD_
389     #ifdef HAVE_API_ANDROID
390     va_list ap;
391     va_start(ap, fmt);
392     debug_for_tests_vprintf(level, fmt, ap);
393     va_end(ap);
394     #endif
395     #endif
396     }
397    
398 zoff99 31 void debug_printf(int level, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, ...)
399 zoff99 2 {
400     #ifdef _DEBUG_BUILD_
401     va_list ap;
402     va_start(ap, fmt);
403     debug_vprintf(level, module, mlen, function, flen, prefix, fmt, ap);
404     va_end(ap);
405     #endif
406     }
407    
408 zoff99 40 void debug_printf_func(int level, int indent, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, ...)
409     {
410     #ifdef _DEBUG_BUILD_
411     va_list ap;
412     va_start(ap, fmt);
413     debug_vprintf_func(level, indent, module, mlen, function, flen, prefix, fmt, ap);
414     va_end(ap);
415     #endif
416     }
417    
418 zoff99 31 void debug_printf2(int level, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, ...)
419 zoff99 2 {
420     va_list ap;
421     va_start(ap, fmt);
422     debug_vprintf(level, module, mlen, function, flen, prefix, fmt, ap);
423     va_end(ap);
424     }
425    
426 zoff99 31 void debug_assert_fail(const char *module, const int mlen, const char *function, const int flen, const char *file, int line, const char *expr)
427 zoff99 2 {
428 zoff99 31 debug_printf2(0, module, mlen, function, flen, 1, "%s:%d assertion failed:%s\n", file, line, expr);
429 zoff99 2 abort();
430     }
431    
432 zoff99 31 void debug_destroy(void)
433 zoff99 2 {
434     if (!debug_fp)
435     return;
436     if (debug_fp == stderr || debug_fp == stdout)
437     return;
438     fclose(debug_fp);
439     debug_fp = NULL;
440     }
441    
442     void debug_set_logfile(const char *path)
443     {
444     FILE *fp;
445     fp = fopen(path, "a");
446 zoff99 31 if (fp)
447     {
448 zoff99 2 debug_destroy();
449     debug_fp = fp;
450     fprintf(debug_fp, "Navit log started\n");
451     fflush(debug_fp);
452     }
453     }
454    
455 zoff99 31 struct malloc_head
456     {
457 zoff99 2 int magic;
458     int size;
459     char *where;
460     void *return_address[8];
461     struct malloc_head *prev;
462     struct malloc_head *next;
463 zoff99 31 }*malloc_heads;
464 zoff99 2
465 zoff99 31 struct malloc_tail
466     {
467 zoff99 2 int magic;
468     };
469    
470 zoff99 31 int mallocs, malloc_size, malloc_size_m;
471 zoff99 2
472 zoff99 31 void debug_dump_mallocs(void)
473 zoff99 2 {
474 zoff99 31 struct malloc_head *head = malloc_heads;
475 zoff99 2 int i;
476 zoff99 31 dbg(0, "mallocs %d\n", mallocs);
477     while (head)
478     {
479     fprintf(stderr, "unfreed malloc from %s of size %d\n", head->where, head->size);
480     for (i = 0; i < 8; i++)
481     fprintf(stderr, "\tlist *%p\n", head->return_address[i]);
482 zoff99 2 #if 0
483     fprintf(stderr,"%s\n",head+1);
484     #endif
485 zoff99 31 head = head->next;
486 zoff99 2 }
487     }
488    
489     void *
490     debug_malloc(const char *where, int line, const char *func, int size)
491     {
492     struct malloc_head *head;
493     struct malloc_tail *tail;
494     if (!size)
495     return NULL;
496     mallocs++;
497 zoff99 31 malloc_size += size;
498     if (malloc_size / (1024 * 1024) != malloc_size_m)
499     {
500     malloc_size_m = malloc_size / (1024 * 1024);
501     dbg(0, "malloced %d kb\n", malloc_size / 1024);
502 zoff99 2 }
503 zoff99 31 head = malloc(size + sizeof(*head) + sizeof(*tail));
504     head->magic = 0xdeadbeef;
505     head->size = size;
506     head->prev = NULL;
507     head->next = malloc_heads;
508     malloc_heads = head;
509     if (head->next)
510     head->next->prev = head;
511     head->where = g_strdup_printf("%s:%d %s", where, line, func);
512 zoff99 2 #if !defined (__GNUC__)
513     #define __builtin_return_address(x) NULL
514     #endif
515 zoff99 31 head->return_address[0] = __builtin_return_address(0);
516     head->return_address[1] = __builtin_return_address(1);
517     head->return_address[2] = __builtin_return_address(2);
518     head->return_address[3] = __builtin_return_address(3);
519     head->return_address[4] = __builtin_return_address(4);
520     head->return_address[5] = __builtin_return_address(5);
521     head->return_address[6] = __builtin_return_address(6);
522     head->return_address[7] = __builtin_return_address(7);
523 zoff99 2 head++;
524 zoff99 31 tail = (struct malloc_tail *) ((unsigned char *) head + size);
525     tail->magic = 0xdeadbef0;
526 zoff99 2 return head;
527     }
528    
529     void *
530     debug_malloc0(const char *where, int line, const char *func, int size)
531     {
532 zoff99 31 void *ret = debug_malloc(where, line, func, size);
533 zoff99 2 if (ret)
534     memset(ret, 0, size);
535     return ret;
536     }
537    
538     void *
539     debug_realloc(const char *where, int line, const char *func, void *ptr, int size)
540     {
541 zoff99 31 void *ret = debug_malloc(where, line, func, size);
542 zoff99 2 if (ret && ptr)
543     memcpy(ret, ptr, size);
544     debug_free(where, line, func, ptr);
545     return ret;
546     }
547    
548     char *
549     debug_strdup(const char *where, int line, const char *func, const char *ptr)
550 zoff99 31 {
551 zoff99 2 int size;
552     char *ret;
553    
554     if (!ptr)
555     return NULL;
556 zoff99 31 size = strlen(ptr) + 1;
557     ret = debug_malloc(where, line, func, size);
558 zoff99 2 memcpy(ret, ptr, size);
559     return ret;
560     }
561    
562     char *
563     debug_guard(const char *where, int line, const char *func, char *str)
564     {
565 zoff99 31 char *ret = debug_strdup(where, line, func, str);
566 zoff99 2 g_free(str);
567     return ret;
568     }
569    
570 zoff99 31 void debug_free(const char *where, int line, const char *func, void *ptr)
571 zoff99 2 {
572     struct malloc_head *head;
573 zoff99 31 struct malloc_tail *tail;
574 zoff99 2 if (!ptr)
575     return;
576     mallocs--;
577 zoff99 31 head = (struct malloc_head *) ((unsigned char *) ptr - sizeof(*head));
578     tail = (struct malloc_tail *) ((unsigned char *) ptr + head->size);
579     malloc_size -= head->size;
580     if (head->magic != 0xdeadbeef || tail->magic != 0xdeadbef0)
581     {
582     fprintf(stderr, "Invalid free from %s:%d %s\n", where, line, func);
583 zoff99 2 }
584 zoff99 31 head->magic = 0;
585     tail->magic = 0;
586     if (head->prev)
587     head->prev->next = head->next;
588 zoff99 2 else
589 zoff99 31 malloc_heads = head->next;
590 zoff99 2 if (head->next)
591 zoff99 31 head->next->prev = head->prev;
592 zoff99 2 free(head->where);
593     free(head);
594     }
595    
596 zoff99 31 void debug_free_func(void *ptr)
597 zoff99 2 {
598 zoff99 31 debug_free("unknown", 0, "unknown", ptr);
599 zoff99 2 }
600    
601 zoff99 31 clock_t debug_measure_start(void)
602 zoff99 28 {
603     clock_t start = clock();
604     return start;
605     }
606    
607 zoff99 31 clock_t debug_measure_end(clock_t start_time)
608 zoff99 28 {
609     clock_t diff_time = clock() - start_time;
610     return diff_time;
611     }
612    
613 zoff99 31 int debug_measure_end_tsecs(clock_t start_time)
614 zoff99 28 {
615     clock_t diff_time = clock() - start_time;
616 zoff99 31 return (int) (((double) diff_time / (double) CLOCKS_PER_SEC) * 1000);
617 zoff99 28 }
618    
619 zoff99 31 void debug_measure_result_str(clock_t diff, char *buffer)
620 zoff99 28 {
621     sprintf(buffer, "elapsed: %fs\n", (diff / CLOCKS_PER_SEC));
622     }
623    
624 zoff99 31 void debug_mrp(const char* function_name, clock_t diff)
625 zoff99 28 {
626 zoff99 31 dbg(0, "el:(%s) %fs\n", function_name, (double) ((double) diff / (double) CLOCKS_PER_SEC));
627 zoff99 28 }
628    
629     void debug_finished(void)
630     {
631 zoff99 2 debug_dump_mallocs();
632     g_free(gdb_program);
633     g_hash_table_destroy(debug_hash);
634     debug_destroy();
635     }
636    
637 zoff99 51

   
Visit the ZANavi Wiki