My daemon-ish program panics, how can I get at the message?

<p>In normal terminal / CLI programs this is easy, the panic message is printed just as the program dies.</p>
<p>But what I have is a dead-simple json-rpc-ipc-via-pipes (no need for sockets here) concoction, the client being a nodejs app and my Go program acting as the clients &#34;server&#34;. They communicate brilliantly simply via writeln/readln ping-pong communication. (Neat because I can talk to the tool via terminal just like the client app would if needed to investigate the odd bug.)</p>
<p>Nonetheless some async background activity (goroutines, waitgroups, some mutexes) has by now made it into the go program and so it occasionally crashes and I&#39;m wondering how I can speed up my investigations here. This is regrettably not reproducable via terminal even when the exact same sequence of commands is sent manually as the client did to provoke the die-off --- so sth. timing-related and most likely goroutine-related.</p>
<p>Is the panic msg always printed to stderr? If I redirect stderr to a local file, will it allow flushing before proceeding to die? Can some custom logger be hooked up to Go&#39;s built-in &#34;print panic message&#34; logic? If I could just <em>see</em> the message that&#39;d be 80% of the battle.</p>
<p>(If that message is just sent to stdout I can already report it never makes it in time to my client or in any event node closes that pipe/ipc reader before allowing a final <code>line</code> event.)</p>
<hr/>**评论：**<br/><br/>Ballresin: <pre><p>I ran into a similar problem. Found I was often running into Index Out Of Range or nil pointers. Frustrating when the program dies silently.</p>
<p>I use this to grab a stack trace:</p>
<pre><code>func Stack() []byte {
buf := make([]byte, 1024)
for {
n := runtime.Stack(buf, false)
if n &lt; len(buf) {
return buf[:n]
}
buf = make([]byte, 2*len(buf))
}
}
</code></pre>
<p>And inside any top-level function or goroutine I suspect might panic, I recover and perform the dump:</p>
<pre><code>defer func() {
if err := recover(); err != nil {
log.Print(fmt.Sprintf(&#34;Recovering panic in myInfinityFunc(): %v&#34;, err))
log.Print(string(Stack()))
sendLogsToServer()
time.Sleep(3 * time.Second)
myInfinityFunc()
}
}()
</code></pre>
<p>Though if anyone has more brilliant approaches to this I&#39;m all ears too.</p>
<p>In my case it will echo to the logs, to the console if running interactive, as well as upload the logs to the server for investigation. I then kick the function off again after a short nap to help mitigate possible flapping.</p></pre>ZetaHunter: <pre><p>consider adding some recovery to catch the panic and print the error</p>
<p>also you should probably try your own ideas before coming for suggestions, that said, try logging stderr to a file as well.</p></pre>