I want to write a automatic C program checker.
For example, I have a toy "hello.c" program:
#include <stdio.h>
int main()
{
int a, b;
while (scanf("%d %d", (&a)-1000000000000000, &b) != EOF)
{
printf("%d\n", a+b);
}
return 0;
}
And here is my input file "1.in":
1 2
4 5
10 10
2 2
3 2
7 4
and output file "1.out":
3
9
20
4
5
11
I use "gcc hello.c -o hello.o" to compile and generate an executable program "hello.o". Obviously, the program will meet "segment fault": (Run in my MAC OS X)
$ ./hello.o <1.in
Segmentation fault: 11
But I want to make an auto checker using pipe and diff:
./hello.o <1.in | diff - 1.out
And the output is:
0a1,6
> 3
> 9
> 20
> 4
> 5
> 11
No error message display! But I want to display them in the terminal (MAC OS X).
I try to redirect stderr to stdout like:
./hello.o <1.in 2>&1 | diff - 1.out
But no effect!
I also try to redirect stderr to a file like:
./hello.o <1.in 2>log
and the info "Segmentation fault: 11" display in the terminal while nothing in the file.
The same situation happens when I use
./hello.o <1.in &>log
Maybe the error info isn't in stderr.
So, how can I solve this problem? Thank you!
Best Answer
NOTE: I've replaced
hello.o
withhello
, since the.o
file extension in this context would typically denote an object file and not the final executable program.According to your post, you want to run the command:
And you want the error message from running
./hello <1.in
to appear in the output of this command. However the error message isn't coming from thehello.o
program itself, but from the shell. The closest thing I can think of for approximating the desired effect with a single line is to run the command in a subshell and then use this output with yourdiff
command:This gives us the following output:
The only difference is that in this case you get some additional metadata output by the shell (i.e. the line number and the command string). If you want to exactly replicate the error message, then you can use
trap
to insert a hook which prints out exactly the right string.I couldn't find a way to programmatically extract the error message, so I went to the Bash source code and searched for the "Segmentation fault" message. I found it in a file called siglist.c, along with a bunch of other signals and error descriptions. Using that information I wrote the following script:
Now, using this script, we can run the following command:
This produces the same string as running
./hello <1.in
:But now you can capture that string from standard error (stderr) and pipe it to
diff
like you wanted:This produces the exact output that you would have gotten if the error message had been written to standard output you had originally expected: