How to manage debugging messages at run-time

Discussion in 'C Programming' started by pozzugno@gmail.com, Oct 22, 2012.

  1. Guest

    I'd like to have debug messages during execution of my applications. I'd also like to enable/disable these messages at run-time with a command-line parameter (i.e., -d), or exclude them all with a #define (in order to improveperformance).

    Moreover, it should be nice if the user that launches the application couldselect a "debug level" (with -d option at command line) to choose the verbosity of output messages. So, each message has an associated level: if thedebug level set by the user is greater or equal the message debug level, it will be printed on stderr.

    Do you have any suggestions how to implement these functionalities with pre-processor macros or C code? It would be nice if this works also for "multi-files" projects.

    Thank you
    , Oct 22, 2012
    #1
    1. Advertising

  2. Eric Sosman Guest

    On 10/22/2012 11:28 AM, wrote:
    > I'd like to have debug messages during execution of my applications. I'd also like to enable/disable these messages at run-time with a command-line parameter (i.e., -d), or exclude them all with a #define (in order to improve performance).
    >
    > Moreover, it should be nice if the user that launches the application could select a "debug level" (with -d option at command line) to choose the verbosity of output messages. So, each message has an associated level: if the debug level set by the user is greater or equal the message debug level, it will be printed on stderr.
    >
    > Do you have any suggestions how to implement these functionalities with pre-processor macros or C code? It would be nice if this works also for "multi-files" projects.


    The straightforward approach is to produce all the debug
    output through a single function, like

    void debug(int level, const char *format, ...);

    (You could make the first parameter an enum if you like, or
    perhaps a bit-mask of different message types.) This function
    would check `level' against a global debug level set by your
    command-line processing, and decide whether to generate output
    or just do nothing.

    You probably shouldn't worry too much about the performance
    of a do-nothing debug() call. It will evaluate the arguments
    and enter the function and return from it, and yes: That will
    take some amount of time. Also, the mere presence of the call
    might inhibit some compiler optimizations. But the effect is
    not likely to be huge unless the call is executed a very large
    number of times -- in which case it wouldn't be very useful,
    because if you ever enabled it you'd drown in the output. But
    if you really, Really, REALLY wanted to eliminate it you could
    #define a varargs macro named debug that expanded to nothing.
    (Leave the command-line processing in place, though, so as not
    to antagonize people who've got `-d 0' in their scripts.)

    --
    Eric Sosman
    d
    Eric Sosman, Oct 22, 2012
    #2
    1. Advertising

  3. writes:

    > I'd like to have debug messages during execution of my
    > applications. I'd also like to enable/disable these messages at
    > run-time with a command-line parameter (i.e., -d), or exclude them all
    > with a #define (in order to improve performance).
    >
    > Moreover, it should be nice if the user that launches the application
    > could select a "debug level" (with -d option at command line) to
    > choose the verbosity of output messages. So, each message has an
    > associated level: if the debug level set by the user is greater or
    > equal the message debug level, it will be printed on stderr.
    >
    > Do you have any suggestions how to implement these functionalities
    > with pre-processor macros or C code? It would be nice if this works
    > also for "multi-files" projects.


    On simple way:

    /* In the debug header: */
    #define DBG_INFO 0
    #define DBG_WARNING 1
    #define DBG_ERROR 2
    #define DBG_FATAL 3

    #ifndef DBG_MIN_LEVEL
    #define DBG_MIN_LEVEL 0
    #endif

    #define DBG_PRINT(level, ...) \
    (void)(level >= DBG_MIN_LEVEL ? debug_print(level, __VA_ARGS__) : 0)

    /* In the error reporting module: */
    #include <stdarg.h>
    #include <stdio.h>

    int users_min_debug_level;

    int debug_print(int level, const char *fmt, ...)
    {
    static const char *level_str[] = {
    "info", "warning", "error", "fatal"
    };
    if (level >= users_min_debug_level) {
    va_list args;
    va_start(args, fmt);
    fprintf(stderr, "my_prog %s: ", level_str[level]);
    vfprintf(stderr, fmt, args);
    va_end(args);
    return fputc('\n', stderr);
    }
    else return 0;
    }

    /* Example use: */
    /* Include the debug header */
    #include <stdlib.h>

    int main(int argc, char **argv)
    {
    if (argc > 1)
    users_min_debug_level = atoi(argv[1]);
    DBG_PRINT(DBG_INFO, "program starting");
    if (argc > 2)
    DBG_PRINT(DBG_WARNING, "too many args: %d", argc);
    DBG_PRINT(DBG_ERROR, "entirely made up!");
    DBG_PRINT(DBG_FATAL, "stopping");
    exit(!0);
    }


    This relies on a basic compile optimisation and C99's __VA_ARGS__
    mechanism. In C90 use the "double parentheses" trick (ask if you don't
    know it). Obviously you can define shorthands for
    DBG_PRINT(DBG_ERROR...) and so on, as well as doing things like never
    turning off fatal error messages, but I wanted to keep things simple.

    --
    Ben.
    Ben Bacarisse, Oct 22, 2012
    #3
  4. On Mon, 22 Oct 2012 08:28:56 -0700 (PDT), wrote:

    >I'd like to have debug messages during execution of my applications. I'd also like to enable/disable these messages at run-time with a command-line parameter (i.e., -d), or exclude them all with a #define (in order to improve performance).
    >
    >Moreover, it should be nice if the user that launches the application could select a "debug level" (with -d option at command line) to choose the verbosity of output messages. So, each message has an associated level: if the debug level set by the user is greater or equal the message debug level, it will be printed on stderr.
    >
    >Do you have any suggestions how to implement these functionalities with pre-processor macros or C code? It would be nice if this works also for "multi-files" projects.


    You have requested two completely different control mechanisms. First
    you describe a run-time option by specifying a parameter on the
    command line. Second you describe a compile time option using
    #define. Both are doable but you need to realize they are almost
    completely independent.

    Assume that you encapsulate displaying the debug messages in a
    separate function with a prototype of
    void debug_func(int level, char* message);
    and you control the generation of calls to this function with a
    compile time macro named debug_status.

    Then in your debug header file (that you will include with every
    source file that might display debug messages) you specify code of the
    form
    #if defined(debug_status)
    #define debug_macro(a,b) debug_func(a,b)
    #else
    #define debug_macro(a,b) ((void)0)
    #endif
    During compilation of a source file, you define debug_status or not
    depending on whether or not you want calls to the function generated.

    In main(), you evaluate the command line parameter and store the
    desired level in a global variable named debug_level. If the
    parameter is not present, you set debug_level either very high or very
    low depending on whether the default is print all debug messages or
    print none.

    Any place you want a debug message to be optionally displayed, you add
    code of the form
    debug_macro(desired_debug_level, "desired debug text");

    In debug_func, you perform an initial test on level of the form
    if level < debug_level
    return;

    This allows you to determine if any debug code gets generated at all.
    If the code gets generated, it allows the user to determine what level
    of messages clutter his output.

    --
    Remove del for email
    Barry Schwarz, Oct 22, 2012
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. flamesrock
    Replies:
    8
    Views:
    430
    Hendrik van Rooyen
    Nov 24, 2006
  2. Pierre Yves
    Replies:
    2
    Views:
    467
    Pierre Yves
    Jan 10, 2008
  3. race4space
    Replies:
    11
    Views:
    903
    Chris Marsh
    Jan 21, 2008
  4. Ara.T.Howard

    debugging [BUG] messages/c ext woes

    Ara.T.Howard, Dec 4, 2003, in forum: Ruby
    Replies:
    3
    Views:
    124
    Ara.T.Howard
    Dec 4, 2003
  5. Will Parsons
    Replies:
    3
    Views:
    142
    Brian Candler
    Aug 1, 2009
Loading...

Share This Page