请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

panic: runtime error: invalid memory address or nil pointer dereference

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

goroutine 1 [running]:
database/sql.(*DB).SetMaxOpenConns(0x0, 0xa)
/usr/local/go/src/database/sql/sql.go:847 +0x26
github.com/xiaobaiadm/filestore-server/db/mysql.init.0()
/Users/baijunhua/newgo/src/github.com/xiaobaiadm/filestore-server/db/mysql/conn.go:14 +0x7a

附代码,14行报上面的错误,这块实在不知道那错了,遇到这种问题怎么排查呢,烦请老师给个思路。

func init() {
db,_ = sql.Open(“mysql”,“dog:1233456@localhost/fileserver”)
db.SetMaxOpenConns(10)
if err := db.Ping(); err != nil {
fmt.Println(“db connet,err:”,err)
os.Exit(1)
}
}
//返回数据库连接
func DbConn() *sql.DB {
return db
}

正在回答 回答被采纳积分+3

插入代码

4回答

xiaomo 2020-04-02 08:24:49

可以看到sql.Open这个方法是有返回err信息的,源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func Open(driverName, dataSourceName string) (*DB, error) {
  driversMu.RLock()
  driveri, ok := drivers[driverName]
  driversMu.RUnlock()
  if !ok {
    return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
  }
 
  if driverCtx, ok := driveri.(driver.DriverContext); ok {
    connector, err := driverCtx.OpenConnector(dataSourceName)
    if err != nil {
      return nil, err
    }
    return OpenDB(connector), nil
  }
 
  return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
}

里面返回来的error是由底层的sql driver来提供的,不同的driver可能会返回不同信息。 为了可以处理这种异常,我们这里的代码需要优化一下:

1
2
3
4
5
6
7
8
9
10
db, err := sql.Open("mysql", "test:test@tcp(127.0.0.1:3306)/fileserver?charset=utf8")
if err != nil {
  panic(err)  // 这里是否直接panic, 根据具体场景决定(也可以增加重试,或者只报warning后续再做处理)
}
db.SetMaxOpenConns(1000)
err := db.Ping()
if err != nil {
  fmt.Println("Failed to connect to mysql, err:" + err.Error())
  os.Exit(1)
}


0 回复 有任何疑惑可以回复我~
xiaomo 2020-04-02 08:19:12

处理panic的一般做法是捕获异常,和其他语言的try-catch是类似的原理,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
func doSomething(index int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("异常捕获:%s\n", r)
        }
    }()
 
    if index < 0 {
        panic("index必须大于0")
    }
 
    fmt.Println("方根运算:", math.Sqrt(float64(index)))
}

上述的init方法中,在创建Mysql连接时可以优化一下,加上类似逻辑.

0 回复 有任何疑惑可以回复我~
提问者 慕函数5852696 2020-04-01 12:25:37

已经修复了 ,确实我之前某块地方写错了 ,今天早上尝试的时候好了,但是如果这块没有明显的错误,例如连接数据库出现账号密码错误等这样的明确的信息提示,直接来了一个panic ,出现这种情况我该怎么具体的排查呢,因为在这块开发中可能会遇到各种各样的panic ,有工具或者是什么可以排查代码么,让输出更明确一些,麻烦老师能给个思路,谢谢。
之前还遇到了 编译过程中的panic 

0 回复 有任何疑惑可以回复我~
xiaomo 2020-04-01 08:19:37

同学你好,这个应该是与数据库建立连接没有成功。上面的14行的代码应该是这行?

1
db.SetMaxOpenConns(10)

这说明以下这行代码出了问题:

1
db,_ = sql.Open(“mysql”,“dog:1233456@localhost/fileserver”)

可以参考下git上的代码:https://git.imooc.com/coding-323/filestore-server/src/charter3/db/mysql/conn.go

1
2
3
4
5
6
7
8
9
10
11
var db *sql.DB
 
func init() {
    db, _ = sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/fileserver?charset=utf8")
    db.SetMaxOpenConns(1000)
    err := db.Ping()
    if err != nil {
        fmt.Println("Failed to connect to mysql, err:" + err.Error())
        os.Exit(1)
    }
}

把你的代码换成:

1
db,_ = sql.Open(“mysql”,“dog:1233456@tcp(127.0.0.1:3306)/fileserver?charset=utf8”)

这样试试看。还有就是检查用户名(dog)密码(1233456)是否正确?

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号