I have just upgraded to Xcode 4 and am working in C++ project. I am finding that printf() intermittently fails to complete printing (mid-line) to the Xcode console, and from there on printf() ceases to print anything - even though the application continues to run in debugger.
I suspect Xcode 4's console window is at fault because if I redirect stdout to a file, then logging seems to continue without any problems. That said, if I use following on command line:
tail -f log-out.txt
then there are times when incomplete lines are shown. But this is probably due to some sort of buffering (incomplete flush) because ultimately the lines are complete in the file.
So, I am wondering if anyone has experienced something like this and has an understanding of what's causing freeze in Xcode's console output.
Never actually worked with Xcode, BUT:
Can you show us how your printf calls look like?
The reason why I'm asking is that, if you don't flush your stream, some of the output might not reach the console (as you actually pointed out in the question). The simplest way to do that is to add a newline character at the end of each printf call.
This behavior seems to be intermittent and reportedly pre-exists Xcode 4. As a work-around I did something like this to the main() function. There are some advantages to this approach when Xcode's Debug Console is misbehaving.
#define REDIRECT_STDOUT_TO_FILE 1
int main(int argc, char ** argv)
{
#if REDIRECT_STDOUT_TO_FILE //## redirect stdout to "log-out.txt"
freopen("log-out.txt", "w", stdout);
#endif // REDIRECT_STDOUT_TO_FILE
MyApp app(argc, argv);
int result = app.Run();
#if REDIRECT_STDOUT_TO_FILE //## redirect stdout to "log-out.txt"
fflush(stdout);
fclose(stdout);
#endif // REDIRECT_STDOUT_TO_FILE
return result;
}
Using tail -f log-out.txt in Terminal allows one to view stdout output. Or, if you use BBEdit, bbedit --new-window log-out.txt is also an workable solution.
For now, I am considering this a bug in Xcode - and I will continue trying to understand under what conditions it occurs.
Related
I have an app that generates a dependencies.dot file which I then want to convert to an SVG image.
When I do that from a simple application like so:
int main(int argc, char * argv[])
{
system("dot -Tsvg ../BUILD/dependencies.dot > ../BUILD/dependencies.svg");
return 0;
}
It works great. The SVG image is present and working.
When I instead run it from my Qt application, the SVG file is created (by the shell), but it remains empty.
Any idea what could prevent dot from outputting data to its stdout?
Just in case, I also tried a cat to send the input through stdin instead of a filename:
system("cat ../BUILD/dependencies.dot | dot -Tsvg > ../BUILD/dependencies.svg");
And that didn't make any differences.
Also using the full path (/usr/bin/dot) did not help either.
Another test, I tried to use popen() and the first fread() immediately returns 0 (i.e. the mark of EOF).
It may not be Qt, but something is interacting with dot's ability to do anything. Any pointers on why that is would be wonderful.
Maybe an important note? I start my app. from a console, so stdin, stdout and stderr should all work as expected. I actually can see debug logs appearing there and other apps seem to work just as expected (i.e. My Qt app. can successfully run make, for example).
Here is an example of the resulting SVG (when I don't run it from within my Qt app):
For reference, the source code can be found on github. This is part of the snapbuilder. A tool that I use to run a build on launchpad. It's still incomplete, but it's getting there.
https://github.com/m2osw/snapcpp/tree/master/snapbuilder
The specific function to look for: project::generate_svg().
I still have no clue what side effect Qt has on system() that the dot command would fail. However, if using my own fork() + execve(), then it works.
I wanted a new process class for my environment, so I implemented that. This newer version is using FIFOs or directly opening closing files that it passes to the process.
...
// write the script in `std::stringstream dot` then:
//
std::string script(dot.str());
g_dot_process = std::make_shared<cppprocess::process>("dependencies");
g_dot_process->set_command("/usr/bin/dot");
g_dot_process->add_argument("-Tsvg");
g_dot_process->add_input(cppprocess::buffer_t(script.data(),
script.data() + script.length()));
g_dot_process->set_capture_output();
g_dot_process->set_output_capture_done(output_captured);
g_dot_process->start(); // TODO: check return value for errors
...
// and in output_captured()
//
void snap_builder::svg_ready(std::string const & svg)
{
std::string const svg_filename(...);
{
std::ofstream out;
out.open(svg_filename);
if(!out.is_open())
{
std::cerr << "error: \n";
return;
}
out.write(svg.c_str(), svg.size());
}
dependency_tree->load(QString::fromUtf8(svg_filename.c_str()));
}
Now the dot file is generated and displayed as expected.
This is rather strange since most everything else I've done with a simple system() call works as expected. There must be something about stdin or stdout that makes dot not do its work.
I'm currently programming an SDL Network Game, everything is perfect ... But my game only runs at 30fps, so I ran a Very Sleepy analysis.
First strange effect, very sleepy increase the perfs of my Game to 60Fps ... ( Why ? )
And secondly, there is a lot of SDL_LogCritical calls ( you can get the report here : http://puu.sh/gauEi/9a852462e6.png ). And nothing is shown in the console.
( I also use SDLNet, with TCP protocol, there is no packet loose ).
Moreover, I overwritten the output for SDL Logs :
void log(void* userdata, int category, SDL_LogPriority priority, const char* message) {
std::cout << "Log : " << message << std::endl;
}
int main(int argc, char **argv) {
SDL_Init(SDL_INIT_EVERYTHING);
SDLNet_Init();
SDL_LogSetOutputFunction(log, NULL);
SDL_LogCritical(1, "TEST LOG");
}
And I can see the "TEST LOG" in the console. So the SDL_LogCritical which consumme 30% doesn't output everything .
I don't know what's wrong, but frequent calls to a logging function indicate that something is wrong and SDL tries to tell you about it. However, the lack of output might be caused by you explicitely or implicitely disable logging to the console. Your use of Network might indicate your not looking at the right console to see these warnings. It's all a bit hard to diagnose with the lack of information given.
Performance increase due to debugging is strange, but can often be explained by the fact that the debugger doesn't use exactly the same environment as you do when running normally.
OK, so you're not seeing output when something else calls SDL's log functionality. This points to the messages being logged somehow being below necessary priority. Compare SDL's source code to find out how that could be happening. Maybe you should, at this point, use a debugger to set breakpoints.
I have small question. Is it possible in C/C++ to put bit of codes that would interact a bit more with GDB ?
Let say I have a function like
void gdb_print(const char*);
This would print information in gdb while it executes! If it's not possible it would be awesome. Would be simple to track some information, and faster in some way!
I need something like this, because we're writing some plugins, and info from cout or cerr are not going to the console at all. So it would be something discrete. Also, could add some stuff like:
#ifdef __DEBUG__
#define debug_msg(x) gdb_print(x)
#else
#define debug_msg(x)
#endif
If it doesn't exist, let me know what you think about this!
I need something like this, because we're writing some plugins, and info from cout or cerr are not going to the console at all.
You can always write to console with:
FILE *console = fopen("/dev/tty", "w");
if (console != NULL) fprintf(console, "Your debug message\n");
I don't know of a method to write specifically to the terminal where GDB is running (which could well be different terminal from which the program itself was invoked).
try redirecting the stderr and stdout to a file using freopen. see this
This is a sample code to redirect stdout to a file in runtime:
/* freopen example: redirecting stdout */
#include <stdio.h>
int main ()
{
freopen ("myfile.txt","w",stdout);
printf ("This sentence is redirected to a file.");
fclose (stdout);
return 0;
}
static int gdb = 0;
void gdb_print(char const * msg) {
if(gdb) printf("\tGDB: %s\n", msg);
}
When you load your program up in gdb, set a breakpoint in main, then set gdb to a non-zero value. This isn't the cleanest solution (and certainly not automated) but I think it'll give you what you're looking for. Be sure to use the per-processor to remove the calls in non-debug builds (no sense in having all those extra compares that'll never evaluate to true).
I'm trying to output a zlib compressed string to stdout and something really strange happens. After running the zlib deflate operation successfully (all the correct return values checked), I try to output the result unformatted with either of these methods:
fwrite((void*)output, 1, numbytes, stdout);
OR
for(int i=0; i != numbytes; ++i)
cout.put(output[c]);
if(!cout.good())
throw error();
In either case nothing is output and stdout is broken. In the case of the iostream code, cout.good() returns true, no failbits are set! When using fwrite I check ferror and thats fine too!!! By stdout being broken, I mean that nothing is output via stdout for the rest of the app session. I tried reseting the stdout error state with the respective interfaces to no avail.
I'm strongly inclined to believe this is a library error, as something like this really shouldn't malfunction silently.
All this is happening under OSX 10.6 running XCode 4.2.
This is probably an XCode or GDB issue. I can't reproduce the error running from console, or under Windows.
When using iostream in C++ on Linux, it displays the program output in the terminal, but in Windows, it just saves the output to a stdout.txt file. How can I, in Windows, make the output appear in the console?
Since you mentioned stdout.txt I google'd it to see what exactly would create a stdout.txt; normally, even with a Windows app, console output goes to the allocated console, or nowhere if one is not allocated.
So, assuming you are using SDL (which is the only thing that brought up stdout.txt), you should follow the advice here. Either freopen stdout and stderr with "CON", or do the other linker/compile workarounds there.
In case the link gets broken again, here is exactly what was referenced from libSDL:
How do I avoid creating stdout.txt and stderr.txt?
"I believe inside the Visual C++ project that comes with SDL there is a SDL_nostdio target > you can build which does what you want(TM)."
"If you define "NO_STDIO_REDIRECT" and recompile SDL, I think it will fix the problem." > > (Answer courtesy of Bill Kendrick)
For debugging in Visual Studio you can print to the debug console:
OutputDebugStringW(L"My output string.");
If you have a none-console Windows application, you can create a console with the AllocConsole function. Once created, you can write to it using the normal std::cout methods.
If you're using Visual Studio you need to modify the project property:
Configuration Properties -> Linker -> System -> SubSystem.
This should be set to: Console (/SUBSYSTEM:CONSOLE)
Also you should change your WinMain to be this signature:
int main(int argc, char **argv)
{
//...
return 0;
}
The AllocConsole Windows API function will create a console window for your application.
If you're using Visual Studio, it should work just fine!
Here's a code example:
#include <iostream>
using namespace std;
int main (int) {
cout << "This will print to the console!" << endl;
}
Make sure you chose a Win32 console application when creating a new project. Still you can redirect the output of your project to a file by using the console switch (>>). This will actually redirect the console pipe away from the stdout to your file. (for example, myprog.exe >> myfile.txt).
I wish I'm not mistaken!
Whether to use subsystem:console or subsystem:windows kind of depends on whether how you want to start your application:
If you use subsystem:console, then you get all of the stdout written to the terminal. The trouble is that if you start the application from the Start Menu/Desktop, you (by default) get a console appearing as well as the application window (which can look pretty ugly).
If you use subsystem:windows, you won't get stdout/stderr even if you run the application from a DOS window, Cygwin, or other terminal.
If you want the middle way which is to output to the terminal IF the application was started in a terminal, then follow the link that Luke provided in his solution (http://dslweb.nwnexus.com/~ast/dload/guicon.htm)
For reference, I ran into this problem with an application that I want to run in either normal Windows mode or batch mode (that is, as part of a script) depending on command-line switches. The whole differentiation between console and Windows applications is a bit bizarre to Unix folks!
First off, what compiler or dev environment are you using? If Visual Studio, you need to make a console application project to get console output.
Second,
std::cout << "Hello World" << std::endl;
should work in any C++ console application.
Your application must be compiled as a Windows console application.
There is a good solution
if (AllocConsole() == 0)
{
// Handle error here. Use ::GetLastError() to get the error.
}
// Redirect CRT standard input, output and error handles to the console window.
FILE * pNewStdout = nullptr;
FILE * pNewStderr = nullptr;
FILE * pNewStdin = nullptr;
::freopen_s(&pNewStdout, "CONOUT$", "w", stdout);
::freopen_s(&pNewStderr, "CONOUT$", "w", stderr);
::freopen_s(&pNewStdin, "CONIN$", "r", stdin);
// Clear the error state for all of the C++ standard streams. Attempting to accessing the streams before they refer
// to a valid target causes the stream to enter an error state. Clearing the error state will fix this problem,
// which seems to occur in newer version of Visual Studio even when the console has not been read from or written
// to yet.
std::cout.clear();
std::cerr.clear();
std::cin.clear();
std::wcout.clear();
std::wcerr.clear();
std::wcin.clear();
I assume you're using some version of Visual Studio? In windows, std::cout << "something"; should write something to a console window IF your program is setup in the project settings as a console program.
If using MinGW, add an option, -Wl,subsystem,console or -mconsole.
You don't necessarily need to make any changes to your code (nor to change the SUBSYSTEM type). If you wish, you also could simply pipe stdout and stderr to a console application (a Windows version of cat works well).