duancao2082 2018-08-17 16:21
浏览 45
已采纳

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

I've been working on an API for authentication, and while trying to deploy it on a server I stumbled upon this odd bug. The code works perfectly fine on my laptop, but as soon as I try to deploy it, this error occurs:

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

My code:

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
}

Anyone got any idea why this might happen? My machine is running Arch, the server is on Debian. I've already tried using several other gosqlite-drivers. On yet another machine, a similar error occurs, but the stacktrace shows that it occurs in the PrepareSqlite() method when calling db.Prepare(...). By this point I have no idea what this might be.

Edit: I've tried removing defer rows.Close(), which gave me the Error "Database is closed". After that, I've tried opening the database directly in the PassQuery() method, which gave me the first error once again. I suspect it might be something with opening the database, but I'm not sure what.

  • 写回答

1条回答 默认 最新

  • douluchuo0801 2018-08-18 00:05
    关注

    In your PrepareSqlite method, you are deferring a call to db.Close() which means the database connection is closed once the method returns.

    You are then trying to use that closed db connection in the PassQuery, which is causing the panic (you shouldn't try to use a closed db connection).

    You should remove the defer db.Close() from the PrepareSqlite method and only call db.Close() once you have finished using the connection.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 个人网站被恶意大量访问,怎么办
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制