Click here to Skip to main content
6,306,412 members and growing! (19,814 online)
Email Password   helpLost your password?
Development Lifecycle » Debug Tips » Tips     Intermediate License: A Public Domain dedication

Using an output stream for debugging

By Sven Axelsson

How to create an output stream that writes to the debug terminal.
VC6Win2K, Visual Studio, Dev, QA
Posted:10 Apr 2001
Updated:24 Nov 2001
Views:115,343
Bookmarked:34 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
27 votes for this article.
Popularity: 5.92 Rating: 4.14 out of 5

1

2
1 vote, 16.7%
3

4
5 votes, 83.3%
5

Background

There are many different schools of how to debug a program (yeah, I know - write it correctly from the start), but whatever tools you prefer it is often very convenient just to use the printf approach. Well, since you are a modern C++ kind of person, you don't really want printf, you want to use an output stream, like cerr.

There's just one problem though, you are writing Windows applications, so there is no standard error output to write to. Not true, actually there is, and you've probably used many times already. When you use one of the TRACE macros, the result ends up in the Debug pane of Visual Studio. MFC goes through great pains to turn off all this debug output in Release builds, but it can often be very convenient to keep it.

Of course, you won't see any output in Visual Studio from a release build, but there are other programs that can capture this output. A good one is DebugView from www.sysinternals.com. Incidentially, if you start this program you'll probably see like a million messages from Internet Explorer. There you go, even Microsoft practise Release build debugging!

The problem

So, how to direct a standard output stream to the debug terminal? In general, the correct answer is to derive from streambuf and connect the new class to a normal ostream. In this way all stream inserters and manipulators work as expected. In this case we can save some work by deriving from stringbuf instead. So, without further ado, here's how to do it:

The code

First we include the needed headers.

#include <Windows.h>

#include <ostream>

#include <sstream>

#include <string>

Now for the real work: Since we are using a stringbuf we only need to override the sync function.

The sync method is what actually transfers the text in the put area to whatever output destination the streambuf uses, in this case by calling the API function OutputDebugString.

template <class CharT, class TraitsT = std::char_traits<CharT> >
class basic_debugbuf : 
    public std::basic_stringbuf<CharT, TraitsT>
{
public:

    virtual ~basic_debugbuf()
    {
        sync();
    }

protected:

    int sync()
    {
        output_debug_string(str().c_str());
        str(std::basic_string<CharT>());    // Clear the string buffer


        return 0;
    }

    void output_debug_string(const CharT *text) {}
};

Next, I specialize the output routine so it calls the Ansi or Unicode API as appropriate.

template<>
void basic_debugbuf<char>::output_debug_string(const char *text)
{
    ::OutputDebugStringA(text);
}

template<>
void basic_debugbuf<wchar_t>::output_debug_string(const wchar_t *text)
{
    ::OutputDebugStringW(text);
}

That's really all you need, but as a convenience I also provide a class derived from basic_ostream that connects the output stream to the basic_debugbuf just created.

In order to work just like cout, you should then create a global object of type dostream or wdostream and use that to output to.

template<class CharT, class TraitsT = std::char_traits<CharT> >
class basic_dostream : 
    public std::basic_ostream<CharT, TraitsT>
{
public:

    basic_dostream() : std::basic_ostream<CharT, TraitsT>
                (new basic_debugbuf<CharT, TraitsT>()) {}
    ~basic_dostream() 
    {
        delete rdbuf(); 
    }
};

typedef basic_dostream<char>    dostream;
typedef basic_dostream<wchar_t> wdostream;

History

  • 18-apr-2001 - Original version
  • 23-nov-2001 - Updated to use a stringbuf as suggested by Jim Barry.
    Also fixed the remaining HTML markup errors that made the code un-compileable

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

About the Author

Sven Axelsson


Member

Occupation: Web Developer
Location: Sweden Sweden

Other popular Debug Tips articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 34 (Total in Forum: 34) (Refresh)FirstPrevNext
Generaljust a little adjustment .. make it work with wince Pinmemberisatohon0:59 12 Dec '08  
GeneralHow to ensure that debug stream is flushed? PinmemberFreon14:15 19 Dec '07  
GeneralRe: How to ensure that debug stream is flushed? Pinmemberisatohon0:52 12 Dec '08  
GeneralWorks like a charm, Pinmemberamnonglaser14:37 30 Sep '07  
GeneralHow to declare global dostream PinmemberMax23514:20 16 Jun '06  
GeneralUnbuffered output PinmemberRichard Braint4:43 10 Aug '05  
GeneralRe: Unbuffered output PinmemberHenry Bruce9:50 5 Jun '07  
GeneralRe: Unbuffered output PinmemberFreon8:23 20 Dec '07  
Generalvery handy PinmemberBernhard22:42 14 Oct '03  
GeneralNot possible to output more than 1023 characters with OutputDebugString() Pinmemberpatrickdreyer0:31 20 Aug '03  
GeneralI built a testrunner around this PinmemberPhlip11:22 3 Feb '03  
GeneralRe: I built a testrunner around this PinmemberSven Axelsson6:56 4 Feb '03  
GeneralSTL container? PinmemberAnonymous14:12 13 May '02  
GeneralRe: STL container? PinmemberAnonymous14:21 13 May '02  
GeneralRe: STL container? PinmemberEdwin Chen9:13 3 Jul '03  
GeneralMemory leaks PinmemberJavaBodum9:33 18 Mar '02  
GeneralRe: Memory leaks PinmemberAnthony_Yio16:49 4 Nov '04  
Generalthread safe PinmemberAnonymous6:38 14 Jun '01  
GeneralUsage PinmemberMarkus Johansson23:52 12 Jun '01  
GeneralRe: Usage PinmemberAnonymous11:26 20 Sep '01  
GeneralRe: Usage PinmemberAnonymous17:45 12 Feb '02  
GeneralBetter to use basic_stringbuf PinmemberJim Barry5:12 22 Apr '01  
GeneralA small bug PinmemberSven Axelsson2:31 18 Apr '01  
Generalstlport Compatability PinmemberPatrick DellEra1:16 18 Apr '01  
GeneralRe: stlport Compatability PinmemberSven Axelsson2:27 18 Apr '01  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 24 Nov 2001
Editor: Nishant Sivakumar
Copyright 2001 by Sven Axelsson
Everything else Copyright © CodeProject, 1999-2009
Web20 | Advertise on the Code Project