'LibPst'
debug.c
Go to the documentation of this file.
1 #include "define.h"
2 
3 
4 struct pst_debug_func {
5  char * name;
7 };
8 
9 
10 #define NUM_COL 32
11 #define MAX_DEPTH 32
12 
13 static struct pst_debug_func *func_head = NULL;
14 static int func_depth = 0;
15 static int pst_debuglevel = 0;
16 static char indent[MAX_DEPTH*4+1];
17 static FILE *debug_fp = NULL;
18 #ifdef HAVE_SEMAPHORE_H
19  static sem_t* debug_mutex = NULL;
20 #endif
21 
22 
23 void pst_debug_setlevel(int level)
24 {
25  pst_debuglevel = level;
26 }
27 
29 {
30  #ifdef HAVE_SEMAPHORE_H
31  if (debug_mutex) sem_wait(debug_mutex);
32  #endif
33 }
34 
35 
37 {
38  #ifdef HAVE_SEMAPHORE_H
39  if (debug_mutex) sem_post(debug_mutex);
40  #endif
41 }
42 
43 
44 void pst_debug_init(const char* fname, void* output_mutex) {
45  #ifdef HAVE_SEMAPHORE_H
46  debug_mutex = (sem_t*)output_mutex;
47  #endif
48  memset(indent, ' ', MAX_DEPTH*4);
49  indent[MAX_DEPTH*4] = '\0';
51  if (!fname) return;
52  if ((debug_fp = fopen(fname, "wb")) == NULL) {
53  fprintf(stderr, "Opening of file %s failed\n", fname);
54  exit(1);
55  }
56 }
57 
58 
59 void pst_debug_func(int level, const char* function) {
60  if (pst_debuglevel > level) return;
61  struct pst_debug_func *func_ptr = pst_malloc (sizeof(struct pst_debug_func));
62  func_ptr->name = strdup(function);
63  func_ptr->next = func_head;
64  func_head = func_ptr;
65  func_depth++;
66 }
67 
68 
69 void pst_debug_func_ret(int level) {
70  if (pst_debuglevel > level) return;
71  //remove the head item
72  struct pst_debug_func *func_ptr = func_head;
73  if (func_head) {
75  free(func_ptr->name);
76  free(func_ptr);
77  func_depth--;
78  } else {
79  DIE(("function list is empty!\n"));
80  }
81 }
82 
83 
84 static void pst_debug_info(int level, int line, const char* file);
85 static void pst_debug_info(int level, int line, const char* file) {
86  if (pst_debuglevel > level) return;
87  int le = (func_depth > MAX_DEPTH) ? MAX_DEPTH : func_depth;
88  if (le > 0) le--;
89  char *func = (func_head ? func_head->name : "No Function");
91  fprintf(debug_fp, "%06d %.*s%s %s(%d) ", getpid(), le*4, indent, func, file, line);
92 }
93 
94 
95 void pst_debug(int level, int line, const char* file, const char *fmt, ...) {
96  if (pst_debuglevel > level) return;
97  if (debug_fp) {
98  pst_debug_info(level, line, file);
99  va_list ap;
100  va_start(ap,fmt);
101  vfprintf(debug_fp, fmt, ap);
102  va_end(ap);
103  fflush(debug_fp);
105  }
106 }
107 
108 
109 void pst_debug_hexdump(int level, int line, const char *file, const char *buf, size_t size, int cols, int delta) {
110  if (pst_debuglevel > level) return;
111  if (debug_fp) {
112  pst_debug_info(level, line, file);
113  pst_debug_hexdumper(debug_fp, buf, size, cols, delta);
115  }
116 }
117 
118 
119 void pst_debug_hexdumper(FILE *out, const char *buf, size_t size, int cols, int delta) {
120  int le = (func_depth > MAX_DEPTH) ? MAX_DEPTH : func_depth;
121  size_t off = 0, toff;
122  int count = 0;
123 
124  if (!out) return; // no file
125 
126  if (cols == -1) cols = NUM_COL;
127  fprintf(out, "\n");
128  while (off < size) {
129  fprintf(out, "%06d %.*s%06"PRIx64"\t:", getpid(), le*4, indent, (int64_t)(off+delta));
130  toff = off;
131  while (count < cols && off < size) {
132  fprintf(out, "%02hhx ", (unsigned char)buf[off]);
133  off++; count++;
134  }
135  off = toff;
136  while (count < cols) {
137  // only happens at end of block to pad the text over to the text column
138  fprintf(out, " ");
139  count++;
140  }
141  count = 0;
142  fprintf(out, ":");
143  while (count < cols && off < size) {
144  fprintf(out, "%c", isgraph(buf[off])?buf[off]:'.');
145  off++; count ++;
146  }
147 
148  fprintf(out, "\n");
149  count=0;
150  }
151 
152  fprintf(out, "\n");
153  fflush(out);
154 }
155 
156 
157 void pst_debug_close(void) {
158  while (func_head) {
159  struct pst_debug_func *func_ptr = func_head;
161  free(func_ptr->name);
162  free(func_ptr);
163  }
164  if (debug_fp) fclose(debug_fp);
165  debug_fp = NULL;
166 }
167 
168 
169 void *pst_malloc(size_t size) {
170  void *mem = malloc(size);
171  if (!mem) {
172  fprintf(stderr, "pst_malloc: Out Of memory [req: %ld]\n", (long)size);
173  exit(1);
174  }
175  return mem;
176 }
177 
178 
179 void *pst_realloc(void *ptr, size_t size) {
180  void *mem = realloc(ptr, size);
181  if (!mem) {
182  fprintf(stderr, "pst_realloc: Out Of memory [req: %ld]\n", (long)size);
183  exit(1);
184  }
185  return mem;
186 }
void pst_debug_close(void)
Definition: debug.c:157
void pst_debug_unlock()
Definition: debug.c:36
#define DIE(x)
Definition: define.h:160
void pst_debug_hexdumper(FILE *out, const char *buf, size_t size, int cols, int delta)
Definition: debug.c:119
static struct pst_debug_func * func_head
Definition: debug.c:13
void * pst_malloc(size_t size)
Definition: debug.c:169
struct pst_debug_func * next
Definition: debug.c:6
static int pst_debuglevel
Definition: debug.c:15
void pst_debug_init(const char *fname, void *output_mutex)
Definition: debug.c:44
void pst_debug_func(int level, const char *function)
Definition: debug.c:59
void pst_debug_func_ret(int level)
Definition: debug.c:69
#define NUM_COL
Definition: debug.c:10
static FILE * debug_fp
Definition: debug.c:17
char * name
Definition: debug.c:5
static sem_t * debug_mutex
Definition: debug.c:19
static void pst_debug_info(int level, int line, const char *file)
Definition: debug.c:85
static int func_depth
Definition: debug.c:14
void pst_debug(int level, int line, const char *file, const char *fmt,...)
Definition: debug.c:95
#define MAX_DEPTH
Definition: debug.c:11
static char indent[32 *4+1]
Definition: debug.c:16
void * pst_realloc(void *ptr, size_t size)
Definition: debug.c:179
void pst_debug_lock()
Definition: debug.c:28
void pst_debug_hexdump(int level, int line, const char *file, const char *buf, size_t size, int cols, int delta)
Definition: debug.c:109
void pst_debug_setlevel(int level)
Definition: debug.c:23