3

I have a C program that uses PIPES to communicate with an external application.

I use EXECL for this:

execl("./errorprogram","./errorprogram", NULL);

Now I have also used DUP2 to redirect all STDERR to the writing end of the pipe

dup2(fd[1], STDERR_FILENO);

And if I test that using a simple Python script like:

data = sys.stdin.read() 
sys.stderr.write("Bad error\n")

I can happily read that error back in the "parent".

Now for my issue: Let's say I have a C "child program" that has a memory leak in it or an "invalid pointer" error like:

#include<stdio.h>
#include<string.h>

void main (){
    char szInput[1024];
     char *badvar;
    gets(szInput);

     badvar = realloc(badvar, 100);
    puts(szInput);
    fflush(NULL); 
}

The REALLOC statement above is purposely there to cause the program to die, and I will get an error like the following at runtime (obvioulsy the PARENT is not affected, only the CHILD process):

* glibc detected ./error: realloc(): invalid pointer: 0xb77a5250 **

And a whole stace trace etc....

Now how can I get any runtime errors like this to STDERR so I can read the full trace back into the parent?

Do I have to redirect "runtime errors to STDERR"? Surely it is possible to catch these hectic errors raised from the child so that the parent can log them etc?

Any help or advise would be greatly appreciated ;-)

Thanks

Lynton

Lynton Grice
  • 1,435
  • 3
  • 29
  • 45

2 Answers2

5

By default, Glibc will produce output on the process's controlling terminal, if one exists. It sounds like you want to set the environment variable LIBC_FATAL_STDERR_=1, which will instead send fatal errors to stderr always.

ephemient
  • 198,619
  • 38
  • 280
  • 391
  • Thanks, that is useful, but I just set that ENV variable on my Debian machine and ran the code again and it still puts it out to the screen even though I have redirected STDERR to the writing end of the pipe (so the parent can read back the error message). And reason why this is not working? – Lynton Grice Nov 27 '10 at 12:16
  • 1
    Are you sure you set and exported the variable correctly? Glibc has obeyed this switch [for years](http://sourceware.org/git/?p=glibc.git;a=commit;h=1327439fc6ef182c3ab8c69a55d3bee15b3c62a7), except in setuid/setgid programs. – ephemient Nov 27 '10 at 17:04
  • I had this problem years ago and never found the reason! Is there any official documentation of this anywhere? – Gavin Smith Jun 02 '14 at 11:47
0

One possible solution if you are working on a system that supports signals, such as linux, is to use the signalling mechanism. Installing a signal action for invalid memory references (I believe this is the SIGSEGV signal) should, I think, catch the particular example you give above. In the handler you can then print error messages to STDERR as you wish. You would still need some way to determine the stack trace, however.

River
  • 1,504
  • 13
  • 21
  • Hi there, thanks for the comments on SIGNALS, I will try it out....I was hoping there was a way to simply "redirect" but I suppose if signals are the only way then I will give it a try...thanks ;-) – Lynton Grice Nov 27 '10 at 06:36
  • If you do find a solution that behaves like you want, post it here. I'd be interested to know. – River Nov 27 '10 at 07:33
  • Will do, but to be honest I think signals is the only approach for now...but I will dig some more...;-) – Lynton Grice Nov 27 '10 at 12:39