Mercurial > libpst
diff src/debug.c @ 202:2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Mon, 18 May 2009 15:55:05 -0700 |
parents | ac6e22c8a9cf |
children | 156cf548c764 |
line wrap: on
line diff
--- a/src/debug.c Sat May 16 10:32:26 2009 -0700 +++ b/src/debug.c Mon May 18 15:55:05 2009 -0700 @@ -1,73 +1,135 @@ #include "define.h" -struct pst_debug_item { - int type; - char * function; - unsigned int line; - char * file; - char * text; - struct pst_debug_item *next; -}; - -static struct pst_debug_item *item_head=NULL, *item_tail=NULL, *item_ptr=NULL, *info_ptr=NULL, *temp_list=NULL; - struct pst_debug_func { char * name; struct pst_debug_func *next; }; -static struct pst_debug_func *func_head=NULL, *func_ptr=NULL; + +#define NUM_COL 32 +#define MAX_DEPTH 32 + +static struct pst_debug_func *func_head = NULL; +static int func_depth = 0; +static char indent[MAX_DEPTH*4+1]; +static FILE *debug_fp = NULL; +#ifdef HAVE_SEMAPHORE_H + static sem_t* debug_mutex = NULL; +#endif + + +void pst_debug_lock() +{ + #ifdef HAVE_SEMAPHORE_H + if (debug_mutex) sem_wait(debug_mutex); + #endif +} -static void pst_debug_write_msg(struct pst_debug_item *item, const char *fmt, va_list *ap, int size); -static void pst_debug_write_hex(struct pst_debug_item *item, char *buf, size_t size, int col); -static void pst_debug_write(); +void pst_debug_unlock() +{ + #ifdef HAVE_SEMAPHORE_H + if (debug_mutex) sem_post(debug_mutex); + #endif +} -static size_t pst_debug_fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream); -static size_t pst_debug_fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream) { - return fwrite(ptr, size, nitems, stream); +void pst_debug_init(const char* fname, void* output_mutex) { + #ifdef HAVE_SEMAPHORE_H + debug_mutex = (sem_t*)output_mutex; + #endif + memset(indent, ' ', MAX_DEPTH); + indent[MAX_DEPTH] = '\0'; + if (debug_fp) pst_debug_close(); + if (!fname) return; + if ((debug_fp = fopen(fname, "wb")) == NULL) { + fprintf(stderr, "Opening of file %s failed\n", fname); + exit(1); + } } -// the largest text size we will store in memory. Otherwise we -// will do a debug_write, then create a new record, and write the -// text body directly to the file -#define MAX_MESSAGE_SIZE 4096 +void pst_debug_func(const char* function) { + struct pst_debug_func *func_ptr = pst_malloc (sizeof(struct pst_debug_func)); + func_ptr->name = strdup(function); + func_ptr->next = func_head; + func_head = func_ptr; + func_depth++; +} + -void pst_debug(const char *fmt, ...) { - va_list ap; - va_start(ap,fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); +void pst_debug_func_ret() { + //remove the head item + struct pst_debug_func *func_ptr = func_head; + if (func_head) { + func_head = func_head->next; + free(func_ptr->name); + free(func_ptr); + func_depth--; + } else { + DIE(("function list is empty!\n")); + } } -#define NUM_COL 30 -void pst_debug_hexdumper(FILE *out, char *buf, size_t size, int col, int delta) { +static void pst_debug_info(int line, const char* file); +static void pst_debug_info(int line, const char* file) { + int le = (func_depth > MAX_DEPTH) ? MAX_DEPTH : func_depth; + if (le > 0) le--; + char *func = (func_head ? func_head->name : "No Function"); + pst_debug_lock(); + fprintf(debug_fp, "%06d %.*s%s %s(%d) ", getpid(), le*4, indent, func, file, line); +} + + +void pst_debug(int line, const char* file, const char *fmt, ...) { + if (debug_fp) { + pst_debug_info(line, file); + va_list ap; + va_start(ap,fmt); + vfprintf(debug_fp, fmt, ap); + va_end(ap); + fflush(debug_fp); + pst_debug_unlock(); + } +} + + +void pst_debug_hexdump(int line, const char *file, const char *buf, size_t size, int cols, int delta) { + if (debug_fp) { + pst_debug_info(line, file); + pst_debug_hexdumper(debug_fp, buf, size, cols, delta); + pst_debug_unlock(); + } +} + + +void pst_debug_hexdumper(FILE *out, const char *buf, size_t size, int cols, int delta) { + int le = (func_depth > MAX_DEPTH) ? MAX_DEPTH : func_depth; size_t off = 0, toff; int count = 0; if (!out) return; // no file - if (col == -1) col = NUM_COL; + + if (cols == -1) cols = NUM_COL; fprintf(out, "\n"); while (off < size) { - fprintf(out, "%06"PRIx64"\t:", (int64_t)(off+delta)); + fprintf(out, "%06d %.*s%06"PRIx64"\t:", getpid(), le*4, indent, (int64_t)(off+delta)); toff = off; - while (count < col && off < size) { + while (count < cols && off < size) { fprintf(out, "%02hhx ", (unsigned char)buf[off]); off++; count++; } off = toff; - while (count < col) { + while (count < cols) { // only happens at end of block to pad the text over to the text column fprintf(out, " "); count++; } count = 0; fprintf(out, ":"); - while (count < col && off < size) { + while (count < cols && off < size) { fprintf(out, "%c", isgraph(buf[off])?buf[off]:'.'); off++; count ++; } @@ -77,172 +139,13 @@ } fprintf(out, "\n"); -} - - -static FILE *debug_fp = NULL; -static unsigned int max_items=DEBUG_MAX_ITEMS, curr_items=0; - - -void pst_debug_init(const char* fname) { - unsigned char version = DEBUG_VERSION; - item_head = item_tail = NULL; - curr_items = 0; - if (debug_fp) pst_debug_close(); - if (!fname) return; - if ((debug_fp = fopen(fname, "wb")) == NULL) { - fprintf(stderr, "Opening of file %s failed\n", fname); - exit(1); - } - pst_debug_fwrite(&version, sizeof(char), 1, debug_fp); -} - - -// function must be called before pst_debug_msg. It sets up the -// structure for the function that follows -void pst_debug_msg_info(int line, const char* file, int type) { - char *x; - if (!debug_fp) return; // no file - info_ptr = (struct pst_debug_item*) pst_malloc(sizeof(struct pst_debug_item)); - info_ptr->type = type; - info_ptr->line = line; - x = (func_head==NULL?"No Function":func_head->name); - info_ptr->function = (char*) pst_malloc(strlen(x)+1); - strcpy(info_ptr->function, x); - - info_ptr->file = (char*) pst_malloc(strlen(file)+1); - strcpy(info_ptr->file, file); - - //put the current record on a temp linked list - info_ptr->next = temp_list; - temp_list = info_ptr; -} - - -void pst_debug_msg_text(const char* fmt, ...) { - va_list ap; - int f, g; - char x[2]; - #ifdef _WIN32 - char *buf = NULL; - #endif - struct pst_debug_item *temp; - if (!debug_fp) return; // no file - // get the record off of the temp_list - info_ptr = temp_list; - if (info_ptr) - temp_list = info_ptr->next; - else { - fprintf(stderr, "NULL info_ptr. ERROR!!\n"); - exit(-2); - } - - #ifdef _WIN32 - // vsnprintf trick doesn't work on msvc. - g = 2000; - f = -1; - while (f < 0) { - buf = realloc(buf, g+1); - va_start(ap, fmt); - f = vsnprintf(buf, g, fmt, ap); - va_end(ap); - g += g/2; - } - free(buf); - #else - // according to glibc 2.1, this should return the req. number of bytes for - // the string - va_start(ap, fmt); - f = vsnprintf(x, 1, fmt, ap); - va_end(ap); - #endif - - if (f > 0 && f < MAX_MESSAGE_SIZE) { - info_ptr->text = (char*) pst_malloc(f+1); - va_start(ap, fmt); - if ((g = vsnprintf(info_ptr->text, f, fmt, ap)) == -1) { - fprintf(stderr, "_debug_msg: Dying! vsnprintf returned -1 for format \"%s\"\n", fmt); - exit(-2); - } - va_end(ap); - info_ptr->text[g] = '\0'; - if (f != g) { - fprintf(stderr, "_debug_msg: f != g\n"); - } - } else if (f > 0) { // it is over the max_message_size then - f += strlen(info_ptr->file)+strlen(info_ptr->function); - temp = info_ptr; - pst_debug_write(); // dump the current messages - info_ptr = temp; - va_start(ap, fmt); - pst_debug_write_msg(info_ptr, fmt, &ap, f); - va_end(ap); - free(info_ptr->function); - free(info_ptr->file); - free(info_ptr); - info_ptr = NULL; - return; - } else { - fprintf(stderr, "_debug_msg: error getting requested size of debug message\n"); - info_ptr->text = "ERROR Saving\n"; - } - - // add to the linked list of pending items - if (!item_head) item_head = info_ptr; - info_ptr->next = NULL; - if (item_tail) item_tail->next = info_ptr; - item_tail = info_ptr; - - if (++curr_items == max_items) { - // here we will jump off and save the contents - pst_debug_write(); - info_ptr = NULL; - } -} - - -void pst_debug_hexdump(char *x, size_t y, int cols, int delta) { - struct pst_debug_item *temp; - if (!debug_fp) return; // no file - info_ptr = temp_list; - if (info_ptr) temp_list = info_ptr->next; - temp = info_ptr; - pst_debug_write(); - info_ptr = temp; - pst_debug_write_hex(info_ptr, x, y, cols); - free(info_ptr->function); - free(info_ptr->file); - free(info_ptr); - info_ptr = NULL; -} - - -void pst_debug_func(const char *function) { - func_ptr = pst_malloc (sizeof(struct pst_debug_func)); - func_ptr->name = pst_malloc(strlen(function)+1); - strcpy(func_ptr->name, function); - func_ptr->next = func_head; - func_head = func_ptr; -} - - -void pst_debug_func_ret() { - //remove the head item - func_ptr = func_head; - if (func_head) { - func_head = func_head->next; - free(func_ptr->name); - free(func_ptr); - } else { - DIE(("function list is empty!\n")); - } + fflush(out); } void pst_debug_close(void) { - pst_debug_write(); while (func_head) { - func_ptr = func_head; + struct pst_debug_func *func_ptr = func_head; func_head = func_head->next; free(func_ptr->name); free(func_ptr); @@ -252,195 +155,6 @@ } -static void pst_debug_write() { - size_t size, ptr, funcname, filename, text, end; - char *buf = NULL, rec_type; - if (!debug_fp) return; // no file - int64_t index_pos = ftello(debug_fp); - int64_t file_pos = index_pos; - // add 2. One for the pointer to the next index, - // one for the count of this index - int index_size = ((curr_items+2) * sizeof(int64_t)); - int64_t *index; - int index_ptr = 0; - struct pst_debug_file_rec_m mfile_rec; - struct pst_debug_file_rec_l lfile_rec; - - if (curr_items == 0) return; // no items to write. - - index = (int64_t*)pst_malloc(index_size); - memset(index, 0, index_size); // valgrind, avoid writing uninitialized data - file_pos += index_size; - // write the index first, we will re-write it later, but - // we want to allocate the space - pst_debug_fwrite(index, index_size, 1, debug_fp); - index[index_ptr++] = curr_items; - - item_ptr = item_head; - while (item_ptr) { - file_pos = ftello(debug_fp); - index[index_ptr++] = file_pos; - size = strlen(item_ptr->function) + - strlen(item_ptr->file) + - strlen(item_ptr->text) + 3; //for the three \0s - if (buf) free(buf); - buf = pst_malloc(size+1); - ptr = 0; - funcname=ptr; - ptr += sprintf(&(buf[ptr]), "%s", item_ptr->function)+1; - filename=ptr; - ptr += sprintf(&(buf[ptr]), "%s", item_ptr->file)+1; - text=ptr; - ptr += sprintf(&(buf[ptr]), "%s", item_ptr->text)+1; - end=ptr; - if (end > USHRT_MAX) { // bigger than can be stored in a short - rec_type = 'L'; - pst_debug_fwrite(&rec_type, sizeof(char), 1, debug_fp); - lfile_rec.type = item_ptr->type; - lfile_rec.line = item_ptr->line; - lfile_rec.funcname = funcname; - lfile_rec.filename = filename; - lfile_rec.text = text; - lfile_rec.end = end; - pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); - } else { - rec_type = 'M'; - pst_debug_fwrite(&rec_type, sizeof(char), 1, debug_fp); - mfile_rec.type = item_ptr->type; - mfile_rec.line = item_ptr->line; - mfile_rec.funcname = funcname; - mfile_rec.filename = filename; - mfile_rec.text = text; - mfile_rec.end = end; - pst_debug_fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); - } - pst_debug_fwrite(buf, ptr, 1, debug_fp); - if (buf) free(buf); buf = NULL; - item_head = item_ptr->next; - free(item_ptr->function); - free(item_ptr->file); - free(item_ptr->text); - free(item_ptr); - item_ptr = item_head; - } - curr_items = 0; - index[index_ptr] = ftello(debug_fp); - - // we should now have a complete index - fseeko(debug_fp, index_pos, SEEK_SET); - pst_debug_fwrite(index, index_size, 1, debug_fp); - fseeko(debug_fp, 0, SEEK_END); - item_ptr = item_head = item_tail = NULL; - free(index); - if (buf) free(buf); -} - - -static void pst_debug_write_msg(struct pst_debug_item *item, const char *fmt, va_list *ap, int size) { - struct pst_debug_file_rec_l lfile_rec; - struct pst_debug_file_rec_m mfile_rec; - unsigned char rec_type; - int index_size = 3 * sizeof(int64_t); - int64_t index[3]; - int64_t index_pos, file_pos; - char zero = '\0'; - unsigned int end; - if (!debug_fp) return; // no file - index[0] = 1; // only one item in this index - index[1] = 0; // valgrind, avoid writing uninitialized data - index[2] = 0; // "" - index_pos = ftello(debug_fp); - pst_debug_fwrite(index, index_size, 1, debug_fp); - - index[1] = ftello(debug_fp); - - if (size > USHRT_MAX) { // bigger than can be stored in a short - rec_type = 'L'; - pst_debug_fwrite(&rec_type, sizeof(char), 1, debug_fp); - lfile_rec.type = item->type; - lfile_rec.line = item->line; - lfile_rec.funcname = 0; - lfile_rec.filename = strlen(item->function)+1; - lfile_rec.text = lfile_rec.filename+strlen(item->file)+1; - lfile_rec.end = 0; // valgrind, avoid writing uninitialized data - pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); - } else { - rec_type = 'M'; - pst_debug_fwrite(&rec_type, sizeof(char), 1, debug_fp); - mfile_rec.type = item->type; - mfile_rec.line = item->line; - mfile_rec.funcname = 0; - mfile_rec.filename = strlen(item->function)+1; - mfile_rec.text = mfile_rec.filename+strlen(item->file)+1; - mfile_rec.end = 0; // valgrind, avoid writing uninitialized data - pst_debug_fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); - } - file_pos = ftello(debug_fp); - pst_debug_fwrite(item->function, strlen(item->function)+1, 1, debug_fp); - pst_debug_fwrite(item->file, strlen(item->file)+1, 1, debug_fp); - vfprintf(debug_fp, fmt, *ap); - pst_debug_fwrite(&zero, 1, 1, debug_fp); - - end = (unsigned int) (ftello(debug_fp) - file_pos); - - index[2] = ftello(debug_fp); - fseeko(debug_fp, index_pos, SEEK_SET); - pst_debug_fwrite(index, index_size, 1, debug_fp); - if (size > USHRT_MAX) { - pst_debug_fwrite(&rec_type, sizeof(char), 1, debug_fp); - lfile_rec.end = end; - pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); - } else { - pst_debug_fwrite(&rec_type, sizeof(char), 1, debug_fp); - mfile_rec.end = end; - pst_debug_fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); - } - fseeko(debug_fp, 0, SEEK_END); -} - - -void pst_debug_write_hex(struct pst_debug_item *item, char *buf, size_t size, int col) { - struct pst_debug_file_rec_l lfile_rec; - unsigned char rec_type; - int index_size = 3 * sizeof(int64_t); - int64_t index_pos, file_pos, index[3]; - char zero='\0'; - if (!debug_fp) return; // no file - index[0] = 1; // only one item in this index run - index[1] = 0; // valgrind, avoid writing uninitialized data - index[2] = 0; // "" - index_pos = ftello(debug_fp); - pst_debug_fwrite(index, index_size, 1, debug_fp); - index[1] = ftello(debug_fp); - - // always use the long - rec_type = 'L'; - pst_debug_fwrite(&rec_type, sizeof(char), 1, debug_fp); - lfile_rec.funcname = 0; - lfile_rec.filename = strlen(item->function)+1; - lfile_rec.text = lfile_rec.filename+strlen(item->file)+1; - lfile_rec.end = 0; // valgrind, avoid writing uninitialized data - lfile_rec.line = item->line; - lfile_rec.type = item->type; - pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); - - file_pos = ftello(debug_fp); - pst_debug_fwrite(item->function, strlen(item->function)+1, 1, debug_fp); - pst_debug_fwrite(item->file, strlen(item->file)+1, 1, debug_fp); - - pst_debug_hexdumper(debug_fp, buf, size, col, 0); - pst_debug_fwrite(&zero, 1, 1, debug_fp); - lfile_rec.end = ftello(debug_fp) - file_pos; - - index[2] = ftello(debug_fp); - fseeko(debug_fp, index_pos, SEEK_SET); - pst_debug_fwrite(index, index_size, 1, debug_fp); - pst_debug_fwrite(&rec_type, sizeof(char), 1, debug_fp); - pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); - fseeko(debug_fp, 0, SEEK_END); -} - - void *pst_malloc(size_t size) { void *mem = malloc(size); if (!mem) {