FreeTDM: Add gcc printf()-style format string checks to ftdm_log(), also add FTDM_(U)INT64_FMT and FTDM_TIME_FMT constants.

The format string checks already caught a couple crash-worthy bugs and this
commit fixes a couple more.

Also includes __ftdm_check_scanf(), for completeness (currently unused).

Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
This commit is contained in:
Stefan Knoblich 2012-07-11 22:38:25 +02:00
parent 1e7d214ae6
commit f384e247fc
7 changed files with 48 additions and 7 deletions

View File

@ -92,7 +92,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c
diff = fchan->history[hindex].end_time - fchan->history[hindex].time;
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Completed state change from %s to %s in %llums\n",
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Completed state change from %s to %s in %"FTDM_TIME_FMT" ms\n",
ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff);
@ -209,7 +209,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_cancel_state(const char *file, const char
/* NOTE
* we could potentially also take out the channel from the pendingchans queue, but I believe is easier just leave it,
* the only side effect will be a call to ftdm_channel_advance_states() for a channel that has nothing to advance */
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Cancelled state change from %s to %s in %llums\n",
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Cancelled state change from %s to %s in %"FTDM_TIME_FMT" ms\n",
ftdm_channel_state2str(last_state), ftdm_channel_state2str(state), diff);
return FTDM_SUCCESS;

View File

@ -1221,7 +1221,7 @@ static int on_info(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event
ftdm_caller_data_t *caller_data = NULL;
if (!chan) {
ftdm_log(FTDM_LOG_CRIT, "-- Info on channel %d:%d %s but it's not in use?\n", ftdm_span_get_id(span), pevent->ring.channel);
ftdm_log(FTDM_LOG_CRIT, "-- Info on channel %d:%d but it's not in use?\n", ftdm_span_get_id(span), pevent->ring.channel);
return 0;
}
@ -1284,7 +1284,7 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->hangup.channel);
if (!chan) {
ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d %s but it's not in use?\n", ftdm_span_get_id(spri->span), pevent->hangup.channel);
ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d but it's not in use?\n", ftdm_span_get_id(spri->span), pevent->hangup.channel);
return 0;
}

View File

@ -1143,7 +1143,7 @@ static ftdm_status_t misdn_handle_incoming(ftdm_channel_t *ftdmchan, const char
assert(priv);
if (msg_len < sizeof(*hh)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "mISDN message to small (%d < %d bytes)\n",
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "mISDN message to small (%d < %"FTDM_SIZE_FMT" bytes)\n",
msg_len, sizeof(*hh));
return FTDM_FAIL;
}

View File

@ -216,7 +216,7 @@ FTDM_STR2ENUM_P(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t)
/*! \brief Logging function prototype to be used for all FreeTDM logs
* you should use ftdm_global_set_logger to set your own logger
*/
typedef void (*ftdm_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...);
typedef void (*ftdm_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...) __ftdm_check_printf(5, 6);
/*! \brief Data queue operation functions
* you can use ftdm_global_set_queue_handler if you want to override the default implementation (not recommended)

View File

@ -121,6 +121,36 @@ extern "C" {
#pragma comment(lib, "Winmm")
#endif
/*
* Compiler-specific format checking attributes
* use these on custom functions that use printf/scanf-style
* format strings (e.g. ftdm_log())
*/
#if defined(__GNUC__)
/**
* Enable compiler-specific printf()-style format and argument checks on a function
* @param fmtp Position of printf()-style format string parameter
* @param argp Position of variable argument list ("...") parameter
* @code
* void log(const int level, const char *fmt, ...) __ftdm_check_printf(2, 3);
* @endcode
*/
#define __ftdm_check_printf(fmtp, argp) __attribute__((format (printf, fmtp, argp)))
/**
* Enable compiler-specific scanf()-style format and argument checks on a function
* @param fmtp Position of scanf()-style format string parameter
* @param argp Position of variable argument list ("...") parameter
* @code
* void parse(struct foo *ctx, const char *fmt, ...) __ftdm_check_scanf(2, 3);
* @endcode
*/
#define __ftdm_check_scanf(fmtp, argp) __attribute__((format (scanf, fmtp, argp)))
#else
#define __ftdm_check_printf(fmtp, argp)
#define __ftdm_check_scanf(fmtp, argp)
#endif
#define FTDM_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) FT_DECLARE(_TYPE) _FUNC1 (const char *name); FT_DECLARE(const char *) _FUNC2 (_TYPE type);
#define FTDM_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \
FT_DECLARE(_TYPE) _FUNC1 (const char *name) \
@ -160,6 +190,8 @@ typedef __int16 int16_t;
typedef __int8 int8_t;
#define FTDM_O_BINARY O_BINARY
#define FTDM_SIZE_FMT "Id"
#define FTDM_INT64_FMT "lld"
#define FTDM_UINT64_FMT "llu"
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
@ -168,6 +200,13 @@ typedef __int8 int8_t;
#else /* __WINDOWS__ */
#define FTDM_O_BINARY 0
#define FTDM_SIZE_FMT "zd"
#if (defined(__SIZEOF_LONG__) && (__SIZEOF_LONG__ == 8)) || defined(__LP64__) || defined(__LLP64__)
#define FTDM_INT64_FMT "ld"
#define FTDM_UINT64_FMT "lu"
#else
#define FTDM_INT64_FMT "lld"
#define FTDM_UINT64_FMT "llu"
#endif
#define FTDM_INVALID_SOCKET -1
typedef int ftdm_socket_t;
#include <stdio.h>

View File

@ -53,6 +53,8 @@ extern "C" {
/*! \brief time data type */
typedef uint64_t ftdm_time_t;
/*! format string for ftdm_time_t */
#define FTDM_TIME_FMT FTDM_UINT64_FMT
/*! \brief sleep x amount of milliseconds */
#ifdef __WINDOWS__

View File

@ -144,7 +144,7 @@ int main(int argc, char *argv[])
ftdm_channel_call_indicate(lchan, ind);
stop = ftdm_current_time_in_ms();
diff = stop - start;
ftdm_log(FTDM_LOG_DEBUG, "Setting indication %s took %llums\n",
ftdm_log(FTDM_LOG_DEBUG, "Setting indication %s took %"FTDM_TIME_FMT" ms\n",
ftdm_channel_indication2str(ind), diff);
}
}