Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
log.c
Go to the documentation of this file.
1 ;/*
2  * Copyright (c) 2012, 2013, 2014 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include <stdio.h>
20 #include <stdarg.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <error.h>
24 #include <argp.h>
25 
26 #include "log.h"
27 
28 static int vmi_log_level = -1;
29 static int vmi_warn_level = -1;
30 static log_flags_t vmi_log_flags[32] = {
31  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
32 };
33 
34 void vmi_set_log_level(int level) {
35  vmi_log_level = level;
36 }
37 
38 void vmi_inc_log_level(void) {
39  ++vmi_log_level;
40 }
41 
42 void vmi_set_warn_level(int level) {
43  vmi_warn_level = level;
44 }
45 
46 void vmi_inc_warn_level(void) {
47  ++vmi_warn_level;
48 }
49 
51  if (areas & LA_LIB)
52  vmi_log_flags[LAB_LIB] = flags;
53  if (areas & LA_DEBUG)
54  vmi_log_flags[LAB_DEBUG] = flags;
55  if (areas & LA_TARGET)
56  vmi_log_flags[LAB_TARGET] = flags;
57  if (areas & LA_PROBE)
58  vmi_log_flags[LAB_PROBE] = flags;
59  if (areas & LA_XML)
60  vmi_log_flags[LAB_XML] = flags;
61  if (areas & LA_ANL)
62  vmi_log_flags[LAB_ANL] = flags;
63  if (areas & LA_USER)
64  vmi_log_flags[LAB_USER] = flags;
65 }
66 
68  if (areas & LA_LIB)
69  vmi_log_flags[LAB_LIB] |= flags;
70  if (areas & LA_DEBUG)
71  vmi_log_flags[LAB_DEBUG] |= flags;
72  if (areas & LA_TARGET)
73  vmi_log_flags[LAB_TARGET] |= flags;
74  if (areas & LA_PROBE)
75  vmi_log_flags[LAB_PROBE] |= flags;
76  if (areas & LA_XML)
77  vmi_log_flags[LAB_XML] |= flags;
78  if (areas & LA_ANL)
79  vmi_log_flags[LAB_ANL] |= flags;
80  if (areas & LA_USER)
81  vmi_log_flags[LAB_USER] |= flags;
82 }
83 
84 int vmi_set_log_area_flaglist(char *flaglist,char *separator) {
85  char *flag = NULL;
86  char *saveptr = NULL;
87  log_areas_t areas;
88  log_flags_t flags;
89 
90  if (!separator)
91  separator = ",";
92 
93  while ((flag = strtok_r(!saveptr ? flaglist : NULL,separator,&saveptr))) {
94  if (vmi_log_get_flag_val(flag,&areas,&flags))
95  return -1;
96  else
97  vmi_set_log_area_flags(areas,flags);
98  }
99 
100  return 0;
101 }
102 
103 int vmi_add_log_area_flaglist(char *flaglist,char *separator) {
104  char *flag = NULL;
105  char *saveptr = NULL;
106  log_areas_t areas;
107  log_flags_t flags;
108 
109  if (!separator)
110  separator = ",";
111 
112  while ((flag = strtok_r(!saveptr ? flaglist : NULL,separator,&saveptr))) {
113  areas = 0;
114  flags = 0;
115  if (vmi_log_get_flag_val(flag,&areas,&flags))
116  return -1;
117  else
118  vmi_add_log_area_flags(areas,flags);
119  }
120 
121  return 0;
122 }
123 
124 static char *log_flag_stringmap_none[] = { "NONE",NULL };
125 static char *log_flag_stringmap_lib[] = {
126  "CLMATCH","CLRANGE","RFILTER","WAITPIPE","EVLOOP","MONITOR","ROP","CFI",
127  "REGCACHE",NULL
128 };
129 static char *log_flag_stringmap_debug[] = {
130  "DFILE","SYMBOL","SCOPE","LOC","LOOKUP","DWARF","DWARFATTR",
131  "DWARFSOPS","DWARFOPS","CFA","OTHER","ELF","BFILE",NULL
132 };
133 static char *log_flag_stringmap_target[] = {
134  "TARGET","SPACE","REGION","LOOKUP","LOC","OTHER","SYMBOL","MEMCACHE","UNW",
135  "LUP","XV","OSP","PHP","GDB","DISASM","THREAD","OS","PROCESS","APPLICATION",
136  "OSLINUX",NULL
137 };
138 static char *log_flag_stringmap_probe[] = {
139  "PROBE","PROBEPOINT","ACTION",NULL
140 };
141 static char *log_flag_stringmap_xml[] = {
142  "XML","RPC","SVC","PROXYREQ",NULL
143 };
144 static char *log_flag_stringmap_anl[] = {
145  "ANL",NULL
146 };
147 
148 static char **log_flag_stringmap[32] = {
149  log_flag_stringmap_none,
150  log_flag_stringmap_lib,
151  log_flag_stringmap_debug,
152  log_flag_stringmap_target,
153  log_flag_stringmap_probe,
154  log_flag_stringmap_xml,
155  log_flag_stringmap_anl,
156  NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
157  NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
158  /* Will get set to an array of user flags if they call
159  * vmi_set_user_area_flags().
160  */
161  NULL,
162 };
163 
164 void vmi_set_user_area_flags(char **names) {
165  log_flag_stringmap[LAB_USER] = names;
166 }
167 
168 int vmi_log_get_flag_val(char *flag,log_areas_t *areaval,log_flags_t *flagval) {
169  unsigned int i;
170  int found;
171  char *_dup = NULL;
172  char *_area;
173  char *_flag;
174  char **_rflag;
175  char *_idx;
176  char **subarray = NULL;
177  log_area_bits_t areabits = 0;
178 
179  /* Check the LOG_*_ALL flags first. */
180  if (strcmp("ALL",flag) == 0) {
181  if (flagval)
182  *flagval = LF_ALL;
183  if (areaval)
184  *areaval = LA_ALL;
185  return 0;
186  }
187  else if (strcmp("L_ALL",flag) == 0) {
188  if (flagval)
189  *flagval = LF_L_ALL;
190  if (areaval)
191  *areaval = LA_LIB;
192  return 0;
193  }
194  else if (strcmp("D_ALL",flag) == 0) {
195  if (flagval)
196  *flagval = LF_D_ALL;
197  if (areaval)
198  *areaval = LA_DEBUG;
199  return 0;
200  }
201  else if (strcmp("T_ALL",flag) == 0) {
202  if (flagval)
203  *flagval = LF_T_ALL;
204  if (areaval)
205  *areaval = LA_TARGET;
206  return 0;
207  }
208  else if (strcmp("P_ALL",flag) == 0) {
209  if (flagval)
210  *flagval = LF_P_ALL;
211  if (areaval)
212  *areaval = LA_PROBE;
213  return 0;
214  }
215  else if (strcmp("X_ALL",flag) == 0) {
216  if (flagval)
217  *flagval = LF_X_ALL;
218  if (areaval)
219  *areaval = LA_XML;
220  return 0;
221  }
222  else if (strcmp("A_ALL",flag) == 0) {
223  if (flagval)
224  *flagval = LF_A_ALL;
225  if (areaval)
226  *areaval = LA_ANL;
227  return 0;
228  }
229  else if (strcmp("U_ALL",flag) == 0) {
230  if (flagval)
231  *flagval = LF_U_ALL;
232  if (areaval)
233  *areaval = LA_USER;
234  return 0;
235  }
236 
237  if ((_idx = index(flag,'_'))) {
238  _dup = strdup(flag);
239 
240  *_idx = '\0';
241  _area = _dup;
242  _flag = _idx + 1;
243 
244  if (*_area == 'L')
245  areabits = LAB_LIB;
246  else if (*_area == 'D')
247  areabits = LAB_DEBUG;
248  else if (*_area == 'T')
249  areabits = LAB_TARGET;
250  else if (*_area == 'P')
251  areabits = LAB_PROBE;
252  else if (*_area == 'X')
253  areabits = LAB_XML;
254  else if (*_area == 'A')
255  areabits = LAB_ANL;
256  else if (*_area == 'U')
257  areabits = LAB_USER;
258  else {
259  verror("bad flag '%s': no such area prefix '%s'!\n",flag,_area);
260  free(_dup);
261  return -1;
262  }
263 
264  subarray = log_flag_stringmap[areabits];
265 
266  if (!subarray) {
267  verror("bad flag '%s': area '%s' has no flags!\n",flag,_area);
268  free(_dup);
269  return -1;
270  }
271 
272  i = 0;
273  found = 0;
274  while ((_rflag = subarray++) && *_rflag) {
275  if (strcmp(_flag,*_rflag) == 0) {
276  found = 1;
277  break;
278  }
279  ++i;
280  }
281 
282  if (!found) {
283  verror("area '%s' has no flag '%s'!\n",_area,_flag);
284  free(_dup);
285  return -1;
286  }
287  else {
288  if (areaval)
289  *areaval = 1 << areabits;
290  if (flagval)
291  *flagval = 1 << i;
292  free(_dup);
293  return 0;
294  }
295  }
296  else {
297  /* Assume it is a user-specific flag. */
298  areabits = LAB_USER;
299  subarray = log_flag_stringmap[areabits];
300  _area = "U";
301  _flag = flag;
302 
303  if (!subarray) {
304  verror("bad flag '%s': area '%s' has no flags!\n",flag,_area);
305  free(_dup);
306  return -1;
307  }
308 
309  i = 0;
310  found = 0;
311  while ((_rflag = ++subarray) && *_rflag) {
312  if (strcmp(_flag,*_rflag) == 0) {
313  found = 1;
314  break;
315  }
316  ++i;
317  }
318 
319  if (!found) {
320  verror("area '%s' has no flag '%s'!\n",_area,_flag);
321  free(_dup);
322  return -1;
323  }
324  else {
325  if (areaval)
326  *areaval = 1 << areabits;
327  if (flagval)
328  *flagval = 1 << i;
329  free(_dup);
330  return 0;
331  }
332  }
333 }
334 
335 int vdebug_is_on(int level,log_areas_t areas,log_flags_t flags) {
336  if (vmi_log_level < level)
337  return 0;
338  else {
339  if (areas & LA_LIB && vmi_log_flags[LAB_LIB] & flags)
340  return 1;
341  else if (areas & LA_DEBUG && vmi_log_flags[LAB_DEBUG] & flags)
342  return 1;
343  else if (areas & LA_TARGET && vmi_log_flags[LAB_TARGET] & flags)
344  return 1;
345  else if (areas & LA_PROBE && vmi_log_flags[LAB_PROBE] & flags)
346  return 1;
347  else if (areas & LA_XML && vmi_log_flags[LAB_XML] & flags)
348  return 1;
349  else if (areas & LA_ANL && vmi_log_flags[LAB_ANL] & flags)
350  return 1;
351  else if (areas & LA_USER && vmi_log_flags[LAB_USER] & flags)
352  return 1;
353  }
354  return 0;
355 }
356 
357 int vwarn_is_on(int level,log_areas_t areas,log_flags_t flags) {
358  if (vmi_warn_level < level)
359  return 0;
360  else {
361  if (areas & LA_LIB && vmi_log_flags[LAB_LIB] & flags)
362  return 1;
363  else if (areas & LA_DEBUG && vmi_log_flags[LAB_DEBUG] & flags)
364  return 1;
365  else if (areas & LA_TARGET && vmi_log_flags[LAB_TARGET] & flags)
366  return 1;
367  else if (areas & LA_PROBE && vmi_log_flags[LAB_PROBE] & flags)
368  return 1;
369  else if (areas & LA_XML && vmi_log_flags[LAB_XML] & flags)
370  return 1;
371  else if (areas & LA_ANL && vmi_log_flags[LAB_ANL] & flags)
372  return 1;
373  else if (areas & LA_USER && vmi_log_flags[LAB_USER] & flags)
374  return 1;
375  }
376  return 0;
377 }
378 
379 void _vmi_debug(int level,log_areas_t areas,log_flags_t flags,char *format,...) {
380  va_list args;
381  if (!vdebug_is_on(level,areas,flags))
382  return;
383  va_start(args, format);
384  vfprintf(stderr, format, args);
385  fflush(stderr);
386  va_end(args);
387 }
388 
389 void _vmi_warn(int level,log_areas_t areas,log_flags_t flags,char *format,...) {
390  va_list args;
391  if (!vwarn_is_on(level,areas,flags))
392  return;
393  va_start(args, format);
394  vfprintf(stderr, format, args);
395  fflush(stderr);
396  va_end(args);
397 }
398 
399 /*
400  * Log arg parsing stuff.
401  */
402 struct argp_option log_argp_opts[] = {
403  { "debug",'d',"LEVEL",OPTION_ARG_OPTIONAL,
404  "Set/increase the debugging level.",-2 },
405  //{ "debug",'d',0,0,"Increase the debugging level.",-2 },
406  { "log-flags",'l',"FLAG,FLAG,...",0,"Set the debugging flags",-2 },
407  { "warn",'w',"LEVEL",OPTION_ARG_OPTIONAL,
408  "Set/increase the warning level.",-2 },
409  //{ "warn",'w',0,0,"Increase the warning level.",-2 },
410  { 0,0,0,0,0,0 }
411 };
412 
414  NULL,NULL,NULL,NULL,NULL };
415 
416 error_t log_argp_parse_opt(int key,char *arg,struct argp_state *state) {
417  char *endptr = NULL;
418 
419  switch (key) {
420  case ARGP_KEY_ARG:
421  case ARGP_KEY_ARGS:
422  return ARGP_ERR_UNKNOWN;
423  case ARGP_KEY_END:
424  case ARGP_KEY_NO_ARGS:
425  case ARGP_KEY_SUCCESS:
426  case ARGP_KEY_ERROR:
427  case ARGP_KEY_FINI:
428  return 0;
429  case ARGP_KEY_INIT:
430  /* No child state to initialize. */
431  return 0;
432 
433  case 'd':
434  if (arg) {
435  errno = 0;
436  vmi_log_level = (int)strtol(arg,&endptr,0);
437  if (errno || endptr == arg) {
438  /*
439  * Try to count up any 'd' chars. Grab the one that got
440  * us here too.
441  */
442  ++vmi_log_level;
443  while (*arg != '\0') {
444  if (*arg == 'd')
445  ++vmi_log_level;
446  ++arg;
447  }
448  }
449  }
450  else
451  ++vmi_log_level;
452  break;
453  case 'w':
454  if (arg) {
455  errno = 0;
456  vmi_warn_level = (int)strtol(arg,&endptr,0);
457  if (errno || endptr == arg) {
458  /*
459  * Try to count up any 'w' chars. Grab the one that got
460  * us here too.
461  */
462  ++vmi_warn_level;
463  while (*arg != '\0') {
464  if (*arg == 'w')
465  ++vmi_warn_level;
466  ++arg;
467  }
468  }
469  }
470  else
471  ++vmi_warn_level;
472  break;
473  case 'l':
474  if (vmi_add_log_area_flaglist(arg,NULL)) {
475  verror("bad log level flag in '%s'!\n",arg);
476  return EINVAL;
477  }
478  break;
479 
480  default:
481  return ARGP_ERR_UNKNOWN;
482  }
483 
484  return 0;
485 }
void vmi_inc_warn_level(void)
Definition: log.c:46
#define LF_ALL
Definition: log.h:232
int vmi_log_get_flag_val(char *flag, log_areas_t *areaval, log_flags_t *flagval)
Definition: log.c:168
Definition: log.h:58
Definition: log.h:74
int vdebug_is_on(int level, log_areas_t areas, log_flags_t flags)
Definition: log.c:335
void _vmi_debug(int level, log_areas_t areas, log_flags_t flags, char *format,...)
Definition: log.c:379
static uint64_t unsigned int i
int vwarn_is_on(int level, log_areas_t areas, log_flags_t flags)
Definition: log.c:357
#define LF_X_ALL
Definition: log.h:243
Definition: log.h:60
void vmi_set_warn_level(int level)
Definition: log.c:42
void vmi_set_log_level(int level)
Definition: log.c:34
#define verror(format,...)
Definition: log.h:30
struct argp log_argp
Definition: log.c:413
Definition: log.h:56
void free(void *ptr)
Definition: debugserver.c:207
int vmi_add_log_area_flaglist(char *flaglist, char *separator)
Definition: log.c:103
void vmi_add_log_area_flags(log_areas_t areas, log_flags_t flags)
Definition: log.c:67
Definition: log.h:59
Definition: log.h:69
#define LF_P_ALL
Definition: log.h:242
#define LF_D_ALL
Definition: log.h:234
Definition: log.h:64
Definition: log.h:62
int vmi_set_log_area_flaglist(char *flaglist, char *separator)
Definition: log.c:84
#define LF_A_ALL
Definition: log.h:244
#define LA_ALL
Definition: log.h:52
Definition: log.h:68
enum log_areas log_areas_t
void vmi_inc_log_level(void)
Definition: log.c:38
error_t log_argp_parse_opt(int key, char *arg, struct argp_state *state)
Definition: log.c:416
enum log_area_bits log_area_bits_t
Definition: log.h:72
void vmi_set_user_area_flags(char **names)
Definition: log.c:164
Definition: log.h:70
#define LF_T_ALL
Definition: log.h:238
Definition: log.h:71
Definition: log.h:76
#define LF_U_ALL
Definition: log.h:246
void _vmi_warn(int level, log_areas_t areas, log_flags_t flags, char *format,...)
Definition: log.c:389
struct argp_option log_argp_opts[]
Definition: log.c:402
void vmi_set_log_area_flags(log_areas_t areas, log_flags_t flags)
Definition: log.c:50
Definition: log.h:57
#define LF_L_ALL
Definition: log.h:233
int log_flags_t
Definition: log.h:83