Reputation: 2798
I have this strange problem with stdout
/stderr
.
I want to apologize for not being able to put here the original code, it's too long / too many libraries dependent etc...
So please let me know if you ever encountered anything like it, or what may cause this issue without getting the original code, only the idea and examples of the simple things I tried to do:
g++ (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)
on RHEL 6.3
fprintf() / printf() / std::cout
stops working after a while.
I'm using boost::asio::io_service
with deadline_timer
in order to call a my_print()
function.my_print()
function prints to screen every 1 second
some information.In order to print, I use alignments, like the following:
fprintf(stdout, "%*s\n", -printWidth, someEnumToStr[i]);
fprintf(stdout, "%s\n", aString);
fprintf(stdout, "%u\n", num);
While aString
is a std::string
. Sometimes I construct aString
from std::ostringstream
.
Sometimes I construct it with snprintf()
.
std::map
with information, exactly 16 elements inside the map. I iterate over it, and for each element I try to print data with the example of fprintf()
above.16
isn't printed.stdout
to a file (./a.out > aaa.txt
) the line of element 16
is getting printed.FILE*
and fprintf()
to this file, again, everything is getting printed (all lines, including line of element 16
)fprintf()
I tried to use std::cout
(and alignments with std::cout.width(printWidth) << std::left
...), The same behavior happened, but when line 16
wasn't drawn, stdout
got stuck (I mean, the program still worked, but nothing was printed to stdout
never again. I had to call std::cout.clear()
for it to work again). Since a point in the code, which I couldn't lay my hands on, std::cout.failbit
and badbit
were 1
.valgrind
this behavior doesn't happen. valgrind
doesn't say anything wrong.gdb
it happens, but gdb
doesn't say anything wrong.clion
) in debug mode, it doesn't happen.printWidth
I give for the alignment in fprintf()
- When printWidth
is bigger, it happens sooner (when it's smaller, line 16
is randomly getting printed).std::cout
a bigger buffer (not his default) and it didn't work.fprintf()
once. Same behavior happens.NULL
pointer.\n
every couple of fprintf()s
, and do fflush()
in the end of my_print()
Please let me know if you know anything.
Illustration:
deadline_timer..... every 1 sec... my_print()
boost::asio::io_service.run
my_print() {
for(std::map<>::iterator... begin, end, ++it....) {
fprintf()s....
}
}
Upvotes: 0
Views: 1537
Reputation: 2798
I use boost::asio
, I have a callback to read from stdin
. this read is nonblocking
- happens with async_read_some()
.
The problem was stdin
was turned to be nonblocking
, and it also caused stdout
to be nonblocking
as well because they point to the same file description (explanation).
It caused the fprintf()
calls to fail (returned -1 with errno 11
) and not all of the output got printed out on the screen.
It has no relation to boost.
I succeeded isolating the problem, the following code creates this problem:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
using namespace std;
int main(int argc, char *argv[]) {
const int problem = 8000;
const int myBuffSize = 32000;
char *myBuff = new char[myBuffSize];
int myoffset = 0;
memset(myBuff, '-', myBuffSize);
int flags;
bool toogle = true;
bool running = true;
// Comment from here
if ((flags = fcntl(STDIN_FILENO, F_GETFL, 0)) < 0) {
printf("error fcntl()\n");
return 0;
}
if (fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK) < 0) {
printf("error fcntl()\n");
return 0;
}
// Comment until here
while(running) {
toogle = toogle ? false : true;
if (toogle) {
snprintf(myBuff + problem, myBuffSize - problem, "fin\n\n");
} else {
snprintf(myBuff + problem, myBuffSize - problem, "end\n\n");
}
fprintf(stdout, "%s", myBuff);
sleep(1);
}
delete[] myBuff;
return 0;
}
If you'll comment the // Comment from here
to // Comment untill here
, it will print all of the output (fin
and end
will be printed).
One solution to this problem is to open another fd
to the current tty
using fopen(ttyname(STDOUT_FILENO), "w")
and to print into it.
I believe another solution is to async_write()
into screen.
Upvotes: 1
Reputation: 13073
Non printable characters may be breaking terminal.
fprintf(stdout,"%s", astdstring.cstr() );
Is how to print std::string
Upvotes: 1
Reputation: 934
The output might be stuck in a buffer, and not flushed before program termination.
Try adding exit(0)
at the end of the program, and see if it helps.
http://www.cplusplus.com/reference/cstdlib/exit/
All C streams (open with functions in <cstdio>) are closed (and flushed, if buffered), and all files created with tmpfile are removed.
Upvotes: 0