diff options
Diffstat (limited to 'navit/debug.c')
-rw-r--r-- | navit/debug.c | 761 |
1 files changed, 407 insertions, 354 deletions
diff --git a/navit/debug.c b/navit/debug.c index 6d1bd4c95..ef485ad8a 100644 --- a/navit/debug.c +++ b/navit/debug.c @@ -67,459 +67,512 @@ static FILE *debug_fp; #if defined(_WIN32) || defined(__CEGCC__) -static void sigsegv(int sig) -{ +static void sigsegv(int sig) { } #else #include <unistd.h> -static void sigsegv(int sig) -{ - char buffer[256]; - if (segv_level > 1) - sprintf(buffer, "gdb -ex bt %s %d", gdb_program, getpid()); - else - sprintf(buffer, "gdb -ex bt -ex detach -ex quit %s %d", gdb_program, getpid()); - system(buffer); - exit(1); +static void sigsegv(int sig) { + char buffer[256]; + if (segv_level > 1) + sprintf(buffer, "gdb -ex bt %s %d", gdb_program, getpid()); + else + sprintf(buffer, "gdb -ex bt -ex detach -ex quit %s %d", gdb_program, getpid()); + system(buffer); + exit(1); } #endif -void -debug_init(const char *program_name) -{ +void debug_init(const char *program_name) { #ifndef HAVE_API_ANDROID - gdb_program=g_strdup(program_name); - signal(SIGSEGV, sigsegv); + gdb_program=g_strdup(program_name); + signal(SIGSEGV, sigsegv); #endif - debug_hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + debug_hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED - debug_fp = stdout; + debug_fp = stdout; #else - debug_fp = stderr; + debug_fp = stderr; #endif } -static void -debug_update_level(gpointer key, gpointer value, gpointer user_data) -{ - if (max_debug_level < GPOINTER_TO_INT(value)) - max_debug_level = GPOINTER_TO_INT(value); +static void debug_update_level(gpointer key, gpointer value, gpointer user_data) { + if (max_debug_level < GPOINTER_TO_INT(value)) + max_debug_level = GPOINTER_TO_INT(value); } -void -debug_set_global_level(dbg_level level, int override_old_value ) { - if (global_debug_level == GLOBAL_DEBUG_LEVEL_UNSET || override_old_value) { - global_debug_level=level; - if (max_debug_level < global_debug_level){ - max_debug_level = global_debug_level; - } - } +void debug_set_global_level(dbg_level level, int override_old_value ) { + if (global_debug_level == GLOBAL_DEBUG_LEVEL_UNSET || override_old_value) { + global_debug_level=level; + if (max_debug_level < global_debug_level) { + max_debug_level = global_debug_level; + } + } } -void -debug_level_set(const char *name, dbg_level level) -{ - if (!strcmp(name, "segv")) { +void debug_level_set(const char *name, dbg_level level) { + if (!strcmp(name, "segv")) { #ifndef HAVE_API_ANDROID - segv_level=level; - if (segv_level) - signal(SIGSEGV, sigsegv); - else - signal(SIGSEGV, NULL); + segv_level=level; + if (segv_level) + signal(SIGSEGV, sigsegv); + else + signal(SIGSEGV, NULL); #endif - } else if (!strcmp(name, "timestamps")) { - timestamp_prefix=level; - } else if (!strcmp(name, DEBUG_MODULE_GLOBAL)) { - debug_set_global_level(level, 0); - } else { - g_hash_table_insert(debug_hash, g_strdup(name), GINT_TO_POINTER(level)); - g_hash_table_foreach(debug_hash, debug_update_level, NULL); - } + } else if (!strcmp(name, "timestamps")) { + timestamp_prefix=level; + } else if (!strcmp(name, DEBUG_MODULE_GLOBAL)) { + debug_set_global_level(level, 0); + } else { + g_hash_table_insert(debug_hash, g_strdup(name), GINT_TO_POINTER(level)); + g_hash_table_foreach(debug_hash, debug_update_level, NULL); + } } -static dbg_level -parse_dbg_level(struct attr *dbg_level_attr, struct attr *level_attr) -{ - if (dbg_level_attr) { - if(!strcmp(dbg_level_attr->u.str,"error")){ - return lvl_error; - } - if(!strcmp(dbg_level_attr->u.str,"warning")){ - return lvl_warning; - } - if(!strcmp(dbg_level_attr->u.str,"info")){ - return lvl_info; - } - if(!strcmp(dbg_level_attr->u.str,"debug")){ - return lvl_debug; - } - dbg(lvl_error, "Invalid debug level in config: '%s'\n", dbg_level_attr->u.str); - } else if (level_attr) { - if (level_attr->u.num>= lvl_error && - level_attr->u.num<= lvl_debug) - return level_attr->u.num; - dbg(lvl_error, "Invalid debug level in config: %ld\n", level_attr->u.num); - } - return lvl_unset; +static dbg_level parse_dbg_level(struct attr *dbg_level_attr, struct attr *level_attr) { + if (dbg_level_attr) { + if(!strcmp(dbg_level_attr->u.str,"error")) { + return lvl_error; + } + if(!strcmp(dbg_level_attr->u.str,"warning")) { + return lvl_warning; + } + if(!strcmp(dbg_level_attr->u.str,"info")) { + return lvl_info; + } + if(!strcmp(dbg_level_attr->u.str,"debug")) { + return lvl_debug; + } + dbg(lvl_error, "Invalid debug level in config: '%s'", dbg_level_attr->u.str); + } else if (level_attr) { + if (level_attr->u.num>= lvl_error && + level_attr->u.num<= lvl_debug) + return level_attr->u.num; + dbg(lvl_error, "Invalid debug level in config: %ld", level_attr->u.num); + } + return lvl_unset; } struct debug * -debug_new(struct attr *parent, struct attr **attrs) -{ - struct attr *name,*dbg_level_attr,*level_attr; - dbg_level level; - name=attr_search(attrs, NULL, attr_name); - dbg_level_attr=attr_search(attrs, NULL, attr_dbg_level); - level_attr=attr_search(attrs, NULL, attr_level); - level = parse_dbg_level(dbg_level_attr,level_attr); +debug_new(struct attr *parent, struct attr **attrs) { + struct attr *name,*dbg_level_attr,*level_attr; + dbg_level level; + name=attr_search(attrs, NULL, attr_name); + dbg_level_attr=attr_search(attrs, NULL, attr_dbg_level); + level_attr=attr_search(attrs, NULL, attr_level); + level = parse_dbg_level(dbg_level_attr,level_attr); #ifdef HAVE_SOCKET - if (!name && level==lvl_unset) { - struct attr *socket_attr=attr_search(attrs, NULL, attr_socket); - char *p,*s; - if (!socket_attr) - return NULL; - s=g_strdup(socket_attr->u.str); - p=strchr(s,':'); - if (!p) { - g_free(s); - return NULL; - } - *p++='\0'; - debug_sin.sin_family=AF_INET; - if (!inet_aton(s, &debug_sin.sin_addr)) { - g_free(s); - return NULL; - } - debug_sin.sin_port=ntohs(atoi(p)); - if (debug_socket == -1) - debug_socket=socket(PF_INET, SOCK_DGRAM, 0); - g_free(s); - return (struct debug *)&dummy; - } + if (!name && level==lvl_unset) { + struct attr *socket_attr=attr_search(attrs, NULL, attr_socket); + char *p,*s; + if (!socket_attr) + return NULL; + s=g_strdup(socket_attr->u.str); + p=strchr(s,':'); + if (!p) { + g_free(s); + return NULL; + } + *p++='\0'; + debug_sin.sin_family=AF_INET; + if (!inet_aton(s, &debug_sin.sin_addr)) { + g_free(s); + return NULL; + } + debug_sin.sin_port=ntohs(atoi(p)); + if (debug_socket == -1) + debug_socket=socket(PF_INET, SOCK_DGRAM, 0); + g_free(s); + return (struct debug *)&dummy; + } #endif - if (!name || level==lvl_unset) - return NULL; - debug_level_set(name->u.str, level); - return (struct debug *)&dummy; + if (!name || level==lvl_unset) + return NULL; + debug_level_set(name->u.str, level); + return (struct debug *)&dummy; } -dbg_level -debug_level_get(const char *message_category) -{ - if (!debug_hash) - return DEFAULT_DEBUG_LEVEL; - gpointer level = g_hash_table_lookup(debug_hash, message_category); - if (!level) { - return DEFAULT_DEBUG_LEVEL; - } - return GPOINTER_TO_INT(level); +dbg_level debug_level_get(const char *message_category) { + if (!debug_hash) + return DEFAULT_DEBUG_LEVEL; + gpointer level = g_hash_table_lookup(debug_hash, message_category); + if (!level) { + return DEFAULT_DEBUG_LEVEL; + } + return GPOINTER_TO_INT(level); } -static void debug_timestamp(char *buffer) -{ +/** + * @brief Write a timestamp to a string buffer + * + * Timestamp has the format "HH:MM:SS:mmm|" (with mmm=milliseconds), or under Windows "SSSSS:uuuuuu|" (with uuuuuu=microseconds) + * + * @param[out] buffer The buffer to write to + * + * @warning Buffer overflow may occur on @p buffer, if it is less than 14-bytes long (13 chars will be stored at max) + */ +static void debug_timestamp(char *buffer) { #if defined HAVE_API_WIN32_CE || defined _MSC_VER - LARGE_INTEGER counter, frequency; - double val; - QueryPerformanceCounter(&counter); - QueryPerformanceFrequency(&frequency); - val=counter.HighPart * 4294967296.0 + counter.LowPart; - val/=frequency.HighPart * 4294967296.0 + frequency.LowPart; - sprintf(buffer,"%.6f|",val); - + LARGE_INTEGER counter, frequency; + double val; + unsigned int intpart; + QueryPerformanceCounter(&counter); + QueryPerformanceFrequency(&frequency); + val=counter.HighPart * 4294967296.0 + counter.LowPart; + val/=frequency.HighPart * 4294967296.0 + frequency.LowPart; + intpart=((unsigned int)val)/100000; /* Extract all digits above 5 lower from integer part */ + val = val - (intpart * 100000); /* Limit val integer part to 5 digits */ + sprintf(buffer,"%.6f|",val); #else - struct timeval tv; - - if (gettimeofday(&tv, NULL) == -1) - return; - /* Timestamps are UTC */ - 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); + struct timeval tv; + + if (gettimeofday(&tv, NULL) == -1) + return; + /* Timestamps are UTC */ + 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); #endif } -static char* dbg_level_to_string(dbg_level level) -{ - switch(level) { - case lvl_unset: - return "-unset-"; - case lvl_error: - return "error"; - case lvl_warning: - return "warning"; - case lvl_info: - return "info"; - case lvl_debug: - return "debug"; - } - return "-invalid level-"; +static char* dbg_level_to_string(dbg_level level) { + switch(level) { + case lvl_unset: + return "-unset-"; + case lvl_error: + return "error"; + case lvl_warning: + return "warning"; + case lvl_info: + return "info"; + case lvl_debug: + return "debug"; + } + return "-invalid level-"; } #ifdef HAVE_API_ANDROID -static android_LogPriority -dbg_level_to_android(dbg_level level) -{ - switch(level) { - case lvl_unset: - return ANDROID_LOG_UNKNOWN; - case lvl_error: - return ANDROID_LOG_ERROR; - case lvl_warning: - return ANDROID_LOG_WARN; - case lvl_info: - return ANDROID_LOG_INFO; - case lvl_debug: - return ANDROID_LOG_DEBUG; - } - return ANDROID_LOG_UNKNOWN; +static android_LogPriority dbg_level_to_android(dbg_level level) { + switch(level) { + case lvl_unset: + return ANDROID_LOG_UNKNOWN; + case lvl_error: + return ANDROID_LOG_ERROR; + case lvl_warning: + return ANDROID_LOG_WARN; + case lvl_info: + return ANDROID_LOG_INFO; + case lvl_debug: + return ANDROID_LOG_DEBUG; + } + return ANDROID_LOG_UNKNOWN; } #endif -void -debug_vprintf(dbg_level level, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, va_list ap) -{ +/** + * @brief Write a log message + * + * @param level The level of the message. The message will only be written if \p level is higher than the minimum (global, per module or per function) + * @param module The name of the module that is initiating the log message + * @param mlen The length of string \p module + * @param function The name of the function that is initiating the log message + * @param flen The length of string \p function + * @param prefix Force prepending the message with context information (a timestamp, if timestamp_prefix is set), and the module and function name + * @param fmt The format string that specifies how subsequent arguments are output + * @param ap A list of arguments to use for substitution in the format string + */ +void debug_vprintf(dbg_level level, const char *module, const int mlen, const char *function, const int flen, + int prefix, const char *fmt, va_list ap) { + char *end; /* Pointer to the NUL terminating byte of debug_message */ + char debug_message[4096]; + char *message_origin = debug_message + sizeof(debug_message) + -1; /* message_origin is actually stored at the very end of debug_message buffer */ + size_t len; /* Length of the currently processed C-string */ + + /* Here we store a description of the source of the debugging message (message_origin) + * For this, we use the last bytes of the debug_message[] buffer. + * For example, if message_origin is "gui_internal:gui_internal_set_attr", debug_message[] will contain: + * "gui_internal:gui_internal_set_attr\0" with '\0' being the last byte (stored in debug_message[sizeof(debug_message) -1]) + */ + + *message_origin = '\0'; /* Force string termination of message_origin (last byte of debug_message) */ + +#if defined HAVE_API_WIN32_CE || defined _MSC_VER + len = strlen(function); +#else + len = flen; +#endif + message_origin -= len; + dbg_assert(message_origin >= debug_message); + memmove(message_origin, function, len); + message_origin--; + dbg_assert(message_origin >= debug_message); + *message_origin = ':'; #if defined HAVE_API_WIN32_CE || defined _MSC_VER - char message_origin[4096]; + len = strlen(module); #else - char message_origin[mlen+flen+3]; + len = mlen; #endif + message_origin -= len; + dbg_assert(message_origin >= debug_message); + memmove(message_origin, module, len); - sprintf(message_origin, "%s:%s", module, function); - if (global_debug_level >= level || debug_level_get(module) >= level || debug_level_get(message_origin) >= level) { + /* The source of the debug message has been created, is terminated with '\0' and stored at the very end of the debug_message buffer. */ + + if (global_debug_level >= level || debug_level_get(module) >= level || debug_level_get(message_origin) >= level) { + /* Do we output a debug message, based on the current debug level set */ #if defined(DEBUG_WIN32_CE_MESSAGEBOX) - wchar_t muni[4096]; + wchar_t muni[4096]; #endif - char debug_message[4096]; - debug_message[0]='\0'; - if (prefix) { - if (timestamp_prefix) - debug_timestamp(debug_message); - strcpy(debug_message+strlen(debug_message),dbg_level_to_string(level)); - strcpy(debug_message+strlen(debug_message),":"); - strcpy(debug_message+strlen(debug_message),message_origin); - strcpy(debug_message+strlen(debug_message),":"); - } + debug_message[0]='\0'; + end = debug_message; + if (prefix) { + if (timestamp_prefix) { + /* Do we prepend with a timestamp? */ + dbg_assert(sizeof(debug_message)>=14); + debug_timestamp(debug_message); + len = strlen(debug_message); + end = debug_message+len; + } + /* When we reach this part of the code, end is a pointer to the beginning of the debug message (inside the buffer debug_message) */ + g_strlcpy(end, dbg_level_to_string(level), + sizeof(debug_message) - (end - debug_message)); /* Add the debug level for the current debug message level */ + len = strlen(debug_message); + end = debug_message+len; /* Have len points to the end of the constructed string */ + dbg_assert(end < debug_message+sizeof(debug_message)); /* Make sure we don't get any overflow */ + *end++ = ':'; + /* In the code below, we add the message_origin to the debug message */ + len=strlen(message_origin); + dbg_assert(end+len < debug_message+sizeof(debug_message)); /* Make sure we don't get any overflow */ + memmove(end,message_origin,len); /* We use memmove here as both message_origin and destination may overlap */ + message_origin = + NULL; /* Warning: from this point, we must not use the pointer message_origin as the content of the debug_message may be overwritten at any time. */ + end+=len; + dbg_assert(end+1 < debug_message+sizeof( + debug_message)); /* Make sure we don't get any overflow for both ':' and terminating '\0' */ + *end++ = ':'; + *end = '\0'; /* Force termination of the string */ + /* When we get here, debug_message contains: + * "ttttttttttttt|error:gui_internal:gui_internal_set_attr:\0" (if timestamps are enabled) or + * "error:gui_internal:gui_internal_set_attr:\0" otherwise. + * end points to the terminating '\0' + */ + } #if defined HAVE_API_WIN32_CE #define vsnprintf _vsnprintf #endif - vsnprintf(debug_message+strlen(debug_message),4095-strlen(debug_message),fmt,ap); + len = strlen(debug_message); + vsnprintf(end,sizeof(debug_message) - len,fmt, + ap); /* Concatenate the debug log message itself to the prefix constructed above */ + len = strlen(debug_message); /* Adjust len to store the length of the current string */ + end = debug_message+len; /* Adjust end to point to the terminating '\0' of the current string */ + + /* In the code below, we prepend the end-of-line sequence to the current string pointed by debug_message ("\r\n" for Windows, "\r" otherwise */ +#ifdef HAVE_API_WIN32_BASE + if (len + 1 < sizeof(debug_message) - 1) { + /* For Windows platforms, add \r at the end of the buffer (if any room), make sure that we have room for one more character */ + *end++ = '\r'; + len++; + *end = '\0'; + } +#endif + if (len + 1 < sizeof(debug_message)) { /* Add \n at the end of the buffer (if any room) */ + *end++ = '\n'; + len++; + *end = '\0'; + } #ifdef DEBUG_WIN32_CE_MESSAGEBOX - mbstowcs(muni, debug_message, strlen(debug_message)+1); - MessageBoxW(NULL, muni, TEXT("Navit - Error"), MB_APPLMODAL|MB_OK|MB_ICONERROR); + mbstowcs(muni, debug_message, len+1); + MessageBoxW(NULL, muni, TEXT("Navit - Error"), MB_APPLMODAL|MB_OK|MB_ICONERROR); #else #ifdef HAVE_API_ANDROID - __android_log_print(dbg_level_to_android(level), "navit", "%s", debug_message); + __android_log_print(dbg_level_to_android(level), "navit", "%s", debug_message); #else #ifdef HAVE_SOCKET - if (debug_socket != -1) { - sendto(debug_socket, debug_message, strlen(debug_message), 0, (struct sockaddr *)&debug_sin, sizeof(debug_sin)); - return; - } + if (debug_socket != -1) { + sendto(debug_socket, debug_message, len, 0, (struct sockaddr *)&debug_sin, sizeof(debug_sin)); + return; + } #endif - FILE *fp=debug_fp; - if (! fp) - fp = stderr; - fprintf(fp,"%s",debug_message); - fflush(fp); + FILE *fp=debug_fp; + if (! fp) + fp = stderr; + fprintf(fp,"%s",debug_message); + fflush(fp); #endif #endif - } + } } -void -debug_printf(dbg_level level, const char *module, const int mlen,const char *function, const int flen, int prefix, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - debug_vprintf(level, module, mlen, function, flen, prefix, fmt, ap); - va_end(ap); +void debug_printf(dbg_level level, const char *module, const int mlen,const char *function, const int flen, + int prefix, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + debug_vprintf(level, module, mlen, function, flen, prefix, fmt, ap); + va_end(ap); } -void -debug_assert_fail(const char *module, const int mlen,const char *function, const int flen, const char *file, int line, const char *expr) -{ - debug_printf(lvl_error,module,mlen,function,flen,1,"%s:%d assertion failed:%s\n", file, line, expr); - abort(); +void debug_assert_fail(const char *module, const int mlen,const char *function, const int flen, const char *file, + int line, const char *expr) { + debug_printf(lvl_error,module,mlen,function,flen,1,"%s:%d assertion failed:%s\n", file, line, expr); + abort(); } -void -debug_destroy(void) -{ - if (!debug_fp) - return; - if (debug_fp == stderr || debug_fp == stdout) - return; - fclose(debug_fp); - debug_fp = NULL; +void debug_destroy(void) { + if (!debug_fp) + return; + if (debug_fp == stderr || debug_fp == stdout) + return; + fclose(debug_fp); + debug_fp = NULL; } -void debug_set_logfile(const char *path) -{ - FILE *fp; - fp = fopen(path, "a"); - if (fp) { - debug_destroy(); - debug_fp = fp; - fprintf(debug_fp, "Navit log started\n"); - fflush(debug_fp); - } +void debug_set_logfile(const char *path) { + FILE *fp; + fp = fopen(path, "a"); + if (fp) { + debug_destroy(); + debug_fp = fp; + fprintf(debug_fp, "Navit log started\n"); + fflush(debug_fp); + } } struct malloc_head { - int magic; - int size; - char *where; - void *return_address[8]; - struct malloc_head *prev; - struct malloc_head *next; + int magic; + int size; + char *where; + void *return_address[8]; + struct malloc_head *prev; + struct malloc_head *next; } *malloc_heads; struct malloc_tail { - int magic; + int magic; }; int mallocs,debug_malloc_size,debug_malloc_size_m; -void -debug_dump_mallocs(void) -{ - struct malloc_head *head=malloc_heads; - int i; - dbg(lvl_debug,"mallocs %d\n",mallocs); - while (head) { - fprintf(stderr,"unfreed malloc from %s of size %d\n",head->where,head->size); - for (i = 0 ; i < 8 ; i++) - fprintf(stderr,"\tlist *%p\n",head->return_address[i]); -#if 0 - fprintf(stderr,"%s\n",head+1); -#endif - head=head->next; - } +void debug_dump_mallocs(void) { + struct malloc_head *head=malloc_heads; + int i; + dbg(lvl_debug,"mallocs %d",mallocs); + while (head) { + fprintf(stderr,"unfreed malloc from %s of size %d\n",head->where,head->size); + for (i = 0 ; i < 8 ; i++) + fprintf(stderr,"\tlist *%p\n",head->return_address[i]); + head=head->next; + } } -void * -debug_malloc(const char *where, int line, const char *func, int size) -{ - struct malloc_head *head; - struct malloc_tail *tail; - if (!size) - return NULL; - mallocs++; - debug_malloc_size+=size; - if (debug_malloc_size/(1024*1024) != debug_malloc_size_m) { - debug_malloc_size_m=debug_malloc_size/(1024*1024); - dbg(lvl_debug,"malloced %d kb\n",debug_malloc_size/1024); - } - head=malloc(size+sizeof(*head)+sizeof(*tail)); - head->magic=0xdeadbeef; - head->size=size; - head->prev=NULL; - head->next=malloc_heads; - malloc_heads=head; - if (head->next) - head->next->prev=head; - head->where=g_strdup_printf("%s:%d %s",where,line,func); +void *debug_malloc(const char *where, int line, const char *func, int size) { + struct malloc_head *head; + struct malloc_tail *tail; + if (!size) + return NULL; + mallocs++; + debug_malloc_size+=size; + if (debug_malloc_size/(1024*1024) != debug_malloc_size_m) { + debug_malloc_size_m=debug_malloc_size/(1024*1024); + dbg(lvl_debug,"malloced %d kb",debug_malloc_size/1024); + } + head=malloc(size+sizeof(*head)+sizeof(*tail)); + head->magic=0xdeadbeef; + head->size=size; + head->prev=NULL; + head->next=malloc_heads; + malloc_heads=head; + if (head->next) + head->next->prev=head; + head->where=g_strdup_printf("%s:%d %s",where,line,func); #if !defined (__GNUC__) #define __builtin_return_address(x) NULL #endif - head->return_address[0]=__builtin_return_address(0); - head->return_address[1]=__builtin_return_address(1); - head->return_address[2]=__builtin_return_address(2); - head->return_address[3]=__builtin_return_address(3); - head->return_address[4]=__builtin_return_address(4); - head->return_address[5]=__builtin_return_address(5); - head->return_address[6]=__builtin_return_address(6); - head->return_address[7]=__builtin_return_address(7); - head++; - tail=(struct malloc_tail *)((unsigned char *)head+size); - tail->magic=0xdeadbef0; - return head; + head->return_address[0]=__builtin_return_address(0); + head->return_address[1]=__builtin_return_address(1); + head->return_address[2]=__builtin_return_address(2); + head->return_address[3]=__builtin_return_address(3); + head->return_address[4]=__builtin_return_address(4); + head->return_address[5]=__builtin_return_address(5); + head->return_address[6]=__builtin_return_address(6); + head->return_address[7]=__builtin_return_address(7); + head++; + tail=(struct malloc_tail *)((unsigned char *)head+size); + tail->magic=0xdeadbef0; + return head; } -void * -debug_malloc0(const char *where, int line, const char *func, int size) -{ - void *ret=debug_malloc(where, line, func, size); - if (ret) - memset(ret, 0, size); - return ret; +void *debug_malloc0(const char *where, int line, const char *func, int size) { + void *ret=debug_malloc(where, line, func, size); + if (ret) + memset(ret, 0, size); + return ret; } -void * -debug_realloc(const char *where, int line, const char *func, void *ptr, int size) -{ - void *ret=debug_malloc(where, line, func, size); - if (ret && ptr) - memcpy(ret, ptr, size); - debug_free(where, line, func, ptr); - return ret; +void *debug_realloc(const char *where, int line, const char *func, void *ptr, int size) { + void *ret=debug_malloc(where, line, func, size); + if (ret && ptr) + memcpy(ret, ptr, size); + debug_free(where, line, func, ptr); + return ret; } -char * -debug_strdup(const char *where, int line, const char *func, const char *ptr) -{ - int size; - char *ret; - - if (!ptr) - return NULL; - size=strlen(ptr)+1; - ret=debug_malloc(where, line, func, size); - memcpy(ret, ptr, size); - return ret; +char *debug_strdup(const char *where, int line, const char *func, const char *ptr) { + int size; + char *ret; + + if (!ptr) + return NULL; + size=strlen(ptr)+1; + ret=debug_malloc(where, line, func, size); + memcpy(ret, ptr, size); + return ret; } -char * -debug_guard(const char *where, int line, const char *func, char *str) -{ - char *ret=debug_strdup(where, line, func, str); - g_free(str); - return ret; +char *debug_guard(const char *where, int line, const char *func, char *str) { + char *ret=debug_strdup(where, line, func, str); + g_free(str); + return ret; } -void -debug_free(const char *where, int line, const char *func, void *ptr) -{ - struct malloc_head *head; - struct malloc_tail *tail; - if (!ptr) - return; - mallocs--; - head=(struct malloc_head *)((unsigned char *)ptr-sizeof(*head)); - tail=(struct malloc_tail *)((unsigned char *)ptr+head->size); - debug_malloc_size-=head->size; - if (head->magic != 0xdeadbeef || tail->magic != 0xdeadbef0) { - fprintf(stderr,"Invalid free from %s:%d %s\n",where,line,func); - } - head->magic=0; - tail->magic=0; - if (head->prev) - head->prev->next=head->next; - else - malloc_heads=head->next; - if (head->next) - head->next->prev=head->prev; - free(head->where); - free(head); +void debug_free(const char *where, int line, const char *func, void *ptr) { + struct malloc_head *head; + struct malloc_tail *tail; + if (!ptr) + return; + mallocs--; + head=(struct malloc_head *)((unsigned char *)ptr-sizeof(*head)); + tail=(struct malloc_tail *)((unsigned char *)ptr+head->size); + debug_malloc_size-=head->size; + if (head->magic != 0xdeadbeef || tail->magic != 0xdeadbef0) { + fprintf(stderr,"Invalid free from %s:%d %s\n",where,line,func); + } + head->magic=0; + tail->magic=0; + if (head->prev) + head->prev->next=head->next; + else + malloc_heads=head->next; + if (head->next) + head->next->prev=head->prev; + free(head->where); + free(head); } -void -debug_free_func(void *ptr) -{ - debug_free("unknown",0,"unknown",ptr); +void debug_free_func(void *ptr) { + debug_free("unknown",0,"unknown",ptr); } void debug_finished(void) { - debug_dump_mallocs(); - g_free(gdb_program); - g_hash_table_destroy(debug_hash); - debug_destroy(); + debug_dump_mallocs(); + g_free(gdb_program); + g_hash_table_destroy(debug_hash); + debug_destroy(); } |