gwenhywfar  4.6.0beta
debug.c
Go to the documentation of this file.
1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs : $Id$
5  begin : Sun Dec 04 2004
6  copyright : (C) 2004 by Martin Preuss
7  email : martin@libchipcard.de
8 
9  ***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU Lesser General Public *
13  * License as published by the Free Software Foundation; either *
14  * version 2.1 of the License, or (at your option) any later version. *
15  * *
16  * This library is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19  * Lesser General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU Lesser General Public *
22  * License along with this library; if not, write to the Free Software *
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
24  * MA 02111-1307 USA *
25  * *
26  ***************************************************************************/
27 
28 
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32 
33 #include "debug_p.h"
34 
35 #include <stdarg.h>
36 #include <assert.h>
37 #include <stdio.h>
38 #ifdef HAVE_STRINGS_H
39 # include <strings.h>
40 #endif
41 #include <gwenhywfar/misc.h>
42 
43 
44 
46 
47 
48 
49 uint32_t GWEN_Debug_PrintDec(char *buffer,
50  uint32_t size,
51  uint32_t num,
52  int leadingZero,
53  uint32_t length) {
54  uint32_t i;
55  uint32_t j;
56  uint32_t k;
57  char numbuf[16];
58  int numOr;
59 
60  /* first convert number */
61  numOr=0;
62  i=0;
63  j=1000000000;
64 
65  while(j) {
66  k=num/j;
67  numOr|=k;
68  if (numOr || leadingZero || j==1) {
69  numbuf[i]=k+'0';
70  i++;
71  }
72  num-=(k*j);
73  j/=10;
74  } /* while j */
75 
76  j=0;
77  if (length) {
78  if (i>length)
79  i=length;
80 
81  /* fill left up to length-(sizeof number) */
82  k=length-i;
83  while(k) {
84  if (j<size) {
85  if (leadingZero)
86  buffer[j]='0';
87  else
88  buffer[j]=' ';
89  }
90  j++;
91  k--;
92  } /* while k */
93  } /* if length */
94 
95  /* copy number */
96  for (k=0; k<i; k++) {
97  if (j<size)
98  buffer[j]=numbuf[k];
99  j++;
100  } /* while i */
101 
102  /* append trailing 0 */
103  if (j<size)
104  buffer[j]=0;
105  j++;
106  /* return length (or possible length) */
107  return j;
108 }
109 
110 
111 
112 uint32_t GWEN_Debug_PrintHex(char *buffer,
113  uint32_t size,
114  uint32_t num,
115  int leadingZero,
116  int up,
117  uint32_t length) {
118  uint32_t i;
119  uint32_t j;
120  uint32_t k;
121  char numbuf[16];
122  int numOr;
123 
124  /* first convert number */
125  numOr=0;
126  i=0;
127  j=8;
128 
129  while(j) {
130  k=(num>>((j-1)*4))&0xf;
131  numOr|=k;
132  if (numOr || leadingZero || j==1) {
133  if (k>9) {
134  if (up)
135  numbuf[i]=k+'0'+7;
136  else
137  numbuf[i]=k+'0'+7+32;
138  }
139  else
140  numbuf[i]=k+'0';
141  i++;
142  }
143  j--;
144  } /* while j */
145 
146  j=0;
147  if (length) {
148  if (i>length)
149  i=length;
150 
151  /* fill left up to length-(sizeof number) */
152  k=length-i;
153  while(k) {
154  if (j<size) {
155  if (leadingZero)
156  buffer[j]='0';
157  else
158  buffer[j]=' ';
159  }
160  j++;
161  k--;
162  } /* while k */
163  } /* if length */
164 
165  /* copy number */
166  for (k=0; k<i; k++) {
167  if (j<size)
168  buffer[j]=numbuf[k];
169  j++;
170  } /* while i */
171 
172  /* append trailing 0 */
173  if (j<size)
174  buffer[j]=0;
175  j++;
176  /* return length (or possible length) */
177  return j;
178 }
179 
180 
181 
182 
183 
184 uint32_t GWEN_Debug_Snprintf(char *buffer,
185  uint32_t size,
186  const char *fmt, ...) {
187  va_list arguments;
188  uint32_t i;
189 
190  i=0;
191  va_start(arguments, fmt);
192  while(*fmt) {
193  if (*fmt=='%') {
194  fmt++;
195  if (*fmt=='%') {
196  /* write character '%' */
197  if (i<size)
198  buffer[i]='%';
199  i++;
200  }
201  else {
202  uint32_t length;
203  int leadingZero;
204 
205  leadingZero=0;
206  length=0;
207 
208  /* read length */
209  if ((*fmt)>='0' && (*fmt)<='9') {
210  /* read number */
211  if (*fmt=='0') {
212  leadingZero=1;
213  }
214  while ((*fmt)>='0' && (*fmt)<='9') {
215  length*=10;
216  length+=*fmt-'0';
217  fmt++;
218  } /* while */
219  }
220 
221  /* read type */
222  switch(*fmt) {
223  /* decimal integer */
224  case 'c':
225  case 'd': {
226  int p;
227 
228  p=va_arg(arguments, int);
229  if (p<0) {
230  if (i<size)
231  buffer[i]='-';
232  i++;
233  p=-p;
234  }
235  i+=GWEN_Debug_PrintDec(buffer+i,
236  size-i,
237  p,
238  leadingZero,
239  length)-1;
240  break;
241  }
242 
243  /* hexadecimal integer */
244  case 'x': {
245  unsigned int p;
246 
247  p=va_arg(arguments, unsigned int);
248  i+=GWEN_Debug_PrintHex(buffer+i,
249  size-i,
250  p,
251  leadingZero,
252  0,
253  length)-1;
254  break;
255  }
256 
257  /* hexadecimal integer */
258  case 'X': {
259  unsigned int p;
260 
261  p=va_arg(arguments, unsigned int);
262  i+=GWEN_Debug_PrintHex(buffer+i,
263  size-i,
264  p,
265  leadingZero,
266  1,
267  length)-1;
268  break;
269  }
270 
271  case 's': {
272  const char *p;
273 
274  p=va_arg(arguments, const char*);
275  if (!p)
276  p="(null)";
277  while(*p) {
278  if (i<size)
279  buffer[i]=*p;
280  i++;
281  p++;
282  } /* while */
283  break;
284  }
285 
286  default:
287  break;
288  } /* switch */
289  }
290  }
291  else {
292  if (i<size)
293  buffer[i]=*fmt;
294  i++;
295  }
296  fmt++;
297  } /* while */
298 
299  /* add trailing 0 */
300  if (i<size)
301  buffer[i]=0;
302  i++;
303  va_end(arguments);
304  return i;
305 }
306 
307 
308 
309 
310 #ifdef NO_VARIADIC_MACROS
311 void DBG_ERROR(const char *dbg_logger, const char *format, ...) {
312  va_list args;
313  char dbg_buffer[256];
314  va_start(args, format);
315  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
316  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
317  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelError, dbg_buffer);
318  va_end(args);
319 }
320 
321 void DBG_WARN(const char *dbg_logger, const char *format, ...) {
322  va_list args;
323  char dbg_buffer[256];
324  va_start(args, format);
325  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
326  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
327  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelWarning, dbg_buffer);
328  va_end(args);
329 }
330 
331 void DBG_NOTICE(const char *dbg_logger, const char *format, ...) {
332  if (GWEN_Logger_GetLevel(dbg_logger)>=GWEN_LoggerLevelNotice) {
333  va_list args;
334  char dbg_buffer[256];
335  va_start(args, format);
336  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
337  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
338  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelNotice, dbg_buffer);
339  va_end(args);
340  }
341 }
342 
343 void DBG_INFO(const char *dbg_logger, const char *format, ...) {
344  if (GWEN_Logger_GetLevel(dbg_logger)>=GWEN_LoggerLevelInfo) {
345  va_list args;
346  char dbg_buffer[256];
347  va_start(args, format);
348  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
349  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
350  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelInfo, dbg_buffer);
351  va_end(args);
352  }
353 }
354 
355 void DBG_DEBUG(const char *dbg_logger, const char *format, ...) {
356 # ifndef DISABLE_DEBUGLOG
357  if (GWEN_Logger_GetLevel(dbg_logger)>=GWEN_LoggerLevelDebug) {
358  va_list args;
359  char dbg_buffer[256];
360  va_start(args, format);
361  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
362  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
363  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelDebug, dbg_buffer);
364  va_end(args);
365  }
366 # endif /* DISABLE_DEBUGLOG */
367 }
368 
369 void DBG_VERBOUS(const char *dbg_logger, const char *format, ...) {
370 # ifndef DISABLE_DEBUGLOG
371  if (GWEN_Logger_GetLevel(dbg_logger)>=GWEN_LoggerLevelVerbous) {
372  va_list args;
373  char dbg_buffer[256];
374  va_start(args, format);
375  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
376  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
377  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelVerbous, dbg_buffer);
378  va_end(args);
379  }
380 # endif /* DISABLE_DEBUGLOG */
381 }
382 
383 #endif /* NO_VARIADIC_MACROS */
384 
385 
386 
387 
388 
389 
390 
391 GWEN_MEMORY_DEBUG_ENTRY*
392 GWEN_MemoryDebugEntry_new(GWEN_MEMORY_DEBUG_ENTRY_TYPE t,
393  const char *wFile,
394  int wLine){
395  GWEN_MEMORY_DEBUG_ENTRY *e;
396 
397  assert(wFile);
398  assert(wLine);
399  GWEN_NEW_OBJECT(GWEN_MEMORY_DEBUG_ENTRY, e);
400  e->file=strdup(wFile);
401  e->line=wLine;
402  e->type=t;
403  return e;
404 }
405 
406 
407 
408 void GWEN_MemoryDebugEntry_free(GWEN_MEMORY_DEBUG_ENTRY *e){
409  if (e) {
410  free(e->file);
411  GWEN_FREE_OBJECT(e);
412  }
413 }
414 
415 
416 
417 
420 
421  assert(name);
423  o->name=strdup(name);
424  return o;
425 }
426 
427 
428 
430  if (o) {
431  GWEN_MEMORY_DEBUG_ENTRY *e;
432 
433  e=o->entries;
434  while(e) {
435  GWEN_MEMORY_DEBUG_ENTRY *next;
436 
437  next=e->next;
439  e=next;
440  }
441  free(o->name);
442  GWEN_FREE_OBJECT(o);
443  }
444 }
445 
446 
447 
450 
452  while(o) {
453  assert(o->name);
454  if (strcasecmp(o->name, name)==0)
455  break;
456  if (o->next==o) {
457  DBG_ERROR(GWEN_LOGDOMAIN, "What ?? Pointing to myself ??");
458  abort();
459  }
460  o=o->next;
461  }
462 
463  return o;
464 }
465 
466 
467 
468 void GWEN_MemoryDebug_Increment(const char *name,
469  const char *wFile,
470  int wLine,
471  int attach){
473  GWEN_MEMORY_DEBUG_ENTRY *e;
474 
475  assert(name);
476  assert(wFile);
477  assert(wLine);
479  if (!o) {
482  e=GWEN_MemoryDebugEntry_new(attach?GWEN_MemoryDebugEntryTypeAttach:
483  GWEN_MemoryDebugEntryTypeCreate,
484  wFile, wLine);
485  GWEN_LIST_ADD(GWEN_MEMORY_DEBUG_ENTRY, e, &(o->entries));
486  o->count++;
487  }
488  else {
489  e=GWEN_MemoryDebugEntry_new(attach?GWEN_MemoryDebugEntryTypeAttach:
490  GWEN_MemoryDebugEntryTypeCreate,
491  wFile, wLine);
492  GWEN_LIST_ADD(GWEN_MEMORY_DEBUG_ENTRY, e, &(o->entries));
493  o->count++;
494  }
495 }
496 
497 
498 
499 void GWEN_MemoryDebug_Decrement(const char *name,
500  const char *wFile,
501  int wLine){
503  GWEN_MEMORY_DEBUG_ENTRY *e;
504 
505  assert(name);
506  assert(wFile);
507  assert(wLine);
509  if (!o) {
511  "Object to be freed not found (%s at %s:%d)",
512  name, wFile, wLine);
515  e=GWEN_MemoryDebugEntry_new(GWEN_MemoryDebugEntryTypeFree,
516  wFile, wLine);
517  GWEN_LIST_ADD(GWEN_MEMORY_DEBUG_ENTRY, e, &(o->entries));
518  o->count--;
519  }
520  else {
521  e=GWEN_MemoryDebugEntry_new(GWEN_MemoryDebugEntryTypeFree,
522  wFile, wLine);
523  GWEN_LIST_ADD(GWEN_MEMORY_DEBUG_ENTRY, e, &(o->entries));
524  o->count--;
525  }
526 }
527 
528 
529 
531  uint32_t mode){
532 
533  DBG_ERROR(0, "Object \"%s\" (count=%ld)",
534  o->name, o->count);
535  if (o->count!=0 || mode==GWEN_MEMORY_DEBUG_MODE_DETAILED) {
536  GWEN_MEMORY_DEBUG_ENTRY *e;
537 
538  if (mode!=GWEN_MEMORY_DEBUG_MODE_SHORT) {
539  e=o->entries;
540  while(e) {
541  const char *s;
542 
543  fprintf(stderr, " ");
544  switch(e->type) {
545  case GWEN_MemoryDebugEntryTypeCreate:
546  s="created";
547  break;
548  case GWEN_MemoryDebugEntryTypeAttach:
549  s="attached";
550  break;
551  case GWEN_MemoryDebugEntryTypeFree:
552  s="freed";
553  break;
554  default:
555  s="<unknown action>";
556  break;
557  }
558  DBG_ERROR(0, " %s at %s:%d", s, e->file, e->line);
559  e=e->next;
560  } /* while e */
561  }
562  }
563 }
564 
565 
566 
567 void GWEN_MemoryDebug_DumpObject(const char *name,
568  uint32_t mode){
570 
571  assert(name);
573  if (!o) {
574  DBG_ERROR(GWEN_LOGDOMAIN, "Object \"%s\" not found", name);
575  }
576  else
578 }
579 
580 
581 
582 long int GWEN_MemoryDebug_GetObjectCount(const char *name){
584 
585  assert(name);
587  if (!o) {
588  DBG_ERROR(GWEN_LOGDOMAIN, "Object \"%s\" not found", name);
589  return 0;
590  }
591  else
592  return o->count;
593 }
594 
595 
596 
597 void GWEN_MemoryDebug_Dump(uint32_t mode){
599 
600  DBG_ERROR(0, "Gwenhywfar Memory Debugger Statistics:");
601  DBG_ERROR(0, "====================================== begin\n");
603  while(o) {
605  o=o->next;
606  }
607  DBG_ERROR(0, "====================================== end\n");
608 }
609 
610 
611 
614 
616  while(o) {
618 
619  next=o->next;
621  o=next;
622  }
624 }
625 
626 
627 
628