0

It's easy to redirect a golang panic to a file, just use recover() to capture that and use syscall.Dup2() to redirect. But when it comes to a C panic, it seems to be useless, just like the image, the console will show the error message like "fatal error: unexpected signal during runtime execution" and some stack message. How to redirect these error message to a file

package main

/*
#include <stdio.h>
void sayHi(int a, int b) {
int c = a/b;
}
*/
import "C"

import (
"runtime/debug"
"syscall"
"os"
"log"
)
func main() {
    logFile, logErr := os.OpenFile("/home/error.log",   os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
    if logErr != nil {
       log.Println("Fail to find", *logFile)
       os.Exit(1)
     }
     log.SetOutput(logFile)
     defer func() {
     if r := recover(); r != nil {
          syscall.Dup2(int(logFile.fd()), 2)
          debug.PrintStack()
      }
      }()
      C.sayHi(1, 0)
}

ps:The key point is how to redirect the error message on the terminal screen to a file?

sentry
  • 1
  • 1

1 Answers1

0

Integer division by zero at runtime in C does not result in a traditional panic() that you can recover() from. It turns out the C standard does not define a specific action to be taken in this case; this is called "undefined behavior", and you should be working to avoid it (for instance, by checking your denominators).

But I assume you are only using that as an example; it just turns out to not be a very good example.

What can happen in C, and what you're getting in your case, is that the operating system can throw a signal. Signals are a way for the operating system to notify a traditional C program that something went wrong, for instance that the user hit control-C (asking to terminate the process) or that a floating-point exception occurred. You can catch these from Go with the os/signal package, but note that only the Interrupt and Kill signals are available on all OSs (and only Interrupt can be caught; Kill cannot). See the package documentation for details.

andlabs
  • 11,290
  • 1
  • 31
  • 52
  • 1
    Yes,It's just an example, In linux , Integer division by zero is SIGFPE, and we can use signal.Notify(c, syscall.Signal(0x8)) to handle that. The question is how can I redirect the error message printed in the console window to a file – sentry Jul 15 '16 at 18:21
  • Once you catch the signal, you should be able to do whatever you want, no? Or do you want to use the runtime's behavior? If so, you'll have to change the runtime or redirect stderr outside your program; there's no way to change what runtime does otherwise, sorry. – andlabs Jul 15 '16 at 18:22
  • Do you mean that If I catch the signal , I just fix the problem to avoid the error? – sentry Jul 15 '16 at 18:32
  • When the C code panic, Does golang print the error message via stderr?I just don't know how to get the error message on the terminal screen to a file.I think it can be done theoretically – sentry Jul 15 '16 at 18:52