登录
首页 >  Golang >  Go问答

Go测试中发生的意外错误调试

来源:stackoverflow

时间:2024-03-13 18:30:28 463浏览 收藏

Golang不知道大家是否熟悉?今天我将给大家介绍《Go测试中发生的意外错误调试》,这篇文章主要会讲到等等知识点,如果你在看完本篇文章后,有更好的建议或者发现哪里有问题,希望大家都能积极评论指出,谢谢!希望我们能一起加油进步!

问题内容

我有一个 go 二进制文件,现在我对其进行了一些测试,这些测试都应该并行运行。 因此,我有很多 _test 包,并且所有 test* 都包含对 t.parallel() 的调用。

go 二进制文件使用 2 个第三方模块,我已经在其中发现(并修复了)并发问题。对我来说不存在明显的并发问题。使用 -race 运行也不会产生任何投诉。

现在使用 go clean -testcache && go test 执行所有测试 ./... 每 4 次运行一次左右:

unexpected fault address 0x2d84420
fatal error: fault
[signal sigsegv: segmentation violation code=0x1 addr=0x2d84420 pc=0x4730e5]

goroutine 15 [running]:
runtime.throw(0x129fe7b, 0x5)
        /usr/lib/go-1.15/src/runtime/panic.go:1116 +0x72 fp=0xc000074810 sp=0xc0000747e0 pc=0x439612
runtime.sigpanic()
        /usr/lib/go-1.15/src/runtime/signal_unix.go:727 +0x405 fp=0xc000074840 sp=0xc000074810 pc=0x44fda5
runtime.memmove(0xc000680000, 0x1236820, 0x1b4dc80)
        /usr/lib/go-1.15/src/runtime/memmove_amd64.s:392 +0x485 fp=0xc000074848 sp=0xc000074840 pc=0x4730e5
fmt.(*buffer).writestring(...)
        /usr/lib/go-1.15/src/fmt/print.go:82
fmt.(*fmt).padstring(0xc00009f2f0, 0x1236820, 0x1b4dc80)
        /usr/lib/go-1.15/src/fmt/format.go:110 +0x8e fp=0xc0000748d0 sp=0xc000074848 pc=0x4f288e
fmt.(*fmt).fmts(0xc00009f2f0, 0x1236820, 0x1b4dc80)
        /usr/lib/go-1.15/src/fmt/format.go:359 +0x65 fp=0xc000074908 sp=0xc0000748d0 pc=0x4f37c5
fmt.(*pp).fmtstring(0xc00009f2b0, 0x1236820, 0x1b4dc80, 0x73)
        /usr/lib/go-1.15/src/fmt/print.go:450 +0x1ba fp=0xc000074958 sp=0xc000074908 pc=0x4f6dfa
fmt.(*pp).printarg(0xc00009f2b0, 0x10a2320, 0xc0004c8cf0, 0x73)
        /usr/lib/go-1.15/src/fmt/print.go:698 +0x7e7 fp=0xc0000749f0 sp=0xc000074958 pc=0x4f9147
fmt.(*pp).doprintf(0xc00009f2b0, 0x129f741, 0x5, 0xc000074bb8, 0x2, 0x2)
        /usr/lib/go-1.15/src/fmt/print.go:1030 +0x168 fp=0xc000074ad8 sp=0xc0000749f0 pc=0x4fc208
fmt.sprintf(0x129f741, 0x5, 0xc000074bb8, 0x2, 0x2, 0xe300000001b7f5f0, 0x1b4f180)
        /usr/lib/go-1.15/src/fmt/print.go:219 +0x66 fp=0xc000074b30 sp=0xc000074ad8 pc=0x4f54a6
github.com/grantstreetgroup/go-exasol-client.(*conn).wsconnect(0xc0004a1680)
        /user/go/pkg/mod/github.com/grantstreetgroup/[email protected]/websocket.go:33 +0xea fp=0xc000074c78 sp=0xc000074b30 pc=0x7a7daa
github.com/grantstreetgroup/go-exasol-client.connect(0x1236820, 0x1b4dc80, 0xc00063fe10, 0x129ebb5, 0x3, 0x12a1065, 0x6, 0x0, 0x0, 0x0, ...)
        /user/go/pkg/mod/github.com/grantstreetgroup/[email protected]/client.go:84 +0x113 fp=0xc000074cb0 sp=0xc000074c78 pc=0x7a2253
github.com/abergmeier/terraform-provider-exasol/internal/exaprovider.newconnect(0x1236820, 0x1b4dc80, 0xc00063fe10, 0x129ebb5, 0x3, 0x12a1065, 0x6, 0x0, 0x0, 0x0, ...)
        /user/projects/terraform-provider-exasol/internal/exaprovider/client.go:28 +0x45 fp=0xc000074d30 sp=0xc000074cb0 pc=0x7aa005
github.com/abergmeier/terraform-provider-exasol/internal/exaprovider.(*client).lock(...)
        /user/projects/terraform-provider-exasol/internal/exaprovider/client.go:35
github.com/abergmeier/terraform-provider-exasol/internal/resources/role_test_test.testaccexasolrole_import(0xc0003f9800)
        /user/projects/terraform-provider-exasol/internal/resources/role_test/role_acc_test.go:61 +0x178 fp=0xc000074f80 sp=0xc000074d30 pc=0xfeb0f8
testing.trunner(0xc0003f9800, 0x12ee108)
        /usr/lib/go-1.15/src/testing/testing.go:1127 +0xef fp=0xc000074fd0 sp=0xc000074f80 pc=0x529f8f
runtime.goexit()
        /usr/lib/go-1.15/src/runtime/asm_amd64.s:1374 +0x1 fp=0xc000074fd8 sp=0xc000074fd0 pc=0x471e61
created by testing.(*t).run
        /usr/lib/go-1.15/src/testing/testing.go:1178 +0x386

goroutine 1 [chan receive]:
testing.(*t).run(0xc0003f9800, 0x12b54a8, 0x18, 0x12ee108, 0x49b701)
        /usr/lib/go-1.15/src/testing/testing.go:1179 +0x3ad
testing.runtests.func1(0xc0003f9380)
        /usr/lib/go-1.15/src/testing/testing.go:1449 +0x78
testing.trunner(0xc0003f9380, 0xc00063fc00)
        /usr/lib/go-1.15/src/testing/testing.go:1127 +0xef
testing.runtests(0xc0004c4940, 0x1b37060, 0x2, 0x2, 0xbfdb48dc53e2df3f, 0x8bb3466227, 0x1b4df40, 0x40f948)
        /usr/lib/go-1.15/src/testing/testing.go:1447 +0x2e8
testing.(*m).run(0xc00019ad00, 0x0)
        /usr/lib/go-1.15/src/testing/testing.go:1357 +0x245
github.com/abergmeier/terraform-provider-exasol/internal/resources/role_test_test.testrun(0xc00019ad00, 0x0)
        /user/projects/terraform-provider-exasol/internal/resources/role_test/main_test.go:28 +0x136
github.com/abergmeier/terraform-provider-exasol/internal/resources/role_test_test.testmain(0xc00019ad00)
        /user/projects/terraform-provider-exasol/internal/resources/role_test/main_test.go:20 +0x85
main.main()
        _testmain.go:47 +0x165

goroutine 6 [select]:
go.opencensus.io/stats/view.(*worker).start(0xc00019a700)
        /user/go/pkg/mod/[email protected]/stats/view/worker.go:276 +0x105
created by go.opencensus.io/stats/view.init.0
        /user/go/pkg/mod/[email protected]/stats/view/worker.go:34 +0x68

goroutine 14 [chan receive]:
testing.(*t).parallel(0xc0003f9500)
        /usr/lib/go-1.15/src/testing/testing.go:1003 +0x20b
github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource.paralleltest(0x147e120, 0xc0003f9500, 0x0, 0x0, 0x0, 0xc0004d4f30, 0x0, 0x0, 0x0, 0xc0003f9680, ...)
        /user/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/[email protected]/helper/resource/testing.go:482 +0x63
github.com/abergmeier/terraform-provider-exasol/internal/resources/role_test_test.testaccexasolrole_rename(0xc0003f9500)
        /user/projects/terraform-provider-exasol/internal/resources/role_test/role_acc_test.go:26 +0x878
testing.trunner(0xc0003f9500, 0x12ee110)
        /usr/lib/go-1.15/src/testing/testing.go:1127 +0xef
created by testing.(*t).run
        /usr/lib/go-1.15/src/testing/testing.go:1178 +0x386

堆栈跟踪总是相似的。

我调查了 /user/go/pkg/mod/github.com/grantstreetgroup/[email protected]/websocket.go:33,我非常怀疑它实际上是罪魁祸首(sprintf 和活动对象似乎是无辜的够了)。

我尝试使用 valgrind --error-limit=no --track-origins=yes 运行,但似乎没有确凿证据。特别是因为输出中没有任何地方提到 0x2d84420

我尝试通过 dlv 运行,但现在似乎有附加到递归启动测试的方法。

到目前为止,我有点不知所措,希望能够采取任何具体步骤来确定错误地址的来源。

如果有人能够弄清楚 0x2d84420 应该是逻辑 (go) 地址还是物理 (linux) 地址,那就加分了。

go版本的输出是:

go version go1.15.2 linux/amd64

编辑1:

因此我重写了第三方模块的函数以不使用 sprintf,现​​在它声称失败:

Host:   host + ":" + port,

hostport 都是 string 类型。 所以目前我认为 stacktrace 是假的。也许是由于缺少调试符号?

编辑2:

现在我不知何故认为我可能会触发某种未定义的行为。似乎 port 以前有时会损坏。我尝试测试 port 的(损坏的)值 65040 ,它似乎在 testmain 之后很快就损坏了。我删除了一些非必要的代码,现在损坏的值为 65056


解决方案


所以我改变了 testmain

var (
    exaclient *exaprovider.client
    exaconf   exasol.connconf
)

func testmain(m *testing.m) {
    flag.parse()
    os.exit(testrun(m))
}

func testrun(m *testing.m) int {
    exaconf = internal.mustcreatetestconf()
    exaclient = exaprovider.newclient(exaconf)

    return m.run()
}

var (
    exaClient *exaprovider.Client
    exaConf   exasol.ConnConf
)

func init() {
    exaConf = internal.MustCreateTestConf()
}

func TestMain(m *testing.M) {
    flag.Parse()
    os.Exit(testRun(m))
}

func testRun(m *testing.M) int {
    exaClient = exaprovider.NewClient(exaConf)

    return m.Run()
}

所有的腐败似乎都消失了。这是官方的 - 我不再理解 golang 了。

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《Go测试中发生的意外错误调试》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>