运行时错误:查询时无效的内存地址或nil指针取消引用

时间:2018-08-17 16:21:18

标签: sqlite go

我一直在开发用于身份验证的API,在尝试将其部署到服务器上时,偶然发现了这个奇怪的错误。该代码在我的笔记本电脑上可以正常工作,但是一旦我尝试部署它,就会发生此错误:

PANIC: runtime error: invalid memory address or nil pointer dereference
goroutine 21 [running]:
github.com/urfave/negroni.(*Recovery).ServeHTTP.func1(0x7f5771b811e8, 0xc4200980e8, 0xc42009a870, 0xc420138800)
    /home/linux/go/src/github.com/urfave/negroni/recovery.go:159 +0xef
panic(0x84ad60, 0xcc4f30)
    /usr/local/go/src/runtime/panic.go:502 +0x229
database/sql.(*Rows).close(0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/database/sql/sql.go:2907 +0x6b
database/sql.(*Rows).Close(0x0, 0x0, 0x0)
    /usr/local/go/src/database/sql/sql.go:2903 +0x33
panic(0x8408e0, 0xc42008ab70)
    /usr/local/go/src/runtime/panic.go:502 +0x229
github.com/lars250698/iotmap/api/models.PassQuery(0xc420096d38, 0x4, 0xc4201129a0, 0x0)
    /home/linux/go/src/github.com/lars250698/iotmap/api/models/user.go:35 +0x236
github.com/lars250698/iotmap/api/controllers.Auth(0x7f5771b811e8, 0xc4200980e8, 0xc420138b00)
    /home/linux/go/src/github.com/lars250698/iotmap/api/controllers/auth.go:28 +0x151
net/http.HandlerFunc.ServeHTTP(0x8d1d60, 0x7f5771b811e8, 0xc4200980e8, 0xc420138b00)
    /usr/local/go/src/net/http/server.go:1947 +0x44
github.com/gorilla/mux.(*Router).ServeHTTP(0xc42013e850, 0x7f5771b811e8, 0xc4200980e8, 0xc420138b00)
    /home/linux/go/src/github.com/gorilla/mux/mux.go:162 +0xed
github.com/gorilla/handlers.(*cors).ServeHTTP(0xc42014a480, 0x7f5771b811e8, 0xc4200980e8, 0xc420138800)
    /home/linux/go/src/github.com/gorilla/handlers/cors.go:52 +0xa3b
github.com/urfave/negroni.Wrap.func1(0x7f5771b811e8, 0xc4200980e8, 0xc420138800, 0xc420112980)
    /home/linux/go/src/github.com/urfave/negroni/negroni.go:46 +0x4d
github.com/urfave/negroni.HandlerFunc.ServeHTTP(0xc420112800, 0x7f5771b811e8, 0xc4200980e8, 0xc420138800, 0xc420112980)
    /home/linux/go/src/github.com/urfave/negroni/negroni.go:29 +0x4e
github.com/urfave/negroni.middleware.ServeHTTP(0x9019c0, 0xc420112800, 0xc420112880, 0x7f5771b811e8, 0xc4200980e8, 0xc420138800)
    /home/linux/go/src/github.com/urfave/negroni/negroni.go:38 +0xa5
github.com/urfave/negroni.(middleware).ServeHTTP-fm(0x7f5771b811e8, 0xc4200980e8, 0xc420138800)
    /home/linux/go/src/github.com/urfave/negroni/negroni.go:38 +0x60
github.com/urfave/negroni.(*Static).ServeHTTP(0xc42008ff20, 0x7f5771b811e8, 0xc4200980e8, 0xc420138800, 0xc420112960)
    /home/linux/go/src/github.com/urfave/negroni/static.go:34 +0x8c
github.com/urfave/negroni.middleware.ServeHTTP(0x900e00, 0xc42008ff20, 0xc420112860, 0x7f5771b811e8, 0xc4200980e8, 0xc420138800)
    /home/linux/go/src/github.com/urfave/negroni/negroni.go:38 +0xa5
github.com/urfave/negroni.(middleware).ServeHTTP-fm(0x7f5771b811e8, 0xc4200980e8, 0xc420138800)
    /home/linux/go/src/github.com/urfave/negroni/negroni.go:38 +0x60
github.com/urfave/negroni.(*Logger).ServeHTTP(0xc42008f9b0, 0x7f5771b811e8, 0xc4200980e8, 0xc420138800, 0xc420112940)
    /home/linux/go/src/github.com/urfave/negroni/logger.go:62 +0x8e
github.com/urfave/negroni.middleware.ServeHTTP(0x900da0, 0xc42008f9b0, 0xc420112840, 0x7f5771b811e8, 0xc4200980e8, 0xc420138800)
    /home/linux/go/src/github.com/urfave/negroni/negroni.go:38 +0xa5
github.com/urfave/negroni.(middleware).ServeHTTP-fm(0x7f5771b811e8, 0xc4200980e8, 0xc420138800)
    /home/linux/go/src/github.com/urfave/negroni/negroni.go:38 +0x60
github.com/urfave/negroni.(*Recovery).ServeHTTP(0xc42009a870, 0x7f5771b811e8, 0xc4200980e8, 0xc420138800, 0xc420112920)
    /home/linux/go/src/github.com/urfave/negroni/recovery.go:193 +0x8c
github.com/urfave/negroni.middleware.ServeHTTP(0x900de0, 0xc42009a870, 0xc420112820, 0x7f5771b811e8, 0xc4200980e8, 0xc420138800)
    /home/linux/go/src/github.com/urfave/negroni/negroni.go:38 +0xa5
github.com/urfave/negroni.(*Negroni).ServeHTTP(0xc42008ff80, 0x904660, 0xc42012e1c0, 0xc420138800)
    /home/linux/go/src/github.com/urfave/negroni/negroni.go:96 +0xf2
net/http.serverHandler.ServeHTTP(0xc420091040, 0x904660, 0xc42012e1c0, 0xc420138800)
    /usr/local/go/src/net/http/server.go:2694 +0xbc
net/http.(*conn).serve(0xc4200a74a0, 0x9049a0, 0xc42009c500)
    /usr/local/go/src/net/http/server.go:1830 +0x651
created by net/http.(*Server).Serve
    /usr/local/go/src/net/http/server.go:2795 +0x27b

我的代码:

package models

import (
    "database/sql"
    _ "github.com/mattn/go-sqlite3"
)

type User struct {
    Id int `json:"id"`
    User string `json:"user"`
    Admin bool `json:"admin"`
}

func PrepareSqlite() (db *sql.DB, err error) {
    db, err = sql.Open("sqlite3","./auth.db")
    if err != nil {
        panic(err)
        return
    }
    defer db.Close()
    // My other Laptop fails here
    statement, _ := db.Prepare("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT, passw TEXT, admin INTEGER)")
    statement.Exec()
    return db, nil
}

func PassQuery(username string) (pass string) {
    db, err := PrepareSqlite()
    if err != nil {
        panic(err)
        return
    }
    // Server fails here
    rows, err := db.Query("SELECT passw FROM users WHERE username=\"" + username + "\"")
    defer rows.Close()
    if err != nil {
        panic(err)
        return
    }
    for rows.Next() {
        rows.Scan(&pass)
    }
    return pass
}

有人知道为什么会发生这种情况吗?我的机器正在运行Arch,服务器在Debian上。我已经尝试使用其他几个gosqlite驱动程序。在另一台机器上,发生类似的错误,但是当调用db.Prepare(...)时,stacktrace显示它在PrepareSqlite()方法中发生。至此我还不知道这可能是什么。

编辑:我尝试删除延迟的row.Close(),这给了我错误“数据库已关闭”。之后,我尝试直接在PassQuery()方法中打开数据库,这再次给了我第一个错误。我怀疑这可能与打开数据库有关,但是我不确定。

1 个答案:

答案 0 :(得分:1)

在您的PrepareSqlite方法中,您将延迟对db.Close()的调用,这意味着一旦该方法返回,数据库连接将关闭。

然后,您尝试在PassQuery中使用该关闭的数据库连接,这引起了恐慌(您不应尝试使用关闭的数据库连接)。

您应该从defer db.Close()方法中删除PrepareSqlite,并在使用完连接后才调用db.Close()