Link to home
Start Free TrialLog in
Avatar of 12bsure
12bsure

asked on

Capture debug-output to file of printf/cout statements in VC++

Hi,

How can I capture the output of cout and printf statements of a console program when run as a debugged process in MS Visual C++? Usually from the command prompt I'd use the pipeline symbol for this. How can I accomplish the same when I choose Build->Execute, or Build->Debug or F5 and the like?
It doesn't work to set the program arguments with a pipeline symbol...

Any help appreciated

Rgds,
12Bsure corp.
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nietod
nietod

Depending on your needs you might consider a completely different approach.  You can use the windows API function OutputDebugString() to output to the debugger.  In VC it outputs to the debug window.
Avatar of 12bsure

ASKER

I like the freopen approach, though this project is too dependent on stdout that I cannot use it.

I actually hoped for something like the 'command.com /c yourexe.exe | ...' approach. I thought that in that way, VC would debug command.com instead of yourexe.exe.

I am trying a few possibilities now, but I haven't yet succeeded. Here is what my command in the "Executable for debug session" looks like:
cmd /c D:\MyDebgPath\MyProject.exe  -f D:\OtherPath\config.cfg | D:\OtherPath\tee.exe D:\LogPath\mylogfile.log

Here, tee.exe is the little program that writes the logfile and prints to the screen.
Avatar of 12bsure

ASKER

Forgot to tell you what went wrong: When I hit F5 the IDE asks for a process to debug...
There used to be system API called "popen" which basically would open a application
and return you piped pointer to its standard input and standard output.

I had used it successfully on HP UX earlier, but my last attempt on Win 95 (First Release)
failed miserably. I had neither the need nor requirement to use it since.

Check out the documentation and function
meanwhile I will find to see if I can find some working sample
from my archives.
>> I actually hoped for something like
>> the 'command.com /c yourexe.exe | ...'
>> approach. I thought that
>> in that way, VC would debug command.com
>> instead of yourexe.exe.
You should be able to do that.  In the project settings under the debug tab, make command.cpm the executable for debug session.  place a path to you exe and the pipe in the program arguments.

That should work.  However, the debuger will try to debu comamnd.com, not your app, so you can't set breakpoints in your app etc etc etc.  But in terms of redirecting output, that will work.
>>so you can't set breakpoints in your app

This can be remedied by placing a '__asm{ int3};' at the beginning of the code; the debugger will stop there and allow the setting of  breakpoints.
One other thing:

>>I like the freopen approach, though this project is too
>>dependent on stdout that I cannot use it.

So, why not

#include <stdio.h>

#define printf _MyPrintf // no args, pure text replacement!

int _MyPrintf( const char *format , ... )
{
        int nRet;
     static     char     s_acOutput          [     BUFSIZE     +     MAX_PATH];
     static     char     s_acBuf               [     UFSIZE];

     va_list               args;

     va_start     (     args,     pszFormat);

     wvsprintf     (     s_acBuf,     pszFormat,     args);

     wsprintf     (     s_acOutput,
                         "%s%s",
                         s_acBuf,
                         strchr     (     s_acBuf,     '\n')     ?     "\0"     :     "\r\n"
                    );

     OutputDebugString     (     s_acOutput);
     n Ret = printf ( "%s", s_acOutput);
     fprintf ( pFile, "%s", s_acOutput);

     va_end     (     args);

       return ( nRet);
}




Avatar of 12bsure

ASKER

The way I look at it now is the following:

First option:
Manually set debug points each time you debug your app (jkr). Seems tedious in large applications.

Second option
Debug command.com (actually I use cmd.exe from Win2k) (nietod)

Third option
Create my own printf function and use it wisely. I'll have to make two different versions for debugging and for release in case of output strings. (jkr)


Clarifying the problem:
The release version will have a trace option by using "| tee.exe mylog.log". The debug version must have the same functionality, writing to the log, and *must* do that through tee.exe. I said I like the third option, but in my case, I cannot alter the requirements for this project. I can't even alter the command line arguments of it! (you might argue: why don't you just give the filename as a commandline argument).

The log-file is in a single run several Mb big in size. I want to be both able to view the log later on *and* debug like I'm used to with setting breakpoints in the IDE *and* having a log-file when run with the pipeline symbol on the command line by our customers *and* (of course :) with the least amount of effort.

But if the IDE does not support capturing output, I'll think of a way of doing that using the third option. With some compiler directives I should be able to make something nice of it.
If you go with the third option, I strongly recommend you don't use a printf() style approach.  The point is to catch errors varaible argument functions are bad at catching errors in parameters passed to them!   Instead take a more C++ approach and create a C++ stream object that outputs the debug information using operator <<.
>>I strongly recommend you don't use a printf() style
>>approach

I wouldn't have recommended it either, but if there's already a lot of existing 'printf()' output, I'd rather do it that way than rewriting half of the app...
Avatar of 12bsure

ASKER

I more a less thought of cout instead of printf. Although I talk about printf/cout and the like in my comments, most projects I do (though it depends on the coding team and the styles of the individuals) use the cout approach. I usually find it easier to use.

Reading back this discussion it appears to me that there's no way in debugging a process from the IDE *and* catch its stdout output. Probably unless I use OutputDebugString and the DebugView tool from Russinovich.

Unless anyone can prove otherwise (and I still hope so!), I hereby declare the points for jkr for his fast and most thoughtful solution ;-)  (execution of verdict in a day or so)

Rgds
12Bsure
>>Probably unless I use OutputDebugString and the
>>DebugView tool from Russinovich.

That's actually my favourite tool for that purpose...
Avatar of 12bsure

ASKER

I guess nothing more will come up here. Let's conclude that VC cannot capture debug output to a file easily or automatically.

Thanks for all your efforts!
Avatar of 12bsure

ASKER

PS, the excellent is of course for the effort and because it's a good solution on its own. Also, it answers the question correctly, there just doesn't seem to be a better way :(

Thanks, jkr.
>>Let's conclude that VC cannot capture debug output to a
>>file easily or automatically.

Well, that's not a VC issue - if you want to invest some time, everything you want to do is achievable, but if you're about to change an existing project with minimal impact, there are of course limitations...
Thsnx, 12bsure!
Avatar of 12bsure

ASKER

> if you're about to change an existing project with minimal impact, there are of course limitations...

I agree. But that's not my goal. I'd like to capture any console output for any program when the program is run from within VC as a debug, and probably also as a release built. For that matter, it is a VC-problem, and I doubt if an add-in or something the like could achieve that kind of functionality.
Avatar of 12bsure

ASKER

btw, quite long ago I've seen threads on EE on the subject of capturing the text in a console window. It appeared not to be an easy task. Maybe things have changed in Win2k (my usual dev. platform), but I haven't looked into it yet.