views:

308

answers:

3

I've got a C++ unit test that produces useful output to stderr, and mostly noise (unless I'm debugging) to stdout, so I'd like to redirect the stdout to /dev/null.

Curiously enough, doing this seems to cause a segmentation fault.

Is there any reason why code might seg fault with "> /dev/null" and run fine otherwise?

The output is produced entirely by printfs, if that has any bearing.

It is difficult for me to post the offending code because it is research being submitted for publication. I'm hoping there is an "obvious" possible cause based on this description.

post mortem

The segfault was being caused by code like this:

ArrayElt* array = AllocateArrayOfSize(array_size);
int index = GetIndex(..) % array_size;
ArrayElt elt = array[index];

For the umpteenth time, I forgot that x % y remains negative when x is negative in C/C++.

Ok, so why was it only happening when I redirected to /dev/null? My guess is that the invalid memory address I was accessing was in an output buffer for stdout - and this buffer isn't allocated when it isn't needed.

Thanks for the good answers!

+2  A: 

There is no 'normal' reason for I/O to stdout to trigger a core dump when standard output is redirected to /dev/null.

You most probably have a stray pointer or a buffer overflow that triggers the core dump when sent to /dev/null and not when sent to standard output - but it will be hard to spot the problem without the code.

It is conventional to put the useful information on standard output and the noise on standard error.

Jonathan Leffler
+1  A: 

It could be that something is checking "isatty", which might cause different behavior for /dev/null.

It might be that something is reading from stdout, which would fail for /dev/null.

Martin v. Löwis
@Martin: if /dev/null is open for reading, then you can read from it (but you get no information - just 'EOF'). If someone is expecting to read from a nominally write-only channel (that is, the code is reading from standard output), then it has serious problems (but you can often get away with it when standard output is the terminal).
Jonathan Leffler
+5  A: 

This doesn't exactly answer your question, but it could. Have you tried using gdb? It's a command-line debugging tool that can find where segfaults are occurring. It's fairly easy to use. Here is a pretty in-depth tutorial on how to use it.

Lucas McCoy
Good idea - I've used it a little before. When I run "gdb ./my_binary > /dev/null", though, I also lose the interface for gdb - how can I start gdb on my process with its stdout redirected?
Tyler
@Tyler: check the options for run within `gdb`: `gdb ./my_binary` on the command line (or add the name of the core dump if you have one), and then run the program with 'run >/dev/null'.
Jonathan Leffler
Thanks, Jonathan!
Tyler