1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
/*
* No copyright is claimed. This code is in the public domain; do with
* it what you wish.
*/
#ifndef UTIL_LINUX_DEBUG_H
#define UTIL_LINUX_DEBUG_H
/*
* util-linux debug macros
*
* The debug stuff is based on <name>_debug_mask that controls what outputs is
* expected. The mask is usually initialized by <NAME>_DEBUG= env.variable
*
* After successful initialization the flag <PREFIX>_DEBUG_INIT is always set
* to the mask (this flag is required). The <PREFIX> is usually library API
* prefix (e.g. MNT_) or program name (e.g. CFDISK_)
*
* In the code is possible to use
*
* DBG(FOO, ul_debug("this is output for foo"));
*
* where for the FOO has to be defined <PREFIX>_DEBUG_FOO.
*
* It's possible to initialize the mask by comma delimited strings with
* subsystem names (e.g. "LIBMOUNT_DEBUG=options,tab"). In this case is
* necessary to define mask names array. This functionality is optional.
*
* It's strongly recommended to use UL_* macros to define/declare/use
* the debug stuff.
*
* See disk-utils/cfdisk.c: cfdisk_init_debug() for programs debug
* or libmount/src/init.c: mnt_init_debug() for library debug
*
*/
#include <stdarg.h>
#include <string.h>
#include "c.h"
struct ul_debug_maskname {
const char *name;
int mask;
const char *help;
};
#define UL_DEBUG_EMPTY_MASKNAMES {{ NULL, 0, NULL }}
#define UL_DEBUG_DEFINE_MASKNAMES(m) static const struct ul_debug_maskname m ## _masknames[]
#define UL_DEBUG_MASKNAMES(m) m ## _masknames
#define UL_DEBUG_MASK(m) m ## _debug_mask
#define UL_DEBUG_DEFINE_MASK(m) int UL_DEBUG_MASK(m)
#define UL_DEBUG_DECLARE_MASK(m) extern UL_DEBUG_DEFINE_MASK(m)
/*
* Internal mask flags (above 0xffffff)
*/
#define __UL_DEBUG_FL_NOADDR (1 << 24) /* Don't print object address */
/* l - library name, p - flag prefix, m - flag postfix, x - function */
#define __UL_DBG(l, p, m, x) \
do { \
if ((p ## m) & l ## _debug_mask) { \
fprintf(stderr, "%d: %s: %8s: ", getpid(), # l, # m); \
x; \
} \
} while (0)
#define __UL_DBG_CALL(l, p, m, x) \
do { \
if ((p ## m) & l ## _debug_mask) { \
x; \
} \
} while (0)
#define __UL_DBG_FLUSH(l, p) \
do { \
if (l ## _debug_mask && \
l ## _debug_mask != p ## INIT) { \
fflush(stderr); \
} \
} while (0)
#define __UL_INIT_DEBUG_FROM_STRING(lib, pref, mask, str) \
do { \
if (lib ## _debug_mask & pref ## INIT) \
; \
else if (!mask && str) { \
lib ## _debug_mask = ul_debug_parse_mask(lib ## _masknames, str); \
} else \
lib ## _debug_mask = mask; \
if (lib ## _debug_mask) { \
if (is_privileged_execution()) { \
lib ## _debug_mask |= __UL_DEBUG_FL_NOADDR; \
fprintf(stderr, "%d: %s: don't print memory addresses (SUID executable).\n", getpid(), # lib); \
} \
} \
lib ## _debug_mask |= pref ## INIT; \
} while (0)
#define __UL_INIT_DEBUG_FROM_ENV(lib, pref, mask, env) \
do { \
const char *envstr = mask ? NULL : getenv(# env); \
__UL_INIT_DEBUG_FROM_STRING(lib, pref, mask, envstr); \
} while (0)
extern void ul_debug(const char *mesg, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
extern int ul_debug_parse_mask(const struct ul_debug_maskname flagnames[],
const char *mask);
extern void ul_debug_print_masks(const char *env,
const struct ul_debug_maskname flagnames[]);
#endif /* UTIL_LINUX_DEBUG_H */
|