Navigation


Changeset 1085:7d7266115a34 in freeDiameter for include


Ignore:
Timestamp:
May 3, 2013, 8:20:56 PM (11 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Phase:
public
Message:

Cleaning of the traces in progress

Location:
include/freeDiameter
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • include/freeDiameter/libfdcore.h

    r1077 r1085  
    5858
    5959/* Check the return value of a GNUTLS function, log and propagate */
    60 #define CHECK_GNUTLS_DO( __call__, __fallback__ ) {                                             \
    61         int __ret__;                                                                            \
    62         TRACE_DEBUG(GNUTLS_DBG_LEVEL, "GNUTLS call: %s", #__call__ );                           \
    63         __ret__ = (__call__);                                                                   \
    64         if (__ret__ < 0) {                                                                      \
    65                 TRACE_DEBUG(INFO, "Error in '%s':\t%s", #__call__ , gnutls_strerror(__ret__));  \
    66                 __fallback__;                                                                   \
    67         }                                                                                       \
     60#define CHECK_GNUTLS_GEN( faillevel, __call__, __fallback__  ) {                                        \
     61                CHECK_PRELUDE(__call__);                                                                \
     62                if (__ret__ < 0) {                                                                      \
     63                        __ret__ = errno;                                                                \
     64                        LOG(faillevel, "ERROR: in '%s' :\t%s",  #__call__ ,  gnutls_strerror(__ret__)); \
     65                        __fallback__;                                                                   \
     66                }                                                                                       \
    6867}
    6968
    70 /* For GNUTLS routines that do not return a value */
     69/* we use this macro to help debugging gnutls usage issues -- just change the content to display what you need */
    7170#define GNUTLS_TRACE( __call__) {                                       \
    72         TRACE_DEBUG(GNUTLS_DBG_LEVEL, "GNUTLS call: " #__call__ );      \
     71        TRACE_CALL("Check: %s", #__call__ );                            \
    7372        (__call__);                                                     \
    7473}
     74
     75
     76#ifndef EXCLUDE_DEPRECATED
     77/* Macro for transition, replace with CHECK_GNUTLS_GEN */
     78#define CHECK_GNUTLS_DO( __call__, __fallback__ ) {                                                     \
     79                CHECK_PRELUDE(__call__);                                                                \
     80                if (__ret__ < 0) {                                                                      \
     81                        __ret__ = errno;                                                                \
     82                        TRACE_ERROR("ERROR: in '%s' :\t%s",  #__call__ ,  gnutls_strerror(__ret__));    \
     83                        __fallback__;                                                                   \
     84                }                                                                                       \
     85}
     86
     87#endif /* EXCLUDE_DEPRECATED */
    7588
    7689
     
    778791enum {
    779792         FDEV_TERMINATE = 1000  /* request to terminate */
    780         ,FDEV_DUMP_DICT         /* Dump the content of the dictionary */
    781         ,FDEV_DUMP_EXT          /* Dump state of extensions */
    782         ,FDEV_DUMP_SERV         /* Dump the server socket status */
    783         ,FDEV_DUMP_QUEUES       /* Dump the message queues */
    784         ,FDEV_DUMP_CONFIG       /* Dump the configuration */
    785         ,FDEV_DUMP_PEERS        /* Dump the list of peers */
    786793        ,FDEV_TRIGGER           /* Trigger available for extensions. size is sizeof(int), data is int * */
    787794};
     
    795802/* for extensions */
    796803int fd_event_trig_regcb(int trigger_val, const char * module, void (*cb)(void));
    797 void fd_event_trig_dump();
    798 
     804
     805DECLARE_FD_DUMP_PROTOTYPE(fd_event_trig_dump);
     806
     807/* The "old" FD_EV_DUMP_* events are replaced with direct calls to the following dump functions */
     808DECLARE_FD_DUMP_PROTOTYPE(fd_conf_dump);
     809DECLARE_FD_DUMP_PROTOTYPE(fd_ext_dump);
     810DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump_list, int details);
     811DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump, struct peer_hdr * p, int details);
     812DECLARE_FD_DUMP_PROTOTYPE(fd_servers_dump);
    799813
    800814/*============================================================*/
     
    832846int fd_ep_filter_list( struct fd_list * list, struct fd_list * exclude_list );
    833847int fd_ep_clearflags( struct fd_list * list, uint32_t flags );
    834 void fd_ep_dump_one( char * prefix, struct fd_endpoint * ep );
    835 void fd_ep_dump( int indent, struct fd_list * eps );
     848DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump_one, struct fd_endpoint * ep );
     849DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump, int indent, struct fd_list * eps );
    836850
    837851
  • include/freeDiameter/libfdproto.h

    r1082 r1085  
    133133/*
    134134 * FUNCTION:    fd_log
    135  * MACRO:       fd_log_debug
    136  * MACRO:       fd_log_notice
    137  * MACRO:       fd_log_error
    138  *
    139  * PARAMETERS:
    140  *  loglevel    : Integer, how important the message is
     135 *
     136 * PARAMETERS:
     137 *  loglevel    : Integer, how important the message is. Valid values are macros FD_LOG_*
    141138 *  format      : Same format string as in the printf function
    142139 *  ...         : Same list as printf
     
    151148 */
    152149void fd_log ( int, const char *, ... ) _ATTRIBUTE_PRINTFLIKE_(2,3);
    153 #define fd_log_debug(format,args...)  fd_log(FD_LOG_DEBUG, format, ## args)
    154 #define fd_log_notice(format,args...) fd_log(FD_LOG_NOTICE, format, ## args)
    155 #define fd_log_error(format,args...)  fd_log(FD_LOG_ERROR, format, ## args)
    156 
    157 void fd_log_debug_fstr( FILE *, const char *, ... );
     150void fd_log_va( int, const char *, va_list args );
    158151
    159152/* these are internal objects of the debug facility,
     
    229222
    230223
     224/* Helper function for the *dump functions that add into a buffer */
     225char * fd_dump_extend(char ** buf, size_t *len, size_t *offset, const char * format, ... ) _ATTRIBUTE_PRINTFLIKE_(4,5);
     226
     227/* All dump functions follow the same prototype:
     228 * PARAMETERS:
     229 *   buf   : *buf can be NULL on entry, it will be malloc'd. Otherwise it can be realloc'd if needed.
     230 *   len   : the current size of the buffer (in/out)
     231 *   offset: (optional) if provided, starts writing dump at offset in the buffer, and updated upon exit. if NULL, starts at offset O.
     232 *
     233 * RETURN VALUE:
     234 *   *buf upon success, NULL upon failure.
     235 * After the buffer has been used, it should be freed.
     236 */
     237#define DECLARE_FD_DUMP_PROTOTYPE( function_name, args... )     \
     238        char * function_name(char ** buf, size_t *len, size_t *offset, ##args)
     239       
     240#define FD_DUMP_STD_PARAMS  buf, len, offset
     241
     242
    231243/*============================================================*/
    232244/*                    DEBUG MACROS                            */
     
    237249#endif /* ASSERT */
    238250
    239 /* log levels definitions */
    240 #define FD_LOG_DEBUG  0  /* Verbose information for developers use */
    241 #define FD_LOG_NOTICE 3  /* Normal execution states worth noting */
    242 #define FD_LOG_ERROR  5  /* Error conditions, both recoverable or not */
    243 
    244 /* print level definitions */
    245 #define NONE 0  /* Display no debug message */
    246 #define INFO 1  /* Display errors only */
    247 #define FULL 2  /* Display additional information to follow code execution */
    248 #define ANNOYING 4 /* Very verbose, for example in loops */
    249 #define FCTS 6  /* Display entry parameters of most functions */
    250 #define CALL 9  /* Display calls to most functions (with CHECK macros) */
    251 
    252 /* A global level, changed by configuration or cmd line for example. Default is INFO (in libfdproto/log.c). */
     251/* log levels definitions, that are passed to the logger */
     252#define FD_LOG_ANNOYING  0  /* very verbose loops and such "overkill" traces. Only active when the framework is compiled in DEBUG mode. */
     253#define FD_LOG_DEBUG     1  /* Get a detailed sense of what is going on in the framework. Use this level for normal debug */
     254#define FD_LOG_NOTICE    3  /* Normal execution states worth noting */
     255#define FD_LOG_ERROR     5  /* Recoverable or expected error conditions */
     256#define FD_LOG_FATAL     6  /* Unrecoverable error, e.g. malloc fail, etc. that requires the framework to shutdown */
     257
     258/* The level used by the default logger, can be changed by command-line arguments. Ignored for other loggers. */
    253259extern int fd_g_debug_lvl;
    254260
     
    265271#endif /* __PRETTY_FUNCTION__ */
    266272
    267 #ifdef DEBUG
    268273/* A version of __FILE__ without the full path */
    269274static char * file_bname = NULL;
     
    271276#define __STRIPPED_FILE__       (file_bname ?: file_bname_init((char *)__FILE__))
    272277
    273 /* Boolean for tracing at a certain level */
    274 #define TRACE_BOOL(_level_) ( ((_level_) <= fd_g_debug_lvl)                                     \
    275                                 || (fd_debug_one_function && !strcmp(fd_debug_one_function, __PRETTY_FUNCTION__))       \
    276                                 || (fd_debug_one_file && !strcmp(fd_debug_one_file, __STRIPPED_FILE__) ) )
     278
     279
     280/* In DEBUG mode, we add meta-information along each trace. This makes multi-threading problems easier to debug. */
     281#ifdef DEBUG
     282# define STD_TRACE_FMT_STRING "pid:%s in %s@%s:%d: "
     283# define STD_TRACE_FMT_ARGS   , ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed"), __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__
    277284#else /* DEBUG */
    278 #define TRACE_BOOL(_level_) ((_level_) <= fd_g_debug_lvl)
    279 #define __STRIPPED_FILE__ __FILE__
     285# define STD_TRACE_FMT_STRING ""
     286# define STD_TRACE_FMT_ARGS
    280287#endif /* DEBUG */
    281288
    282 
    283 #define STD_TRACE_FMT_STRING "pid:%s in %s@%s:%d: "
     289/*************************
     290  The general debug macro
     291 *************************/
     292#define LOG(printlevel,format,args... ) \
     293        fd_log((printlevel), STD_TRACE_FMT_STRING format STD_TRACE_FMT_ARGS, ## args)
     294
     295/*
     296 * Use the following macros in the code to get traces with location & pid in debug mode:
     297 */
     298#ifdef DEBUG
     299# define LOG_A(format,args... ) \
     300                LOG(FD_LOG_ANNOYING,format,##args)
     301#else /* DEBUG */
     302# define LOG_A(format,args... ) /* not defined in release */
     303#endif /* DEBUG */
     304
     305/* Debug information useful to follow in detail what is going on */
     306#define LOG_D(format,args... ) \
     307                LOG(FD_LOG_DEBUG, format, ##args)
     308
     309/* Report a normal message that is useful for normal admin monitoring */
     310#define LOG_N(format,args... ) \
     311                LOG(FD_LOG_NOTICE, format,##args)
     312
     313/* Report an error */
     314#define LOG_E(format,args... ) \
     315                LOG(FD_LOG_ERROR, format, ##args)
     316
     317/* Report a fatal error */
     318#define LOG_F(format,args... ) \
     319                LOG(FD_LOG_FATAL, format, ##args)
     320
     321
    284322/*************
    285  The general debug macro, each call results in two lines of debug messages (change the macro for more compact output)
    286  *************/
    287 #ifdef DEBUG
    288 /* In DEBUG mode, we add (a lot of) meta-information along each trace. This makes multi-threading problems easier to debug. */
    289 #define TRACE(printlevel,level,format,args... ) {                                                                               \
    290         if ( TRACE_BOOL(level) ) {                                                                                              \
    291                 const char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed");                                 \
    292                 fd_log((printlevel), STD_TRACE_FMT_STRING format,                                                               \
    293                                         __thn, __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__, ## args);                      \
    294         }                                                                                                                       \
     323 Derivatives
     324 ************/
     325/* Trace a binary buffer content */
     326#define LOG_BUFFER(printlevel, prefix, buf, bufsz, suffix ) {                                                           \
     327        int __i;                                                                                                        \
     328        size_t __sz = (size_t)(bufsz);                                                                                  \
     329        uint8_t * __buf = (uint8_t *)(buf);                                                                             \
     330        char __strbuf[1024+1];                                                                                          \
     331        for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2)); __i++) {                                              \
     332                sprintf(__strbuf + (2 * __i), "%02hhx", __buf[__i]);                                                    \
     333        }                                                                                                               \
     334        fd_log(printlevel, STD_TRACE_FMT_STRING "%s%s%s" STD_TRACE_FMT_ARGS,                                            \
     335               (prefix), __strbuf, (suffix));                                                                           \
    295336}
    296 #else /* DEBUG */
    297 /* Do not print thread, function, ... only the message itself in this case */
    298 #define TRACE(printlevel,level,format,args... ) {                                       \
    299         if ( TRACE_BOOL(level) ) {                                                      \
    300                 fd_log((printlevel), format, ## args);                                  \
    301         }                                                                               \
    302 }
    303 #endif /* DEBUG */
    304 
    305 /* Report debug information */
    306 #define TRACE_DEBUG(level,format,args... ) \
    307         TRACE(FD_LOG_DEBUG,(level),format,##args)
    308 
    309 /* Report a normal message that is useful for normal admin monitoring */
    310 #define TRACE_NOTICE(format,args... ) \
    311         TRACE(FD_LOG_NOTICE,INFO,format,##args)
    312 
    313 /* Report an error */
    314 #define TRACE_ERROR(format,args... ) \
    315         TRACE(FD_LOG_ERROR, NONE, format, ##args)
    316 
    317 /*
    318 TRACE_NOTICE(...) and fd_log_notice(...) are equivalent when the code is not compiled in DEBUG mode,
    319 but there is more contextual information when compiled in DEBUG with the TRACE_NOTICE macro,
    320 hence it is recommended to use this one except for formatted output (e.g. fd_*_dump function)
    321 
    322 resp. TRACE_DEBUG and TRACE_ERROR.
    323 */
    324 
    325 /*************
    326  Derivatives for debug
    327  ************/
     337
    328338/* Helper for function entry -- for very detailed trace of the execution */
    329339#define TRACE_ENTRY(_format,_args... ) \
    330         TRACE_DEBUG(FCTS, "[enter] %s(" _format ") {" #_args "}", __PRETTY_FUNCTION__, ##_args );
     340                LOG_A(FCTS, "[enter] %s(" _format ") {" #_args "}", __PRETTY_FUNCTION__, ##_args );
    331341
    332342/* Helper for debugging by adding traces -- for debuging a specific location of the code */
    333343#define TRACE_HERE()    \
    334         TRACE_DEBUG(NONE, " -- debug checkpoint %d -- ", fd_breakhere());
     344                LOG_F(" -- debug checkpoint %d -- ", fd_breakhere());
    335345int fd_breakhere(void);
    336346
    337347/* Helper for tracing the CHECK_* macros below -- very very verbose code execution! */
    338 #define TRACE_DEBUG_ALL( str... )       \
    339         TRACE_DEBUG(CALL, str );
     348#define TRACE_CALL( str... )    \
     349                if ((fd_debug_one_function && !strcmp(fd_debug_one_function, __PRETTY_FUNCTION__))      \
     350                 || (fd_debug_one_file && !strcmp(fd_debug_one_file, __STRIPPED_FILE__) ) ) {           \
     351                        LOG_A( str );                                                                   \
     352                }
    340353
    341354/* For development only, to keep track of TODO locations in the code */
    342355#ifndef ERRORS_ON_TODO
    343 #define TODO( _msg, _args... ) \
    344         TRACE_DEBUG(NONE, "TODO: " _msg , ##_args);
     356# define TODO( _msg, _args... ) \
     357                LOG_F( "TODO: " _msg , ##_args);
    345358#else /* ERRORS_ON_TODO */
    346 #define TODO( _msg, _args... ) \
    347         "TODO" = _msg ## _args; /* just a stupid compilation error to spot the todo */
     359# define TODO( _msg, _args... ) \
     360                "TODO" = _msg ## _args; /* just a stupid compilation error to spot the todo */
    348361#endif /* ERRORS_ON_TODO */
    349362
    350 /* Trace a binary buffer content */
    351 #ifdef DEBUG
    352 /* In DEBUG mode, we add (a lot of) meta-information along each trace. This makes multi-threading problems easier to debug. */
    353 #define TRACE_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) {                                                          \
    354         if ( TRACE_BOOL(level) ) {                                                                                              \
    355                 int __i;                                                                                                        \
    356                 size_t __sz = (size_t)(bufsz);                                                                                  \
    357                 uint8_t * __buf = (uint8_t *)(buf);                                                                             \
    358                 char __strbuf[1024+1];                                                                                          \
    359                 char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed");                                       \
    360                 for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2)); __i++) {                                              \
    361                         sprintf(__strbuf + (2 * __i), "%2.2hhx", __buf[__i]);                                                   \
    362                 }                                                                                                               \
    363                 fd_log(printlevel, STD_TRACE_FMT_STRING "%s%s%s",                                                               \
    364                        __thn, __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__, (prefix), __strbuf, (suffix));                  \
    365         }                                                                                                                       \
     363
     364/*============================================================*/
     365/*                  ERROR CHECKING MACRO                      */
     366/*============================================================*/
     367
     368/* Macros to check a return value and branch out in case of error.
     369 * These macro additionally provide the logging information.
     370 *
     371 * The name "__ret__" is always available in the __fallback__ parameter and contains the error code.
     372 */
     373 
     374#define CHECK_PRELUDE(__call__)                         \
     375                int __ret__;                            \
     376                TRACE_CALL("Check: %s", #__call__ );    \
     377                __ret__ = (__call__)
     378       
     379#define DEFAULT_FB      return __ret__;
     380
     381/* System check: error case if < 0, error value in errno */
     382#define CHECK_SYS_GEN( faillevel, __call__, __fallback__  ) {                                           \
     383                CHECK_PRELUDE(__call__);                                                                \
     384                if (__ret__ < 0) {                                                                      \
     385                        __ret__ = errno;                                                                \
     386                        LOG(faillevel, "ERROR: in '%s' :\t%s",  #__call__ , strerror(__ret__));         \
     387                        __fallback__;                                                                   \
     388                }                                                                                       \
    366389}
    367 #else /* DEBUG */
    368 /* Do not print thread, function, ... only the message itself in this case */
    369 #define TRACE_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) {                                                          \
    370         if ( TRACE_BOOL(level) ) {                                                                                              \
    371                 int __i;                                                                                                        \
    372                 size_t __sz = (size_t)(bufsz);                                                                                  \
    373                 uint8_t * __buf = (uint8_t *)(buf);                                                                             \
    374                 char __strbuf[1024+1];                                                                                          \
    375                 for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2)); __i++) {                                              \
    376                         sprintf(__strbuf + (2 * __i), "%2.2hhx", __buf[__i]);                                                   \
    377                 }                                                                                                               \
    378                 fd_log(printlevel, "%s%s%s", (prefix), __strbuf, (suffix));                                                     \
    379         }                                                                                                                       \
     390
     391
     392/* Check the return value of a function and execute fallback in case of error or special value */
     393#define CHECK_FCT_GEN2( faillevel, __call__, __speval__, __fallback1__, __fallback2__ ) {               \
     394                CHECK_PRELUDE(__call__);                                                                \
     395                if (__ret__ != 0) {                                                                     \
     396                        if (__ret__ == (__speval__)) {                                                  \
     397                                __fallback1__;                                                          \
     398                        } else {                                                                        \
     399                                LOG(faillevel, "ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__));  \
     400                                __fallback2__;                                                          \
     401                        }                                                                               \
     402                }                                                                                       \
    380403}
    381 #endif /* DEBUG */
    382 
    383 /* Some aliases to socket addresses structures */
    384 #define sSS     struct sockaddr_storage
    385 #define sSA     struct sockaddr
    386 #define sSA4    struct sockaddr_in
    387 #define sSA6    struct sockaddr_in6
    388 
    389 /* The sockaddr length of a sSS structure */
    390 #define sSAlen( _sa_ )  \
    391         ( (socklen_t) ( (((sSA *)_sa_)->sa_family == AF_INET) ? (sizeof(sSA4)) :                \
    392                                 ((((sSA *)_sa_)->sa_family == AF_INET6) ? (sizeof(sSA6)) :      \
    393                                         0 ) ) )
    394 
    395 /* Dump one sockaddr Node information */
    396 #define sSA_DUMP_NODE( buf, bufsize, sa, flag ) {                       \
    397         sSA * __sa = (sSA *)(sa);                                       \
    398         char __addrbuf[INET6_ADDRSTRLEN];                               \
    399         if (__sa) {                                                     \
    400           int __rc = getnameinfo(__sa,                                  \
    401                         sSAlen(__sa),                                   \
    402                         __addrbuf,                                      \
    403                         sizeof(__addrbuf),                              \
    404                         NULL,                                           \
    405                         0,                                              \
    406                         (flag));                                        \
    407           if (__rc)                                                     \
    408                 snprintf(buf, bufsize, "%s", gai_strerror(__rc));       \
    409           else                                                          \
    410                 snprintf(buf, bufsize, "%s", &__addrbuf[0]);            \
    411         } else {                                                        \
    412                 snprintf(buf, bufsize, "(NULL / ANY)");                 \
    413         }                                                               \
     404
     405/* Check the return value of a function and execute fallback in case of error (return value different from 0) */
     406#define CHECK_FCT_GEN( faillevel, __call__, __fallback__) \
     407               CHECK_FCT_GEN2( faillevel, (__call__), 0, , (__fallback__) )
     408
     409/* Check that a memory allocator did not return NULL, otherwise log an error and execute fallback */
     410#define CHECK_MALLOC_GEN( faillevel, __call__, __fallback__ ) {                                        \
     411               void *  __ptr__;                                                                        \
     412               TRACE_CALL("Check: %s", #__call__ );                                                    \
     413               __ptr__ = (void *)(__call__);                                                           \
     414               if (__ptr__ == NULL) {                                                                  \
     415                       int __ret__ = errno;                                                            \
     416                       LOG(faillevel, "ERROR: in '%s' :\t%s",  #__call__ , strerror(__ret__));         \
     417                       __fallback__;                                                                   \
     418               }                                                                                       \
    414419}
    415 /* Same but with the port (service) also */
    416 #define sSA_DUMP_NODE_SERV( buf, bufsize, sa, flag ) {                  \
    417         sSA * __sa = (sSA *)(sa);                                       \
    418         char __addrbuf[INET6_ADDRSTRLEN];                               \
    419         char __servbuf[32];                                             \
    420         if (__sa) {                                                     \
    421           int __rc = getnameinfo(__sa,                                  \
    422                         sSAlen(__sa),                                   \
    423                         __addrbuf,                                      \
    424                         sizeof(__addrbuf),                              \
    425                         __servbuf,                                      \
    426                         sizeof(__servbuf),                              \
    427                         (flag));                                        \
    428           if (__rc)                                                     \
    429                 snprintf(buf, bufsize, "%s", gai_strerror(__rc));  \
    430           else                                                          \
    431                 snprintf(buf, bufsize, "[%s]:%s", &__addrbuf[0],&__servbuf[0]); \
    432         } else {                                                        \
    433                 snprintf(buf, bufsize,"(NULL / ANY)");         \
    434         }                                                               \
     420
     421/* Check parameters at function entry, execute fallback on error */
     422#define CHECK_PARAMS_GEN( faillevel, __bool__, __fallback__ ) {                                        \
     423               TRACE_CALL("Check: %s", #__bool__ );                                                    \
     424               if ( ! (__bool__) ) {                                                                   \
     425                       int __ret__ = EINVAL;                                                           \
     426                       LOG(faillevel, "ERROR: invalid parameter '%s'",  #__bool__ );                   \
     427                       __fallback__;                                                                   \
     428               }                                                                                       \
    435429}
    436430
    437 #ifdef DEBUG
    438 /* In DEBUG mode, we add (a lot of) meta-information along each trace. This makes multi-threading problems easier to debug. */
    439 #define TRACE_sSA(printlevel, level, prefix, sa, flags, suffix ) {                                                                              \
    440         if ( TRACE_BOOL(level) ) {                                                                                              \
    441                 char __buf[1024];                                                                                               \
    442                 char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed");                                       \
    443                 sSA_DUMP_NODE_SERV(__buf, sizeof(__buf), sa, flags );                                                           \
    444                 fd_log(printlevel, STD_TRACE_FMT_STRING "%s%s%s" ,                                                              \
    445                        __thn, __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__, (prefix), __buf, (suffix));                     \
    446         }                                                                                                                       \
     431
     432/*============================================================*/
     433/*          COMPATIBILITY MACROS, TO BE REMOVED               */
     434/*============================================================*/
     435/* Redefine the old macros for transition of the code */
     436#ifndef EXCLUDE_DEPRECATED
     437
     438#define MARK_DEPRECATED /* __attribute__ ((deprecated)) */
     439
     440enum old_levels {
     441        NONE = 0,
     442        INFO = 1,
     443        FULL = 2,
     444        ANNOYING = 4,
     445        FCTS = 6,
     446        CALL = 9
     447} MARK_DEPRECATED;
     448
     449static __inline__ int TRACE_BOOL( enum old_levels level ) MARK_DEPRECATED
     450{
     451        return (level <= fd_g_debug_lvl)
     452                || (fd_debug_one_function && !strcmp(fd_debug_one_function, __PRETTY_FUNCTION__))
     453                || (fd_debug_one_file && !strcmp(fd_debug_one_file, __STRIPPED_FILE__) );
    447454}
    448 #else /* DEBUG */
    449 /* Do not print thread, function, ... only the message itself in this case */
    450 #define TRACE_sSA(printlevel, level, prefix, sa, flags, suffix ) {                                                                              \
    451         if ( TRACE_BOOL(level) ) {                                                                                              \
    452                 char __buf[1024];                                                                                               \
    453                 sSA_DUMP_NODE_SERV(__buf, sizeof(__buf), sa, flags );                                                           \
    454                 fd_log(printlevel, "%s%s%s" , (prefix), __buf, (suffix));                                                       \
    455         }                                                                                                                       \
     455
     456static __inline__ void fd_log_deprecated( int level, const char *format, ... ) MARK_DEPRECATED
     457{
     458        va_list ap;
     459        va_start(ap, format);
     460        fd_log_va(level, format, ap);
     461        va_end(ap);     
    456462}
    457 #endif /* DEBUG */
    458 
    459 /******************
    460  Optimized code: remove all debugging code
    461  **/
     463static __inline__ void replace_me() MARK_DEPRECATED { }
     464
     465#define TRACE_sSA(...) replace_me();
     466#define sSA_DUMP_NODE_SERV(...) replace_me();
     467#define sSA_DUMP_NODE(...) replace_me();
     468#define TRACE_BUFFER(...) replace_me();
     469#define TRACE_NOTICE(...) replace_me();
     470
     471
     472/* Use the LOG_* instead, or use the new *_dump functions when dumping an object */
     473#define fd_log_debug(format,args...)  fd_log_deprecated(FD_LOG_DEBUG, format, ## args)
     474#define fd_log_notice(format,args...) fd_log_deprecated(FD_LOG_NOTICE, format, ## args)
     475#define fd_log_error(format,args...)  fd_log_deprecated(FD_LOG_ERROR, format, ## args)
     476
     477/* old macro for traces. To be replaced by appropriate LOG_* macros. */
     478# define TRACE_DEBUG(oldlevel, format,args... ) {                                       \
     479                if (TRACE_BOOL(oldlevel)) {                                             \
     480                        if      (oldlevel == NONE) { LOG_E(format,##args); }            \
     481                        else if (oldlevel == INFO) { LOG_N(format,##args); }            \
     482                        else                       { LOG_D(format,##args); }            \
     483}               }
     484
     485/* the following macro must be replaced with LOG_E or LOG_F */
     486# define TRACE_ERROR    fd_log_error
     487
     488
     489/* The following macros are missing the faillevel information, which indicates at what log level the error case should be displayed. */
     490# define CHECK_SYS_DO( __call__, __fallback__  ) {                                                      \
     491                CHECK_PRELUDE(__call__);                                                                \
     492                if (__ret__ < 0) {                                                                      \
     493                        __ret__ = errno;                                                                \
     494                        TRACE_ERROR("ERROR: in '%s' :\t%s",  #__call__ , strerror(__ret__));            \
     495                        __fallback__;                                                                   \
     496                }                                                                                       \
     497}
     498
     499# define CHECK_SYS( __call__  ) \
     500                CHECK_SYS_DO( (__call__), return __ret__  )
     501
     502
     503# define CHECK_POSIX_DO2( __call__, __speval__, __fallback1__, __fallback2__ ) {                        \
     504                CHECK_PRELUDE(__call__);                                                                \
     505                if (__ret__ != 0) {                                                                     \
     506                        if (__ret__ == (__speval__)) {                                                  \
     507                                __fallback1__;                                                          \
     508                        } else {                                                                        \
     509                                TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__));     \
     510                                __fallback2__;                                                          \
     511                        }                                                                               \
     512                }                                                                                       \
     513}
     514
     515# define CHECK_POSIX_DO( __call__, __fallback__ )       \
     516                CHECK_POSIX_DO2( (__call__), 0, , __fallback__ )
     517
     518# define CHECK_POSIX( __call__ )        \
     519                CHECK_POSIX_DO( (__call__), return __ret__ )
     520               
     521# define CHECK_MALLOC_DO( __call__, __fallback__ ) {                                                   \
     522               void *  __ptr__;                                                                        \
     523               TRACE_CALL("Check: %s", #__call__ );                                                    \
     524               __ptr__ = (void *)(__call__);                                                           \
     525               if (__ptr__ == NULL) {                                                                  \
     526                       int __ret__ = errno;                                                            \
     527                      TRACE_ERROR("ERROR: in '%s' :\t%s",  #__call__ , strerror(__ret__));             \
     528                       __fallback__;                                                                   \
     529               }                                                                                       \
     530}
     531
     532# define CHECK_MALLOC( __call__ )       \
     533                CHECK_MALLOC_DO( (__call__), return __ret__ )
     534       
     535# define CHECK_PARAMS_DO( __bool__, __fallback__ ) {                                                   \
     536               TRACE_CALL("Check: %s", #__bool__ );                                                    \
     537               if ( ! (__bool__) ) {                                                                   \
     538                       int __ret__ = EINVAL;                                                           \
     539                       TRACE_ERROR("ERROR: invalid parameter '%s'",  #__bool__ );                      \
     540                       __fallback__;                                                                   \
     541               }                                                                                       \
     542}
     543
     544# define CHECK_PARAMS( __bool__ )       \
     545                CHECK_PARAMS_DO( (__bool__), return __ret__ )
     546
     547# define CHECK_FCT_DO   CHECK_POSIX_DO
     548# define CHECK_FCT      CHECK_POSIX
     549
     550#endif /* EXCLUDE_DEPRECATED */
     551               
     552
     553/*============================================================*/
     554/*      Optimized code: remove all debugging code             */
     555/*============================================================*/
    462556#ifdef STRIP_DEBUG_CODE
    463 #undef TRACE_DEBUG
    464 #undef TRACE_NOTICE
    465 #undef TRACE_ERROR
    466 #undef TRACE_BOOL
    467 #undef TRACE_BUFFER
    468 #undef TRACE_sSA
    469 
    470 #define TRACE_DEBUG(level,format,args... ) /* noop */
    471 #define TRACE_BOOL(_level_) (0) /* always false */
    472 #define TRACE_NOTICE fd_log_notice
    473 #define TRACE_ERROR fd_log_error
    474 #define TRACE_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) {                                                          \
     557#undef LOG_D
     558#undef LOG_N
     559#undef LOG_E
     560#undef LOG_F
     561#undef LOG_BUFFER
     562
     563#define LOG_D(format,args... ) /* noop */
     564#define LOG_N(format,args...) fd_log(FD_LOG_NOTICE, format, ## args)
     565#define LOG_E(format,args...) fd_log(FD_LOG_ERROR, format, ## args)
     566#define LOG_F(format,args...) fd_log(FD_LOG_FATAL, format, ## args)
     567#define LOG_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) {                                                            \
    475568        if (printlevel > FD_LOG_DEBUG) {                                                                                        \
    476569                int __i;                                                                                                        \
     
    483576                fd_log(printlevel, prefix"%s"suffix, __strbuf);                                                                 \
    484577        }
    485 #define TRACE_sSA(printlevel, level, prefix, sa, flags, suffix )  {                                                             \
    486         if (printlevel > FD_LOG_DEBUG) {                                                                                        \
    487                 char __buf[1024];                                                                                               \
    488                 sSA_DUMP_NODE_SERV(__buf, sizeof(__buf), sa, flags );                                                           \
    489                 fd_log(printlevel, prefix "%s" suffix, __buf);                                                                  \
    490         }
    491578#endif /* STRIP_DEBUG_CODE */
    492579
    493 
    494 /*============================================================*/
    495 /*                  ERROR CHECKING MACRO                      */
    496 /*============================================================*/
    497 
    498 /* Macros to check a return value and branch out in case of error.
    499  * These macro should be used only when errors are improbable, not for expected errors.
    500  */
    501 
    502 /* Check the return value of a system function and execute fallback in case of error */
    503 #define CHECK_SYS_DO( __call__, __fallback__  ) {                                       \
    504         int __ret__;                                                                    \
    505         TRACE_DEBUG_ALL( "Check SYS: %s", #__call__ );                                  \
    506         __ret__ = (__call__);                                                           \
    507         if (__ret__ < 0) {                                                              \
    508                 int __err__ = errno;    /* We may handle EINTR here */                  \
    509                 TRACE_ERROR("ERROR: in '%s' :\t%s",  #__call__ , strerror(__err__));    \
    510                 __fallback__;                                                           \
    511         }                                                                               \
    512 }
    513 /* Check the return value of a system function, return error code on error */
    514 #define CHECK_SYS( __call__  ) {                                                        \
    515         int __ret__;                                                                    \
    516         TRACE_DEBUG_ALL( "Check SYS: %s", #__call__ );                                  \
    517         __ret__ = (__call__);                                                           \
    518         if (__ret__ < 0) {                                                              \
    519                 int __err__ = errno;    /* We may handle EINTR here */                  \
    520                 TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__err__));     \
    521                 return __err__;                                                         \
    522         }                                                                               \
    523 }
    524 
    525 /* Check the return value of a POSIX function and execute fallback in case of error or special value */
    526 #define CHECK_POSIX_DO2( __call__, __speval__, __fallback1__, __fallback2__ ) {                 \
    527         int __ret__;                                                                            \
    528         TRACE_DEBUG_ALL( "Check POSIX: %s", #__call__ );                                        \
    529         __ret__ = (__call__);                                                                   \
    530         if (__ret__ != 0) {                                                                     \
    531                 if (__ret__ == (__speval__)) {                                                  \
    532                         __fallback1__;                                                          \
    533                 } else {                                                                        \
    534                         TRACE_ERROR("ERROR: in '%s':\t%s", #__call__, strerror(__ret__));       \
    535                         __fallback2__;                                                          \
    536                 }                                                                               \
    537         }                                                                                       \
    538 }
    539 
    540 /* Check the return value of a POSIX function and execute fallback in case of error */
    541 #define CHECK_POSIX_DO( __call__, __fallback__ )                                        \
    542         CHECK_POSIX_DO2( (__call__), 0, , __fallback__ );
    543 
    544 /* Check the return value of a POSIX function and return it if error */
    545 #define CHECK_POSIX( __call__ ) {                                                       \
    546         int __v__;                                                                      \
    547         CHECK_POSIX_DO( __v__ = (__call__), return __v__ );                             \
    548 }
    549 
    550 /* Check that a memory allocator did not return NULL, otherwise log an error and execute fallback */
    551 #define CHECK_MALLOC_DO( __call__, __fallback__ ) {                                     \
    552         void *  __ret__;                                                                \
    553         TRACE_DEBUG_ALL( "Check MALLOC: %s", #__call__ );                               \
    554         __ret__ = (void *)( __call__ );                                                 \
    555         if (__ret__ == NULL) {                                                          \
    556                 int __err__ = errno;                                                    \
    557                 TRACE_ERROR("ERROR: in '%s':\t%s", #__call__, strerror(__err__));       \
    558                 __fallback__;                                                           \
    559         }                                                                               \
    560 }
    561 
    562 /* Check that a memory allocator did not return NULL, otherwise return ENOMEM */
    563 #define CHECK_MALLOC( __call__ )                                                        \
    564         CHECK_MALLOC_DO( __call__, return ENOMEM );
    565 
    566 
    567 /* Check parameters at function entry, execute fallback on error */
    568 #define CHECK_PARAMS_DO( __bool__, __fallback__ )                                               \
    569         TRACE_DEBUG_ALL( "Check PARAMS: %s", #__bool__ );                                       \
    570         if ( ! (__bool__) ) {                                                                   \
    571                 TRACE_ERROR("Warning: Invalid parameter received in '%s'", #__bool__);          \
    572                 __fallback__;                                                                   \
    573         }
    574 /* Check parameters at function entry, return EINVAL if the boolean is false (similar to assert) */
    575 #define CHECK_PARAMS( __bool__ )                                                        \
    576         CHECK_PARAMS_DO( __bool__, return EINVAL );
    577 
    578 /* Check the return value of an internal function, log and propagate */
    579 #define CHECK_FCT_DO( __call__, __fallback__ ) {                                        \
    580         int __ret__;                                                                    \
    581         TRACE_DEBUG_ALL( "Check FCT: %s", #__call__ );                                  \
    582         __ret__ = (__call__);                                                           \
    583         if (__ret__ != 0) {                                                             \
    584                 TRACE_ERROR("ERROR: in '%s':\t%s", #__call__, strerror(__ret__));       \
    585                 __fallback__;                                                           \
    586         }                                                                               \
    587 }
    588 /* Check the return value of a function call, return any error code */
    589 #define CHECK_FCT( __call__ ) {                                                         \
    590         int __v__;                                                                      \
    591         CHECK_FCT_DO( __v__ = (__call__), return __v__ );                               \
    592 }
    593 
    594 
    595 
    596 /*============================================================*/
    597 /*                  OTHER MACROS                              */
    598 /*============================================================*/
    599 
    600 
     580/*============================================================*/
     581/*                  OTHER MACROS                              */
     582/*============================================================*/
    601583/* helper macros (pre-processor hacks to allow macro arguments) */
    602584#define __tostr( arg )  #arg
     
    604586#define __agr( arg1, arg2 ) arg1 ## arg2
    605587#define _aggregate( arg1, arg2 ) __agr( arg1, arg2 )
     588
     589/* Some aliases to socket addresses structures */
     590#define sSS     struct sockaddr_storage
     591#define sSA     struct sockaddr
     592#define sSA4    struct sockaddr_in
     593#define sSA6    struct sockaddr_in6
     594
     595/* The sockaddr length of a sSS structure */
     596#define sSAlen( _sa_ )  \
     597        ( (socklen_t) ( (((sSA *)_sa_)->sa_family == AF_INET) ? (sizeof(sSA4)) :                \
     598                                ((((sSA *)_sa_)->sa_family == AF_INET6) ? (sizeof(sSA6)) :      \
     599                                        0 ) ) )
     600
     601DECLARE_FD_DUMP_PROTOTYPE(fd_sa_dump_node, sSA * sa, int flags);
     602DECLARE_FD_DUMP_PROTOTYPE(fd_sa_dump_node_serv, sSA * sa, int flags);
    606603
    607604
     
    984981
    985982/* Debug functions */
    986 void fd_dict_dump_object(struct dict_object * obj);
    987 void fd_dict_dump(struct dictionary * dict);
     983DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_object, struct dict_object * obj);
     984DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump, struct dictionary * dict);
    988985
    989986/* Function to access full contents of the dictionary, see doc in dictionary.c */
     
    12231220        dict_avpdata_interpret   type_interpret;/* cb to convert the AVP value in more comprehensive format (or NULL) */
    12241221        dict_avpdata_encode      type_encode;   /* cb to convert formatted data into an AVP value (or NULL) */
    1225         char *                  (*type_dump)(union avp_value * val);    /* cb called by fd_msg_dump_one for this type of data (if != NULL). Returned string must be freed.  */
     1222        DECLARE_FD_DUMP_PROTOTYPE((*type_dump), union avp_value * val); /* cb called by fd_msg_dump_one for this type of data (if != NULL). Returned string must be freed.  */
    12261223};
    12271224
     
    12401237int fd_dictfct_Address_encode(void * data, union avp_value * avp_value);
    12411238int fd_dictfct_Address_interpret(union avp_value * avp_value, void * interpreted);
    1242 char * fd_dictfct_Address_dump(union avp_value * avp_value);
     1239DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Address_dump, union avp_value * avp_value);
    12431240
    12441241/* Display the content of an AVP of type UTF8String in the log file */
    1245 char * fd_dictfct_UTF8String_dump(union avp_value * avp_value);
     1242DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_UTF8String_dump, union avp_value * avp_value);
    12461243
    12471244/* For Time AVPs, map with time_t value directly */
    12481245int fd_dictfct_Time_encode(void * data, union avp_value * avp_value);
    12491246int fd_dictfct_Time_interpret(union avp_value * avp_value, void * interpreted);
    1250 char * fd_dictfct_Time_dump(union avp_value * avp_value);
     1247DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Time_dump, union avp_value * avp_value);
    12511248
    12521249
     
    18221819typedef void session_state;
    18231820
     1821typedef DECLARE_FD_DUMP_PROTOTYPE(session_state_dump, session_state * st);
     1822
    18241823/* The following function must be called to activate the session expiry mechanism */
    18251824int fd_sess_start(void);
     
    18311830 *  handler     : location where the new handler must be stored.
    18321831 *  cleanup     : a callback function that must be called when the session with associated data is destroyed.
     1832 *  dumper      : if not NULL, will be called during fd_sess_dump to display the data associated with a session. NULL otherwise.
    18331833 *  opaque      : A pointer that is passed to the cleanup callback -- the content is never examined by the framework.
    18341834 *
     
    18431843 *  ENOMEM      : Not enough memory to complete the operation
    18441844 */
    1845 int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state * state, os0_t sid, void * opaque), void * opaque );
     1845int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state * state, os0_t sid, void * opaque), session_state_dump dumper, void * opaque );
    18461846/* Macro to avoid casting everywhere */
    1847 #define fd_sess_handler_create( _handler, _cleanup, _opaque ) \
    1848         fd_sess_handler_create_internal( (_handler), (void (*)(session_state *, os0_t, void *))(_cleanup), (void *)(_opaque) )
     1847#define fd_sess_handler_create( _handler, _cleanup, _dumper, _opaque ) \
     1848        fd_sess_handler_create_internal( (_handler), (void (*)(session_state *, os0_t, void *))(_cleanup), _dumper, (void *)(_opaque) )
    18491849
    18501850       
     
    20462046
    20472047/* For debug */
    2048 void fd_sess_dump(int level, struct session * session);
    2049 void fd_sess_dump_hdl(int level, struct session_handler * handler);
     2048DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump, struct session * session, int with_states);
     2049DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump_hdl, struct session_handler * handler);
    20502050
    20512051/* For statistics / monitoring: get the number of struct session in memory */
     
    23282328 *
    23292329 * PARAMETERS:
    2330  *  level       : the log level (INFO, FULL, ...) at which the object is dumped
    2331  *  obj         : A msg or avp object.
    2332  *
    2333  * DESCRIPTION:
    2334  *   These functions dump the content of a message to the debug log
     2330 *  see definition of DECLARE_FD_DUMP_PROTOTYPE,
     2331 *  obj          : A msg or avp object to dump.
     2332 *  dict         : the dictionary to use if parsing is requested (optional)
     2333 *  force_parsing: by default these functions do not parse the object but dump hexa values in that case.
     2334 *                 use !0 to force parsing. If parsing fails, the hexa dump is still provided.
     2335 *  recurse      : allow the function to go through the children objects if any to dump more information. might require parsing.
     2336 *
     2337 * DESCRIPTION:
     2338 *   These functions dump the content of a message or avp into a buffer
    23352339 * either recursively or only the object itself.
    23362340 *
    23372341 * RETURN VALUE:
    2338  *   -
    2339  */
    2340 void fd_msg_dump_walk ( int level, msg_or_avp *obj );
    2341 void fd_msg_dump_one  ( int level, msg_or_avp *obj );
    2342 
    2343 /* Helper functions to get a dump of an object in the logs. Several formats are available.
    2344  *  buf   : a buffer that can be reallocated if needed. *buf==NULL is also accepted for first allocation
    2345  *  buflen: the length of the buffer buf.
    2346  *  dict  : optional, the dictionary to use for resolving objects, if force_parsing != 0
    2347  *  obj   : the message or AVP to dump.
    2348  *
    2349  * After use, the buf pointer should be freed.
     2342 *   - see DECLARE_FD_DUMP_PROTOTYPE,
    23502343 */
    23512344/* one-line dump with only short information */
    2352 void fd_msg_dump_summary( char ** buf, size_t buflen, struct dictionary *dict, msg_or_avp *obj, int force_parsing);
     2345DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_summary, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse );
    23532346/* one-line dump with all the contents of the message */
    2354 void fd_msg_dump_full( char ** buf, size_t buflen, struct dictionary *dict, msg_or_avp *obj, int force_parsing);
     2347DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_full, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse );
    23552348/* multi-line human-readable dump similar to wireshark output */
    2356 void fd_msg_dump_treeview( char ** buf, size_t buflen, struct dictionary *dict, msg_or_avp *obj, int force_parsing);
     2349DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_treeview, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse );
    23572350
    23582351
     
    31413134
    31423135/* Dump a fifo list and optionally its inner elements -- beware of deadlocks! */
    3143 void fd_fifo_dump(int level, char * name, struct fifo * queue, void (*dump_item)(int level, void * item));
     3136typedef DECLARE_FD_DUMP_PROTOTYPE((*fd_fifo_dump_item_cb), void * item); /* This function should be 1 line if possible, or use indent level. Ends with '\n' */
     3137DECLARE_FD_DUMP_PROTOTYPE(fd_fifo_dump, char * name, struct fifo * queue, fd_fifo_dump_item_cb dump_item);
    31443138
    31453139#ifdef __cplusplus
Note: See TracChangeset for help on using the changeset viewer.