tags:

views:

87

answers:

3

I wrote a code to get a runtime error intentionally:

int main()
{
 int a=5;
 printf("Hello World\n");
 printf("a=%s\n", a);
}

It gives:

$ ./error.o
Hello World
Segmentation Fault
$

Now, to record the runtime errors, I do:

$ ./error.o > so.txt
$ ./error.o &> soe.txt

But both the files are empty. Why?

EDIT:

I'm actually writing a script for remote compilation and execution of a c program. From the answers I get that Segmentation Fault is not the program's error output. So, is there a way to capture that output? Also, the program is just a sample, so I can't add the statements. Can line-buffering be done any other way with redirections?

+9  A: 

so.txt is empty because stdout didn't get flushed before the crash so the buffered content was lost. If you add: fflush(stdout); between the printf-commands, it will contain the expected text.

Your soe.txt is missing also the the message "Segmentation Fault" because it was printed by the shell, not by your program and thus wasn't part of your program's output that was to be redirected.

If you can't modify the code, you can turn on line buffering by fooling the program to think it's printing to a tty. Create the script error.sh:

#!/bin/sh
./error.o

Then do chmod a+x error.sh and call it like this on Linux:

script soe.txt -c ./error.sh

Or like this on OS X:

script soe.txt ./error.sh

The exact output is somewhat system-dependent but will probably contain both "Hello World" and "Segmentation Fault".

Also consider adding appropriate #include lines and returning a value from main.

jjrv
is there a way to capture the `Segmentation fault` in the file? can I run another bash inside the bash and do so?
lalli
Yes, answer updated.
jjrv
ah, thanks.....
lalli
Also the actual code contains the #include and return. I just typed it here instead of copy-pasting, so forgot those things...
lalli
+7  A: 

Because a segmentation fault is serious. Buffers don't get flushed, your process just gets shut down violently.

The reason you see the text when you run without redirection is that standard output is line buffered (ISO C mandates that full buffering is used only if the device can be determined not to be an interactive one). In other words, it will flush whenever it sees a newline, and that happens before your invalid de-referencing.

But because the file output is not line-buffered, the information is still waiting to be sent out when your program's universe is yanked out from under it.

Although support for this is implementation-defined, you can set a specific file handle to be line buffered by using setvbuf with the _IOLBF mode, something like:

setvbuf (stdin, NULL, _IOLBF, BUFSIZ);

at the start of main() - it saves a substantial amount of typing over having to fflush every output line.

paxdiablo
is there a way to buffer the lines with the redirections?
lalli
thanks, guess I have to fool the scheduler then...
lalli
@lalli, yes you can, I've often done this to avoid having to put `fflush()` everywhere. See the update on `setvbuf()`.
paxdiablo
+2  A: 

I think this should do it:

echo ./error.o | sh > error.txt
fortran
oh, this helps, thanks..
lalli