“printf” debugging in Metro style apps

Visual Studio has lots of great debugging features, but sometimes it’s easiest to trace program behavior using “printf” debugging. This can be a bit tricky when writing a Metro style app (you may have noticed that a Metro style app doesn’t have a console window!), so let’s consider a few of our options.

The “supported” way to do this is to use OutputDebugString to write messages to the debug console. This function is callable from within a Metro style app. While useful, it is quite limited: it does no formatting, and is effectively equivalent to the std::puts Standard Library function. If we want to do formatting, we must either do so ourselves before calling OutputDebugString, or write a set of helpers to do the formatting for us. Ick.

Another option would be to configure std::cout to write its output to the debug console via OutputDebugString. It’s fairly straightforward to do this using Boost’s tee_device; see, for example, the answers to the Stack Overflow question “Capturing cout in Visual Studio 2005 output window?”

That’s still a bit more work than we’d like to have to do, not everyone uses Boost, and often it’s nice to have a real console window with which we can interact. While a Metro style app doesn’t start off with a console window, we can create one ourselves.

In Windows, if an application wants to create a console window, it calls the AllocConsole function, which “allocates a new console for the calling process.” We can see in the documentation that it “Applies to: desktop apps only.” This means that, among other things,

  • When we include <Windows.h>, this function will be omitted; its declaration will be #ifdef‘ed out.

  • If we call this function in our program, it will fail WACK certification. Since we only want to use this for debugging or testing, that’s not a problem.

  • There are no guarantees as to the behavior of the function when called from a Metro style app. Technically, if a Metro style app calls the function, the app exhibits undefined behavior.

Note that none of these restrictions mean that we can’t call the function from a Metro style app, it just takes a bit of work to do so and in theory, it might not work (or it might fail unexpectedly or catastrophically). In practice, this particular function appears to work fine, though of course your mileage may vary. Since we’re only suggesting using this for debugging or testing, there is little risk if things go awry.

Here’s a simple example of how you might go about using a console from a Metro style app:

// Include Windows.h for WINBASEAPI and WINAPI:
#include <Windows.h>

// Declare AllocConsole ourselves, since Windows.h omits it:
extern "C" WINBASEAPI int WINAPI AllocConsole();

auto main(Platform::Array<Platform::String^>^) -> int
{
    AllocConsole();

    std::wcout << L"Hello there!" << std::endl;
    std::getchar();

    return EXIT_SUCCESS;
}

This program behaves as you might expect: it creates a console window, prints Hello there!, then awaits user input on the console. This same technique for creating a console window is used in the CxxReflect unit tests so that unit tests that require the Windows Runtime may share much of the same code that is used to drive unit tests that can run in a normal Win32 process.

In a real Metro style app, we might consider calling AllocConsole from the constructor of our App type or in the dynamic initializer of a namespace-scope variable, depending on how early we need to be able to write things to the console.

5 thoughts on ““printf” debugging in Metro style apps

    1. JamesMcNellis Post author

      Thanks; I wasn’t aware that was there!

      However, it still suffers from the problem that you need to separate the formatting and construction of the string to be printed from the act of writing it to the console (since Console::WriteLine takes a String^). It’s just not as easily usable as std::wprintf and std::wcout.

      Reply
      1. Sridhar

        I do agree that is suffers from the same limitations like the others. It was a life saver when writing XAML + DX code though. There were situations when I just wanted to handle errors and exceptions and dump the messages to the console and WriteLine worked like a charm. :)

        Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>