311 lines
9.9 KiB
C
311 lines
9.9 KiB
C
/*
|
|
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/**
|
|
*
|
|
* @file picodbg.h
|
|
*
|
|
* Provides functions and macros to debug the Pico system and to trace
|
|
* the execution of its code.
|
|
*
|
|
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
|
* All rights reserved.
|
|
*
|
|
* History:
|
|
* - 2009-04-20 -- initial version
|
|
*/
|
|
|
|
/**
|
|
* @addtogroup picodbg
|
|
* ---------------------------------------------------\n
|
|
* <b> Pico Debug Support </b>\n
|
|
* ---------------------------------------------------\n
|
|
* GENERAL REMARKS
|
|
* ---------------
|
|
* This module provides a set of macros to help debug the Pico system.
|
|
* The usage of macros allows for completely removing debug code from
|
|
* the binaries delivered to customers. To enable diagnostic output
|
|
* the preprocessor symbol PICO_DEBUG has to be defined.
|
|
*
|
|
* By using global variables (to store the current log level etc.)
|
|
* this module violates a basic Pico design principle!
|
|
*
|
|
* Justification:\n
|
|
* - going without global data would reduce the functionality
|
|
* of this module considerably (e.g., log level could not be
|
|
* changed at runtime etc.)
|
|
* - at the moment, the only known system interdicting global
|
|
* variables is Symbian; but even there global variables are
|
|
* possible by using thread-local storage
|
|
* - allocating global data on the heap would require to pass
|
|
* a handle to this memory block to all routines of this
|
|
* module which in turn implies that _every_ function in the
|
|
* Pico system would require a pointer to some global data;
|
|
* obviously, this would be very awkward
|
|
*
|
|
* Furthermore, this module uses the non-standardized but handy
|
|
* __FUNCTION__ macro. It expands to the name of the enclosing
|
|
* function. For compilers not supporting this macro simply
|
|
* define __FUNCTION__ as an empty string.
|
|
*
|
|
*
|
|
* INITIALIZATION/TERMINATION\n
|
|
* --------------------------\n
|
|
* Before using any debug macros, this module has to be initialized
|
|
* by calling PICODBG_INITIALIZE(). If the routines are not needed
|
|
* anymore, PICODBG_TERMINATE() has to be called to terminate the
|
|
* module (e.g., to close the log file).
|
|
*
|
|
*
|
|
* TRACING\n
|
|
* -------\n
|
|
* Each tracing message is associated with a log level which describes
|
|
* its severity. The following levels are supported:
|
|
* - Trace - Very detailed log messages, potentially of a high
|
|
* frequency and volume
|
|
* - Debug - Less detailed and/or less frequent debugging messages
|
|
* - Info - Informational messages
|
|
* - Warn - Warnings which don't appear to the Pico user
|
|
* - Error - Error messages
|
|
*
|
|
* Tracing messages can use the well-known printf format specification.
|
|
* But because variadic macros (macros with a variable no. arguments)
|
|
* are not commonly supported by compilers a little trick is used
|
|
* which requires the format string and its arguments to be enclosed
|
|
* in double parenthesis:
|
|
*
|
|
* - PICODBG_INFO(("hello, world!"));
|
|
* - PICODBG_TRACE(("argc=%d", argc));
|
|
* ...
|
|
*
|
|
* Each tracing message is expected to be a single line of text. Some
|
|
* contextual information (e.g., log level, time and date, source file
|
|
* and line number) and a newline are automatically added. The output
|
|
* format can be customized by a call to PICODBG_SET_OUTPUT_FORMAT().
|
|
*
|
|
* Sample output:
|
|
* - *** info|2008-04-03|14:51:36|dbgdemo.c(15)|hello world
|
|
* - *** trace|2008-04-03|14:51:36|dbgdemo.c(16)|argc=2
|
|
* - ...
|
|
*
|
|
* To compose a tracing message line consisting of, e.g. the elements
|
|
* of an array, on the Info level two additional macros shown in the
|
|
* following example are provided:
|
|
*
|
|
* PICODBG_INFO_CTX();\n
|
|
* for (i = 0; i < len; i++)\n
|
|
* ...some calc with arr and i\n
|
|
* PICODBG_INFO_MSG((" %d", arr[i]));\n
|
|
* }\n
|
|
* PICODBG_INFO_MSG(("\n"));\n
|
|
*
|
|
* Colored output of tracing messages helps to capture severe problems
|
|
* quickly. This feature is supported on the Windows platform and on
|
|
* platforms supporting ANSI escape codes. PICODBG_ENABLE_COLORS() lets
|
|
* you turn on and off colored output.
|
|
*
|
|
*
|
|
* FILTERING\n
|
|
* ---------\n
|
|
* By calling PICODBG_SET_LOG_LEVEL() the log level may be changed at
|
|
* any time to increase/decrease the amount of debugging output.
|
|
*
|
|
* By calling PICODBG_SET_LOG_FILTERFN() the log filter may be changed
|
|
* at any time to change the source file name being used as filter for
|
|
* log messages (ie. only tracing info of the specified file will be
|
|
* logged). To disable the file name based filter set the filter file
|
|
* name to an empty string.
|
|
*
|
|
* Future version of this module might provide further filtering
|
|
* possibilities (e.g., filtering based on function names * etc.).
|
|
*
|
|
*
|
|
* LOGGING\n
|
|
* -------\n
|
|
* By default, tracing messages are output to the console (stderr).
|
|
* This allows for separating diagnostic output from other console
|
|
* output to stdout. In addition, tracing messages may be saved to
|
|
* a file by calling PICODBG_SET_LOG_FILE().
|
|
* Currently, file output is the only additional output target; but
|
|
* on embedded systems, more output targets may be required (e.g.,
|
|
* sending output to a serial port or over the network).
|
|
*
|
|
*
|
|
* ASSERTIONS\n
|
|
* ----------\n
|
|
* To support the 'design/programming by contract' paradigm, this
|
|
* module also provides assertions. PICODBG_ASSERT(expr) evualuates
|
|
* an expression and, when the result is false, prints a diagnostic
|
|
* message and aborts the program.
|
|
*
|
|
*
|
|
* FUTURE EXTENSIONS\n
|
|
* -----------------\n
|
|
* - advanced tracing functions to dump complex data
|
|
* - debug memory allocation that can be used to assist in
|
|
* finding memory problems
|
|
*/
|
|
|
|
|
|
#if !defined(__PICODBG_H__)
|
|
#define __PICODBG_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
#if 0
|
|
}
|
|
#endif
|
|
|
|
|
|
/* Not all compilers support the __FUNCTION__ macro */
|
|
#if !defined(__FUNCTION__) && !defined(__GNUC__)
|
|
#define __FUNCTION__ ""
|
|
#endif
|
|
|
|
|
|
/* Log levels sorted by severity */
|
|
#define PICODBG_LOG_LEVEL_ERROR 1
|
|
#define PICODBG_LOG_LEVEL_WARN 2
|
|
#define PICODBG_LOG_LEVEL_INFO 3
|
|
#define PICODBG_LOG_LEVEL_DEBUG 4
|
|
#define PICODBG_LOG_LEVEL_TRACE 5
|
|
|
|
/* Output format flags */
|
|
#define PICODBG_SHOW_LEVEL 0x0001
|
|
#define PICODBG_SHOW_DATE 0x0002
|
|
#define PICODBG_SHOW_TIME 0x0004
|
|
#define PICODBG_SHOW_SRCNAME 0x0008
|
|
#define PICODBG_SHOW_SRCLINE 0x0010
|
|
#define PICODBG_SHOW_SRCALL (PICODBG_SHOW_SRCNAME | PICODBG_SHOW_SRCLINE)
|
|
#define PICODBG_SHOW_FUNCTION 0x0020
|
|
#define PICODBG_SHOW_POS (PICODBG_SHOW_SRCALL | PICODBG_SHOW_FUNCTION)
|
|
|
|
/* definition of PICO_DEBUG enables debugging code */
|
|
#if defined(PICO_DEBUG)
|
|
|
|
#define PICODBG_INITIALIZE(level) \
|
|
picodbg_initialize(level)
|
|
|
|
#define PICODBG_TERMINATE() \
|
|
picodbg_terminate()
|
|
|
|
#define PICODBG_SET_LOG_LEVEL(level) \
|
|
picodbg_setLogLevel(level)
|
|
|
|
#define PICODBG_SET_LOG_FILTERFN(name) \
|
|
picodbg_setLogFilterFN(name)
|
|
|
|
#define PICODBG_SET_LOG_FILE(name) \
|
|
picodbg_setLogFile(name)
|
|
|
|
#define PICODBG_ENABLE_COLORS(flag) \
|
|
picodbg_enableColors(flag)
|
|
|
|
#define PICODBG_SET_OUTPUT_FORMAT(format) \
|
|
picodbg_setOutputFormat(format)
|
|
|
|
|
|
#define PICODBG_ASSERT(expr) \
|
|
for (;!(expr);picodbg_assert(__FILE__, __LINE__, __FUNCTION__, #expr))
|
|
|
|
#define PICODBG_ASSERT_RANGE(val, min, max) \
|
|
PICODBG_ASSERT(((val) >= (min)) && ((val) <= (max)))
|
|
|
|
|
|
#define PICODBG_LOG(level, msg) \
|
|
picodbg_log(level, 1, __FILE__, __LINE__, __FUNCTION__, picodbg_varargs msg)
|
|
|
|
#define PICODBG_ERROR(msg) \
|
|
PICODBG_LOG(PICODBG_LOG_LEVEL_ERROR, msg)
|
|
|
|
#define PICODBG_WARN(msg) \
|
|
PICODBG_LOG(PICODBG_LOG_LEVEL_WARN, msg)
|
|
|
|
#define PICODBG_INFO(msg) \
|
|
PICODBG_LOG(PICODBG_LOG_LEVEL_INFO, msg)
|
|
|
|
#define PICODBG_DEBUG(msg) \
|
|
PICODBG_LOG(PICODBG_LOG_LEVEL_DEBUG, msg)
|
|
|
|
#define PICODBG_TRACE(msg) \
|
|
PICODBG_LOG(PICODBG_LOG_LEVEL_TRACE, msg)
|
|
|
|
|
|
#define PICODBG_INFO_CTX() \
|
|
picodbg_log(PICODBG_LOG_LEVEL_INFO, 0, __FILE__, __LINE__, __FUNCTION__, "")
|
|
|
|
#define PICODBG_INFO_MSG(msg) \
|
|
picodbg_log_msg(PICODBG_LOG_LEVEL_INFO, __FILE__, picodbg_varargs msg)
|
|
|
|
#define PICODBG_INFO_MSG_F(filterfn, msg) \
|
|
picodbg_log_msg(PICODBG_LOG_LEVEL_INFO, (const char *)filterfn, picodbg_varargs msg)
|
|
|
|
|
|
|
|
/* helper routines; should NOT be used directly! */
|
|
|
|
void picodbg_initialize(int level);
|
|
void picodbg_terminate();
|
|
|
|
void picodbg_setLogLevel(int level);
|
|
void picodbg_setLogFilterFN(const char *name);
|
|
void picodbg_setLogFile(const char *name);
|
|
void picodbg_enableColors(int flag);
|
|
void picodbg_setOutputFormat(unsigned int format);
|
|
|
|
const char *picodbg_varargs(const char *format, ...);
|
|
|
|
void picodbg_log(int level, int donewline, const char *file, int line,
|
|
const char *func, const char *msg);
|
|
void picodbg_assert(const char *file, int line, const char *func,
|
|
const char *expr);
|
|
|
|
void picodbg_log_msg(int level, const char *file, const char *msg);
|
|
|
|
|
|
#else /* release version; omit debugging code */
|
|
|
|
#define PICODBG_INITIALIZE(level)
|
|
#define PICODBG_TERMINATE()
|
|
#define PICODBG_SET_LOG_LEVEL(level)
|
|
#define PICODBG_SET_LOG_FILTERFN(name)
|
|
#define PICODBG_SET_LOG_FILE(name)
|
|
#define PICODBG_ENABLE_COLORS(flag)
|
|
#define PICODBG_SET_OUTPUT_FORMAT(format)
|
|
|
|
#define PICODBG_ASSERT(expr)
|
|
#define PICODBG_ASSERT_RANGE(val, min, max)
|
|
|
|
#define PICODBG_LOG(level, msg)
|
|
#define PICODBG_ERROR(msg)
|
|
#define PICODBG_WARN(msg)
|
|
#define PICODBG_INFO(msg)
|
|
#define PICODBG_DEBUG(msg)
|
|
#define PICODBG_TRACE(msg)
|
|
|
|
#define PICODBG_INFO_CTX()
|
|
#define PICODBG_INFO_MSG(msg)
|
|
#define PICODBG_INFO_MSG_F(filterfn, msg)
|
|
|
|
|
|
#endif /* defined(PICO_DEBUG) */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
#endif /* !defined(__PICODBG_H__) */
|