Reputation: 41
I tried to debug a go server with gorm & pgsql, an it exitted with panic when gorm try to connect to the pgsql with code:
d, err := gorm.Open("postgres", param)
and as I followed the stack, I found it is the problem with lib/pq proccess the server version:
case "server_version":
var major1 int
var major2 int
var minor int
//r.string is the string of pgsql version.
//mine is: 12.4 (Debian 12.4-1.pgdg100+1)
_, err = fmt.Sscanf(r.string(), "%d.%d.%d", &major1, &major2, &minor)
if err == nil {
cn.parameterStatus.serverVersion = major1*10000 + major2*100 + minor
}
obivisouly, the string 12.4 (Debian 12.4-1.pgdg100+1)
dosen't match format %d.%d.%d
, so it exitted with error.
but the strange thing is, it will only exit when debugging in GoLand (don't know about vscode). It will not happen when simplely build & run, the output is:
[INFO] 2022-11-04 15:30:52 +0800 [start_postgres.go:103] detecting database connecting... pgdir=%v/yak/tmp_build/database
[INFO] 2022-11-04 15:30:52 +0800 [start_postgres.go:106] detected exsited database.
[INFO] 2022-11-04 15:30:52 +0800 [core.go:107] health info manager is loading
[INFO] 2022-11-04 15:30:52 +0800 [manager.go:70] health info: cache 60 infos
[INFO] 2022-11-04 15:30:52 +0800 [core.go:112] start to connection postgres
[INFO] 2022-11-04 15:30:52 +0800 [core.go:117] build basic database manager instance
which is absloutly normal. then I did some modify on the source code in lib/pq/conn.go
rString := r.string()
fmt.Printf("\n%s\n\n", rString)
_, err = fmt.Sscanf(r.string(), "%d.%d.%d", &major1, &major2, &minor)
if err == nil {
cn.parameterStatus.serverVersion = major1*10000 + major2*100 + minor
}
and here is the strangest thing, the server crashed with infinite loop of error logging:
[INFO] 2022-11-04 16:37:00 +0800 [start_postgres.go:103] detecting database connecting... pgdir=%v/yak/tmp_build/database
12.4 (Debian 12.4-1.pgdg100+1)
[WARN] 2022-11-04 16:37:00 +0800 [start_postgres.go:110] open database failed: pq: invalid message format; expected string terminator
[INFO] 2022-11-04 16:37:00 +0800 [start_postgres.go:113] try to start a database...
12.4 (Debian 12.4-1.pgdg100+1)
[WARN] 2022-11-04 16:37:02 +0800 [start_postgres.go:206] try pq: invalid message format; expected string terminator times... waiting for the postgres starting up...
12.4 (Debian 12.4-1.pgdg100+1)
[WARN] 2022-11-04 16:37:03 +0800 [start_postgres.go:206] try pq: invalid message format; expected string terminator times... waiting for the postgres starting up...
12.4 (Debian 12.4-1.pgdg100+1)
[WARN] 2022-11-04 16:37:04 +0800 [start_postgres.go:206] try pq: invalid message format; expected string terminator times... waiting for the postgres starting up...
...
I can't figure it out why would this happen, I don't think it's in a goroutine because the main routine is blocked, so is there anyone can offer some helps?
versions of dependencies and IDE:
GoLand v2022.2.4
go version go1.19.2 linux/amd64
gorm v1.9.2
github.com/lib/pq v1.1.0
postgresql v12.4 (Debian 12.4-1.pgdg100+1)
Upvotes: 2
Views: 172
Reputation: 41
I figured it out about the infinity loop of error, there's a select struct after the init connection, the code is:
select {
case <-ticker:
count++
conn, err := gorm.Open("postgres", param)
//conn, err := net.Dial("tcp", "127.0.0.1:5432")
if err != nil {
log.Warningf("try %v times... waiting for the postgres starting up...", err)
continue
}
_ = conn.Close()
return nil
}
so the problem is, when I print r.string()
, it will return an error.
also it will exitted with panic in debug (GoLand) but work normally when build and run.
Upvotes: 1