-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.help wanted
Milestone
Description
What version of Go are you using (go version
)?
go1.10.2 darwin/amd64
Does this issue reproduce with the latest release?
Tested on go1.10.3 darwin/amd64
as well.
What operating system and processor architecture are you using (go env
)?
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/jake.waksbaum/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/jake.waksbaum/go-src"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.10.3/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.10.3/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/q_/d4dp83cn1jb1t9yrx5x46mhr0000gn/T/go-build472845777=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
Must have a PostgreSQL server setup locally with a database called test_bug
.
package main
import (
"database/sql"
"database/sql/driver"
"fmt"
"os"
_ "github.com/lib/pq"
)
var _ driver.Valuer = customData{}
type customData struct{}
func (customData) Value() (driver.Value, error) {
panic("oh no!")
}
func main() {
db, err := sql.Open("postgres", "dbname=test_bug sslmode=disable")
if err != nil {
fmt.Printf("opening database: %v\n", err)
os.Exit(1)
}
defer db.Close()
tx, err := db.Begin()
if err != nil {
fmt.Printf("beginning transaction: %v\n", err)
os.Exit(1)
}
defer tx.Rollback()
var flag bool
err = tx.QueryRow("SELECT TRUE WHERE $1", customData{}).Scan(&flag)
if err != nil {
fmt.Printf("executing query: %v\n", err)
os.Exit(1)
}
fmt.Printf("we got a %v\n", flag)
os.Exit(0)
}
What did you expect to see?
Some sort of indication of a panic, followed by the program exiting.
What did you see instead?
Nothing. The program hangs with no output.
What I think is the problem
In sql.go
in ExecContext
, releaseConn
is not deferred so when a panic happens in a Valuer.Value
call deep within resultFromStatement
, there is some lock being held on to. Then, when Tx.Rollback
is called because it has been deferred, it hangs, stopping the unrolling of the stack and preventing any output from being shown or the process from exiting cleanly. I think we should change lines 2316-2320 to something like
res, err = func() (res Result, err error) {
defer func() {
p := recover()
if p != nil {
releaseConn(fmt.Errorf("panic: %v", p))
panic(p)
}
releaseConn(err)
}()
return resultFromStatement(ctx, dc.ci, ds, args...)
}()
if err != driver.ErrBadConn {
return res, err
}
gburt
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.help wanted