debug.c

Go to the documentation of this file.
00001 #include "define.h"
00002 
00003 
00004 struct pst_debug_func {
00005     char * name;
00006     struct pst_debug_func *next;
00007 };
00008 
00009 
00010 #define NUM_COL 32
00011 #define MAX_DEPTH 32
00012 
00013 static struct pst_debug_func *func_head = NULL;
00014 static int func_depth = 0;
00015 static int pst_debuglevel = 0;
00016 static char indent[MAX_DEPTH*4+1];
00017 static FILE *debug_fp = NULL;
00018 #ifdef HAVE_SEMAPHORE_H
00019     static sem_t* debug_mutex = NULL;
00020 #endif
00021 
00022 
00023 void pst_debug_setlevel(int level)
00024 {
00025   pst_debuglevel = level;
00026 }
00027 
00028 void pst_debug_lock()
00029 {
00030     #ifdef HAVE_SEMAPHORE_H
00031         if (debug_mutex) sem_wait(debug_mutex);
00032     #endif
00033 }
00034 
00035 
00036 void pst_debug_unlock()
00037 {
00038     #ifdef HAVE_SEMAPHORE_H
00039         if (debug_mutex) sem_post(debug_mutex);
00040     #endif
00041 }
00042 
00043 
00044 void pst_debug_init(const char* fname, void* output_mutex) {
00045     #ifdef HAVE_SEMAPHORE_H
00046         debug_mutex = (sem_t*)output_mutex;
00047     #endif
00048     memset(indent, ' ', MAX_DEPTH*4);
00049     indent[MAX_DEPTH*4] = '\0';
00050     if (debug_fp) pst_debug_close();
00051     if (!fname) return;
00052     if ((debug_fp = fopen(fname, "wb")) == NULL) {
00053         fprintf(stderr, "Opening of file %s failed\n", fname);
00054         exit(1);
00055     }
00056 }
00057 
00058 
00059 void pst_debug_func(int level, const char* function) {
00060     if (pst_debuglevel > level) return;
00061     struct pst_debug_func *func_ptr = pst_malloc (sizeof(struct pst_debug_func));
00062     func_ptr->name = strdup(function);
00063     func_ptr->next = func_head;
00064     func_head = func_ptr;
00065     func_depth++;
00066 }
00067 
00068 
00069 void pst_debug_func_ret(int level) {
00070     if (pst_debuglevel > level) return;
00071     //remove the head item
00072     struct pst_debug_func *func_ptr = func_head;
00073     if (func_head) {
00074         func_head = func_head->next;
00075         free(func_ptr->name);
00076         free(func_ptr);
00077         func_depth--;
00078     } else {
00079         DIE(("function list is empty!\n"));
00080     }
00081 }
00082 
00083 
00084 static void pst_debug_info(int level, int line, const char* file);
00085 static void pst_debug_info(int level, int line, const char* file) {
00086     if (pst_debuglevel > level) return;
00087     int le = (func_depth > MAX_DEPTH) ? MAX_DEPTH : func_depth;
00088     if (le > 0) le--;
00089     char *func = (func_head ? func_head->name : "No Function");
00090     pst_debug_lock();
00091     fprintf(debug_fp, "%06d %.*s%s %s(%d) ", getpid(), le*4, indent, func, file, line);
00092 }
00093 
00094 
00095 void pst_debug(int level, int line, const char* file, const char *fmt, ...) {
00096     if (pst_debuglevel > level) return;
00097     if (debug_fp) {
00098         pst_debug_info(level, line, file);
00099         va_list ap;
00100         va_start(ap,fmt);
00101         vfprintf(debug_fp, fmt, ap);
00102         va_end(ap);
00103         fflush(debug_fp);
00104         pst_debug_unlock();
00105     }
00106 }
00107 
00108 
00109 void pst_debug_hexdump(int level, int line, const char *file, const char *buf, size_t size, int cols, int delta) {
00110     if (pst_debuglevel > level) return;
00111     if (debug_fp) {
00112         pst_debug_info(level, line, file);
00113         pst_debug_hexdumper(debug_fp, buf, size, cols, delta);
00114         pst_debug_unlock();
00115     }
00116 }
00117 
00118 
00119 void pst_debug_hexdumper(FILE *out, const char *buf, size_t size, int cols, int delta) {
00120     int le = (func_depth > MAX_DEPTH) ? MAX_DEPTH : func_depth;
00121     size_t off = 0, toff;
00122     int count = 0;
00123 
00124     if (!out) return;   // no file
00125 
00126     if (cols == -1) cols = NUM_COL;
00127     fprintf(out, "\n");
00128     while (off < size) {
00129         fprintf(out, "%06d %.*s%06"PRIx64"\t:", getpid(), le*4, indent, (int64_t)(off+delta));
00130         toff = off;
00131         while (count < cols && off < size) {
00132             fprintf(out, "%02hhx ", (unsigned char)buf[off]);
00133             off++; count++;
00134         }
00135         off = toff;
00136         while (count < cols) {
00137             // only happens at end of block to pad the text over to the text column
00138             fprintf(out, "   ");
00139             count++;
00140         }
00141         count = 0;
00142         fprintf(out, ":");
00143         while (count < cols && off < size) {
00144             fprintf(out, "%c", isgraph(buf[off])?buf[off]:'.');
00145             off++; count ++;
00146         }
00147 
00148         fprintf(out, "\n");
00149         count=0;
00150     }
00151 
00152     fprintf(out, "\n");
00153     fflush(out);
00154 }
00155 
00156 
00157 void pst_debug_close(void) {
00158     while (func_head) {
00159         struct pst_debug_func *func_ptr = func_head;
00160         func_head = func_head->next;
00161         free(func_ptr->name);
00162         free(func_ptr);
00163     }
00164     if (debug_fp) fclose(debug_fp);
00165     debug_fp = NULL;
00166 }
00167 
00168 
00169 void *pst_malloc(size_t size) {
00170     void *mem = malloc(size);
00171     if (!mem) {
00172         fprintf(stderr, "pst_malloc: Out Of memory [req: %ld]\n", (long)size);
00173         exit(1);
00174     }
00175     return mem;
00176 }
00177 
00178 
00179 void *pst_realloc(void *ptr, size_t size) {
00180     void *mem = realloc(ptr, size);
00181     if (!mem) {
00182         fprintf(stderr, "pst_realloc: Out Of memory [req: %ld]\n", (long)size);
00183         exit(1);
00184     }
00185     return mem;
00186 }

Generated on 6 Jul 2016 for 'LibPst' by  doxygen 1.6.1