我的代码在 Go 中创建 QueryContext 时是否可能存在无效的内存访问?

问题描述 投票:0回答:1

我写的代码如下。

rows, err := s.db.QueryContext(context.TODO(), "select * from mytable")
if err != nil {
        log.WithFields(log.Fields{
            "query": queryString,
        }).Errorln("failed to query, ", err)
        return err
    }
resultString, err := getResultString(rows)

我还添加了

getResultString
,如下所示。

func getResultString(rows *sql.Rows) (*string, error) {
    defer rows.Close()

    var result string
    if rows.Next() {
        if err := rows.Scan(&result); err != nil {
            return nil, fmt.Errorf("scan err, %v", err)
        } else {
            return &result, nil
        }
    }
    return nil, fmt.Errorf("query err, %v", rows.Err())
}

此代码是根据gosnowflake中如何使用查询的示例编写的。

运行应用程序时,有时会出现如下内存问题。

2024-05-14T13:42:08.689+09:00   panic: runtime error: invalid memory address or nil pointer dereference
2024-05-14T13:42:08.689+09:00   panic: runtime error: invalid memory address or nil pointer dereference
2024-05-14T13:42:08.689+09:00   [signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x7d8848]
2024-05-14T13:42:08.689+09:00   goroutine 143 [running]:
2024-05-14T13:42:08.689+09:00   github.com/snowflakedb/gosnowflake.(*snowflakeRows).Close(0x10?)
2024-05-14T13:42:08.689+09:00   /home/ec2-user/go/pkg/mod/github.com/snowflakedb/[email protected]/rows.go:67 +0x18
2024-05-14T13:42:08.689+09:00   database/sql.(*Rows).close.func1()
2024-05-14T13:42:08.689+09:00   /usr/lib/golang/src/database/sql/sql.go:3287 +0x34
2024-05-14T13:42:08.689+09:00   database/sql.withLock({0xb788d8, 0x40033dbc20}, 0x40008ecf48)
2024-05-14T13:42:08.689+09:00   /usr/lib/golang/src/database/sql/sql.go:3405 +0x7c
2024-05-14T13:42:08.689+09:00   database/sql.(*Rows).close(0x4000097980, {0x0, 0x0})
2024-05-14T13:42:08.689+09:00   /usr/lib/golang/src/database/sql/sql.go:3286 +0x130

在努力解决这个问题之后,但我怀疑这一点。

正如您在上面所看到的,我在函数中创建了行并将它们作为参数传递给另一个函数 (

getResultString
)。虽然这个过程,我认为可能会发生一些内存损坏,因为我看到的代码示例是所有逻辑都包含在一个函数中,这与我的代码形成对比。

所以我怀疑将

row
传递给其他函数可能会导致潜在的问题。

我的怀疑合理吗?否则,您有什么解决问题的建议吗?

谢谢,

go snowflake-cloud-data-platform
1个回答
0
投票

实际上

Close()
在这里什么也没做,请参阅此链接 https://github.com/snowflakedb/gosnowflake/blob/c355711dbd1f9ab10dfbfdcdd194656c23abb45d/rows.go#L76

并且您的代码没有问题,这主要是来自

github.com/snowflakedb/gosnowflake
库的错误。 还请继续重构
getResultString(rows *sql.Rows)
,如下所示:

func getResultString(rows *sql.Rows) (*string, error) {
    if err = rows.Next(); err != nil {
        // Next failed with an error, you can wrap the error using errors.Join
        return nil,err
    }
    var result string
    if err = rows.Scan(&result); err != nil {
        // scan fails
        return nil,err
    }
    return &result,nil
}
© www.soinside.com 2019 - 2024. All rights reserved.