Slashdot Mirror


Printf Debugging Revisited

gsasha writes "After long nights spent in debugging, w e have developed a C++ logging facility geared for debugging - and an article that describes our debugging methodology. The article consists of two parts: the first one describes the basics of the method, and the second one presents advanced techniques (to be completed if there is enough reader interest).
Happy debugging!"

10 of 59 comments (clear)

  1. Some comments by Cthefuture · · Score: 4, Insightful

    I didn't read the paper, but I looked at the code (for me this is usually more telling).

    The first thing that jumps out at me is the coding style. Very junior programmer-ish. College student maybe? The style has that "everything crammed together" very diffcult to read feel. When I dug deeper I found the system to be over-designed and not well implemented.

    Nice try though, get some experience then try again.

    I've found that a simple C based logging facility is much more versatile. It can be used from C or C++ plus most programming languages and applications support calling external C libraries also.

    --
    The ratio of people to cake is too big
    1. Re:Some comments by Brandybuck · · Score: 4, Insightful

      Actually my experience is that you can tell how junior a programmer is by their style. While their styles will vary greatly, old timers will almost uniformly prefer an easy-for-others-to-read style. There are of course exceptions. Some junior programmers have been exposed to professors/managers/reviewers who won't accept unreadable code, and some senior programmers got tagged as "heroes" and have never had to maintain someone elses code.

      --
      Don't blame me, I didn't vote for either of them!
    2. Re:Some comments by SamBeckett · · Score: 3, Funny

      Can you please point me to a good C+ compiler... gcc keeps complaining about my .cp files.

  2. C++ makes it hard by YGingras · · Score: 5, Interesting
    It's hard to do a good printing debugger in C++. The lack of introspection throws most of the work in the hands of the pre-processor/developper.

    When I learned Common Lisp, the first macro I did was for printing debugging. It reads the expresions it is debugging, prints it (and shortens it with "..." if needed), evaluates it, prints the results and returns the results.

    What a monster you might say. Lets fist see an example of it's use:
    CL-USER> (+ 16 34 (- 6 7 8) (/ (* 3 (expt 4 1/2)) 2 3))
    42.0
    CL-USER> (dbg (+ 16 34 (dbg (- 6 7 8)) (dbg (/ (* 3 (dbg (expt 4 (/ 1 2)))) 2 3))))
    (- 6 7 8): -9
    (EXPT 4 (/ 1 2)): 2.0
    (/ (* 3 (DBG (EXPT 4 (/ 1 2)))) 2 3): 1.0
    (+ 16 34 (DBG (- 6 7 [...] 4 (/ 1 2)))) 2 3))): 42.0
    42.0
    It's done like that (and it's actually readable when indented properly):
    (defmacro dbg (expr)
    `(let ((val ,expr)
    (repr (format nil "~A" ',expr)))
    (if (> (length repr) 50)
    (format t "~A [...] ~A: ~A~%"
    (subseq repr 0 20)
    (subseq repr (- (length repr) 20))
    val)
    (format t "~A: ~A~%" repr val))
    val))
    Most of the hard work is taken away by the ability of the program to read itself, by dynamic typing and by the notion that there are no statements, only expressions. That being said, I don't claim that you should never use C++, just that it lacks introspection and that it makes printing debuging a lot harder.
  3. Instead of adverts for 2nd-year student projects by devphil · · Score: 4, Informative


    why not a link to a more professional and better-designed debugging library instead? The author has made insane efforts to handle all kinds of error conditions which it looks like these kids haven't even thought of.

    --
    You cannot apply a technological solution to a sociological problem. (Edwards' Law)
  4. Re:log4c++ by Mysteray · · Score: 4, Interesting
    we have developed a C++ logging facility geared for debugging

    My first reaction to this was, who hasn't?

    I agree with some of the other posters that their code has some, well, "interesting" features. I have to say it never would have occurred to me to use strcmp on a compile-time constant in a member initialization.

    That they use, but don't derive from, std::ostream for this is another example. It's not exactly trivial to do so, but it's also hard to argue against not doing it for something like this without good reason. But since there's not a single comment in the source files except some revision control macros we're just left to wonder.

  5. Don't reinvent the wheel by pyrrhonist · · Score: 3, Informative
    Don't reinvent the wheel. These facilities already handle logging better:
    --
    Show me on the doll where his noodly appendage touched you.
  6. Don't take the criticism too hard guys... by museumpeace · · Score: 3, Interesting
    Virtually every project of 10 or more engineers that I have been on in my 30 years of software dev has cooked up its own logging facility. You are on the back of a very crowded bus here. Depending on whether memory, disk i/o resources or realtime and multithread requirements reign in your application, rather different logging approaches are applicable. Being able to dump the Nth occurance is a nice feature but so many more are needed. THE BIGGEST DIFFERENCE I SEE between your logger kit and some I have used/written is that you published the code. A partial feature checklist I would be looking for:
    • []has both compile time and run time mechanism to set severity thresholds.
    • [] idenifies the process/thread from which the logging call is issued
    • [] can generate some kind of event ID so context can be deduced even when the same message occurs many times.
    • []timestamping: this can give you a poor man's perfmon with added programability.
    • [] supports detection of recursion by indenting printouts that are called as you go deeper on the stack
    • [] NOMENCLATURE REGULARITY: a syntax for timestamps, severity, function name from which print is called, etc so that you can automate [eg with AWK etc ] the sorting and dredging for clues in a long output run.
    • []when not in use, can be "turned off" with no compile or run time overhead but still present as comments.
    ...there are more, believe me.
    --
    SLASHDOT: news for people who can't concentrate on work or have no life at all and got tired of yelling back at the TV.
  7. Why is this on Slashdot at all? by Anonymous Coward · · Score: 5, Informative

    As many have said, this has been done before. One of their main macros isn't even correct. Ie.,

    #define LOG(logger) if ((logger).is_active()) (logger).os()

    This will break if one writes:

    if (value == 0)
    LOG(xxx) "hello" endl;
    else ...

    The "else" gets interpreted as being attached to the "if" inside the LOG macro when it shouldn't.

    It should be written as:

    #define LOG(logger) if (!(logger).is_active()) ; else (logger).os()

    For a much more expansive trace/log system see OSE at:

    http://ose.sourceforge.net

    and specifically

    http://ose.sourceforge.net/browse.php?group=librar y-manual&entry=logger.htm

    and

    http://ose.sourceforge.net/browse.php?group=librar y-manual&entry=tracer.htm

    The OSE library has had this stuff for over ten years now.

  8. PURE EVIL by Viking+Coder · · Score: 4, Informative

    // Constructor:
    Logger(const Logger& enable2 = *(Logger*)0);


    (Trimmed to trick the lameness filter.)

    Pure. Evil.

    And don't go telling me "that's perfectly valid," cause you know what? I don't care if the C++ compiler accepts it, and I don't care if you do it in your code. That is just pure evil.

    --
    Education is the silver bullet.