【问题标题】:Golang flock filelocking throwing panic: runtime error: invalid memory address or nil pointer dereferenceGolang 集群文件锁定引发恐慌:运行时错误:无效的内存地址或 nil 指针取消引用
【发布时间】:2016-01-10 20:31:55
【问题描述】:

我有一个修改我的配置文件的 go 程序。我正在尝试从 main() 函数中创建一个文件锁,但它抛出了 panic: runtime error: invalid memory address or nil pointer dereference 错误。没有锁,程序可以按预期正常工作。抛出异常的代码是

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

//这是在一个单独的包中

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);
}

当我在我的配置文件上调用它时,同样的flock 正在工作,但是来自不同的包,而不是主包,但是当我尝试从主包中放置锁时会抛出相同的错误。请帮助我找出我在这里做错了什么。

【问题讨论】:

  • 您在检查错误之前调用了 defer。如果有错误,文件将为 nil。
  • @JimB,如果我错了,请纠正我,但是 defer 是堆叠的,只有在函数即将完成时才会执行,对吗?会不会造成问题?
  • 没关系。如果你的函数结束并且lockProgram 为零,你会感到恐慌。如果您想推迟关闭,您需要检查错误并提前返回
  • 谢谢@JimB,这有帮助。
  • 当你的程序崩溃时,你会得到堆栈跟踪。请告诉确切发生恐慌的地方。它在您的 CheckForError 函数中吗?

标签: file go flock filelock panic


【解决方案1】:

当创建锁时发生错误时,lockProgram 将是nil。这将导致对lockProgram.Close() 的后续(延迟)调用失败。

请注意,当您感到恐慌时(例如在您的 CheckForError 函数中),延迟的方法调用仍将被执行。这在this blog article(强调我的)中有详细解释:

Panic 是一个内置函数,它会停止普通的控制流程并开始恐慌。当函数 F 调用 panic 时,F 的执行停止,F 中的所有延迟函数都正常执行,然后 F 返回其调用者。对调用者来说,F 的行为就像是对恐慌的调用。该进程继续向上堆栈,直到当前 goroutine 中的所有函数都返回,此时程序崩溃。

解决方法:先检查错误,然后推迟Close()调用:

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

【讨论】:

    猜你喜欢
    • 2015-02-24
    • 2022-01-05
    • 2016-12-12
    • 1970-01-01
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    • 2012-07-21
    相关资源
    最近更新 更多