I run the command./a.out < in &> output.txt
I want the errors also to be placed in output.txt.
The exit status of the command was 139 and on terminal its output was:
Segmentation fault (core dumped)
and the file output.txt was empty.
The message Segmentation fault (core dumped) is not coming from your program.
It's produced by shell as result of a signal received by it. It's not a part of stderr or stdout of your program.
So shell's message can be captured as:
{ ./a.out; } 2> out_err
If you want both the error messages from a.out and the string
Segmentation fault (core dumped)
to be appended to output.txt, then you have to redirect the shell's stderr as well. E.g.,
exec 2>> output.txt && ./a.out < in 2>&1 >> output.txt &
This is because the segfault message is coming from the shell itself.
Related
I'm trying to debug PHP segmentation fault in my CI. I managed to get the GDB stacktrace by running phpunit like this:
gdb php -ex "run vendor/bin/phpunit" -ex bt -ex quit
The problem is that this way I do not know if phpunit succeeded or failed (doesn't matter if it failed with segfault or with test failure). I need to somehow log the exit code of the vendor/bin/phpunit command and use it in an if statement later - to decide whether or not the build succeeded.
The problem is that this way I do not know if phpunit succeeded or failed (doesn't matter if it failed with segfault or with test failure)
You can print the value of $_exitsignal variable. In case of SIGSEGV signal it would be equal to 11. Also you can use $_isvoid function to know if the program exited or signalled. For this code:
#include <signal.h>
int main (int argc, char *argv[])
{
raise (SIGSEGV);
return 0;
}
you can invoke gdb this way:
$ gdb -q -ex run -ex bt -ex c -ex "print \$_isvoid(\$_exitsignal)" -ex quit a.out
Reading symbols from a.out...
Starting program: /tmp/a.out
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e1e9e5 in raise () from /lib64/libc.so.6
#0 0x00007ffff7e1e9e5 in raise () from /lib64/libc.so.6
#1 0x000000000040113f in main (argc=1, argv=0x7fffffffd6e8) at 1.c:5
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
$1 = 0
At the end of output you can see that the program ended with signal, $_isvoid($_exitsignal) returned 0:
$1 = 0
I have a program that is seg faulting and I reproduce in gdb as follows:
$ gdb myprogram
(gdb) run mycmdlineargs
Program received signal SIGSEGV, Segmentation fault.
If I type:
(gdb) list
it shows me the source code line where the seg fault occurs, but I would like to see the disassembly (preferably annotated with source code). What command can I use to do that?
You want the disassemble command.
I used to call my program with this line in bash shell to capture all stdout and stderr messages in the log file
./a.out input.txt 2>&1 | tee log
The log file shows no error but by examining the log, it's obvious that there's a problem and program terminates abruptly in the middle of execution.
I have also tried these but the result is the same:
./a.out input.txt > log 2>&1
./a.out input.txt |& tee log
When I run it without any redirection like this:
./a.out input.txt
I see the error message in my terminal window at the end:
*** Error in `./a.out': free(): invalid pointer: 0x000000000169b268 ***
Aborted (core dumped)
So, why I cannot capture the "core dumped" message in my log? What should I do to do so?
There are 2 error messages here:
*** Error in `./a.out': free(): invalid pointer: 0x000000000169b268 ***
This comes from glibc, and is printed on the current tty, if it exists.
If you want it printed to stderr (wherever stderr is redirected), you must set
the LIBC_FATAL_STDERR_ prior to starting the program.
e.g. in bash do:
export LIBC_FATAL_STDERR_=1
The other message
Aborted (core dumped)
This comes from the shell that started your program, by the shell examining the status of wait().
If the program isn't run by a shell, or e.g. is run by a shell that have terminated, you'll not be able to capture that message. Even if the shell havn't terminated, the stderr of that shell isn't redirected to your log file.
You might get around that by doing:
{ ./a.out input.txt ; } >log 2>&1
See also redirection of ./a.out is not capturing segmentation fault)
How can I redirect execution errors of a c++ executable in bash? I've found that 2> helps while trying identify compilation errors:
g++ example.cpp 2> compErr.txt
But running the executable with that command still sends the errors to stdout:
$ ./a.out 2> e.txt
Floating point exception (core dumped)
Actually, the error "Floating point exception (core dumped)" does not come from the executable but from the shell! The messages from bash won't be suppressed by output redirection but there is a flag to enable/disable these messages.
You can install signal handlers for some of the errors which would cause the program to exit and write something to a suitable destination there. Some signals can't be intercepted and some other are hard to handle. That's the approach you can do from inside your code.
If you want to go further you could fork() your program first thing and have the actual work done in the child process. The parent process would essentially just waitpid() for the child process and use the information in the result structure received to report errors to a file.
I found something that worked in my terminal, here: http://bytes.com/topic/c/answers/822874-runtime-error-stderr-gcc-ubuntu-bash
In summary, a participant explained:
In this particular case, the reason that the string "Floating point exception" is not >redirected is that it is not produced by the process that runs ./{file} or anything that it invokes. Instead,it is being produced by the command-interpreter itself.
You can see this by telling the command interpreter to run another command interpreter, redirecting this sub-interpreter's error output. However, a bit of a >trick is required:
$ bash -c './{file}; true' >out 2>err
$ cat out
$ cat err
bash: line 1: 28106 Floating point exception./test_fail
I run the command./a.out < in &> output.txt
I want the errors also to be placed in output.txt.
The exit status of the command was 139 and on terminal its output was:
Segmentation fault (core dumped)
and the file output.txt was empty.
The message Segmentation fault (core dumped) is not coming from your program.
It's produced by shell as result of a signal received by it. It's not a part of stderr or stdout of your program.
So shell's message can be captured as:
{ ./a.out; } 2> out_err
If you want both the error messages from a.out and the string
Segmentation fault (core dumped)
to be appended to output.txt, then you have to redirect the shell's stderr as well. E.g.,
exec 2>> output.txt && ./a.out < in 2>&1 >> output.txt &
This is because the segfault message is coming from the shell itself.