n2coke
n2coke

Reputation: 41

an error only occur when observing in lib/pq

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

Answers (1)

n2coke
n2coke

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

Related Questions