dqde43215 2016-01-10 20:31
浏览 82
已采纳

Golang集群文件锁定引发恐慌:运行时错误:无效的内存地址或nil指针取消引用

I have a go program that modifies my configuration file. I am trying to create a filelock from within the main() function, but it is throwing a panic: runtime error: invalid memory address or nil pointer dereference error. Without the lock, the program is working fine as expected. The piece of code that throws exception is

lockProgram, err := os.Create("/var/.daemon.lock")
defer lockProgram.Close()
CheckForError(err)
GetLock(lockProgram, syscall.LOCK_EX)
defer UngetLock(lockProgram)

//This is in a separate package

func CheckForError(e error) {
    if e != nil {
        Error.Println(e)
        panic(e)
    }
}

func GetLock(file *os.File, locktype int )  {
    fmt.Println("Acquiring lock on ", file.Name())
    syscall.Flock(int(file.Fd()), locktype)
    fmt.Println("Acquired filelock on ", file.Name())
}
func UngetLock(file *os.File)  {
    syscall.Flock(int(file.Fd()), syscall.LOCK_UN);
}

This same flock is working when I call it on my configuration file, but from a different package, not main package, but throws the same error when I try to put lock from within the main package. Please help me in finding out what am I doing wrong here.

  • 写回答

1条回答 默认 最新

  • dpe77294 2016-01-10 20:39
    关注

    When an error occurs while creating the lock, lockProgram will be nil. This will cause the subsequent (deferred) call to lockProgram.Close() to fail.

    Note that when you're panicking (like in your CheckForError function), deferred method calls will still be executed. This is explained in detail in this blog article (emphasis mine):

    Panic is a built-in function that stops the ordinary flow of control and begins panicking. When the function F calls panic, execution of F stops, any deferred functions in F are executed normally, and then F returns to its caller. To the caller, F then behaves like a call to panic. The process continues up the stack until all functions in the current goroutine have returned, at which point the program crashes.

    Solution: Check for errors first, and then defer the Close() call:

    lockProgram, err := os.Create("/var/.daemon.lock")
    CheckForError(err)
    defer lockProgram.Close()
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?