0
votes

I had an application where I was occasionally crashing with a:

panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x122e64a]

The trace kept leading to a return statement that returned a struct and errors.New("Some text for debugging: " + err.Error())

The struct didn't seem to have anything that would be dereferencing a pointer, but I restructured the function so it used a pass by reference and didn't need to return the function; it only returned the errors.New(). The panic still happened.

I went through the function and changed it so it returned just the err, no errors.New() string plus err.Error(). Now I can't seem to induce the panic anymore...

So the question: is there something about errors.New() using the err.Error() concatenated to a string that would cause that type of panic in a return statement?

EDIT: Adding a snippet of code that triggered the occasional panic:

strctStats.intThreadPool80ConnectionCount, err = strconv.ParseInt(strctStats.strThreadPool80ConnectionCount, 10, 64)
if err != nil {
    // Exit external application; send the closing sequences
    tmPause := time.NewTimer(time.Second * 2)
    <-tmPause.C
    stdIn.Write([]byte("close\n"))
    tmPause = time.NewTimer(time.Second * 2)
    <-tmPause.C
    stdIn.Write([]byte("quit\n"))
    return errors.New("Could not parse integer: " + err.Error())
}

EDIT 2: @lmars requested a stack trace. This is what is dumped to the console. Not sure how it helps (could you explain what it tells beyond the function stack and line numbers where the error/calls originated? I'm new to working on some of these traces)

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x122e64a]

goroutine 1 [running]:
main.JMXCheck(0xc42012c000, 0x1a, 0xc420018084, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)

/Users/bsilver/go/src/nagios_tomcat_threadinfo/nagios_tomcat_threadinfo.go:590 +0x38ca
main.main()
/Users/bsilver/go/src/nagios_tomcat_threadinfo/nagios_tomcat_threadinfo.go:146 +0x3cc
1
if err is nil, then err.Error is a nil pointer dereference. It's possible that err.Error() dereferences a nil pointer somewhere else, but we can't tell without the stack trace or context around where you're calling it.JimB
did you maybe do if err == nil { return errors.New("Some text for debugging: " + err.Error()) } instead of if err != nil?dave
@JimB - My first impulse was thinking err was nil, but the return was in an "if err != nil" block.Bart Silverstrim
@dave - I triple checked...all the if err's are != checks. That's part of why this was so strange to me!Bart Silverstrim
@BartSilverstrim: you're not showing how err is declared and used up to that point. I'm guessing it has had a typed nil assigned to it at some point. Use fmt.Errof or stick a fmt.Printf in there and see what the actual value of err is. (BTW, there is a time.Sleep function)JimB

1 Answers

1
votes

Here's an example,

package main

import (
    "errors"
)

func f() error {
    err := error(nil)
    return errors.New("Could not parse integer: " + err.Error())
}

func main() {
    f()
}

Output:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x44ecd6]

goroutine 1 [running]:
main.f(0xc420022070, 0xc420022070)
    /home/peter/gopath/src/so/error.go:9 +0x26
main.main()
    /home/peter/gopath/src/so/error.go:13 +0x22
exit status 2

See How to create a Minimal, Complete, and Verifiable example..