1
0
mirror of https://github.com/golang/go synced 2024-11-17 01:54:53 -07:00
go/test
Russ Cox aa51c40b1c runtime: replace panic(nil) with panic(new(runtime.PanicNilError))
Long ago we decided that panic(nil) was too unlikely to bother
making a special case for purposes of recover. Unfortunately,
it has turned out not to be a special case. There are many examples
of code in the Go ecosystem where an author has written panic(nil)
because they want to panic and don't care about the panic value.

Using panic(nil) in this case has the unfortunate behavior of
making recover behave as though the goroutine isn't panicking.
As a result, code like:

	func f() {
		defer func() {
			if err := recover(); err != nil {
				log.Fatalf("panicked! %v", err)
			}
		}()
		call1()
		call2()
	}

looks like it guarantees that call2 has been run any time f returns,
but that turns out not to be strictly true. If call1 does panic(nil),
then f returns "successfully", having recovered the panic, but
without calling call2.

Instead you have to write something like:

	func f() {
		done := false
		defer func() {
			if err := recover(); !done {
				log.Fatalf("panicked! %v", err)
			}
		}()
		call1()
		call2()
		done = true
	}

which defeats nearly the whole point of recover. No one does this,
with the result that almost all uses of recover are subtly broken.

One specific broken use along these lines is in net/http, which
recovers from panics in handlers and sends back an HTTP error.
Users discovered in the early days of Go that panic(nil) was a
convenient way to jump out of a handler up to the serving loop
without sending back an HTTP error. This was a bug, not a feature.
Go 1.8 added panic(http.ErrAbortHandler) as a better way to access the feature.
Any lingering code that uses panic(nil) to abort an HTTP handler
without a failure message should be changed to use http.ErrAbortHandler.

Programs that need the old, unintended behavior from net/http
or other packages can set GODEBUG=panicnil=1 to stop the run-time error.

Uses of recover that want to detect panic(nil) in new programs
can check for recover returning a value of type *runtime.PanicNilError.

Because the new GODEBUG is used inside the runtime, we can't
import internal/godebug, so there is some new machinery to
cross-connect those in this CL, to allow a mutable GODEBUG setting.
That won't be necessary if we add any other mutable GODEBUG settings
in the future. The CL also corrects the handling of defaulted GODEBUG
values in the runtime, for #56986.

Fixes #25448.

Change-Id: I2b39c7e83e4f7aa308777dabf2edae54773e03f5
Reviewed-on: https://go-review.googlesource.com/c/go/+/461956
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
2023-01-19 22:21:50 +00:00
..
abi
alias3.dir
asmhdr.dir
bench test/bench/go1: eliminate start-up time 2022-11-01 17:07:14 +00:00
chan
closure3.dir test: relax closure name matching in closure3.go 2022-10-01 01:52:16 +00:00
closure5.dir
codegen cmd/compile: turn off jump tables when spectre retpolines are on 2022-12-06 05:12:12 +00:00
ddd2.dir
dwarf
fixedbugs runtime: replace panic(nil) with panic(new(runtime.PanicNilError)) 2023-01-19 22:21:50 +00:00
import2.dir
import4.dir
interface
intrinsic.dir runtime: replace all uses of CtzXX with TrailingZerosXX 2022-10-18 18:06:27 +00:00
ken
linkname.dir
method4.dir
retjmp.dir
runtime
stress
syntax
typeparam all: fix typos in go file comments 2023-01-09 15:34:31 +00:00
uintptrescapes.dir
64bit.go
235.go
alg.go
alias1.go
alias2.go
alias3.go
alias.go
align.go
append1.go
append.go
args.go
armimm.go
asmhdr.go
assign1.go
assign.go
atomicload.go
bigalg.go
bigmap.go
blank1.go
blank.go
bom.go
bombad.go
bounds.go
cannotassign.go
chancap.go
chanlinear.go
char_lit1.go
char_lit.go
checkbce.go
clearfat.go
closedchan.go
closure1.go
closure2.go
closure3.go
closure4.go
closure5.go
closure6.go
closure7.go
closure.go
cmp6.go
cmp.go
cmplx.go
cmplxdivide1.go
cmplxdivide.c
cmplxdivide.go
complit1.go
complit.go
compos.go
const1.go
const2.go
const3.go
const4.go
const5.go
const6.go
const7.go
const8.go
const.go
convert1.go
convert2.go
convert3.go
convert4.go
convert.go
convinline.go cmd/compile: handle integer conversions in static init inliner 2022-11-17 13:46:05 +00:00
convlit1.go
convlit.go
convT2X.go
copy1.go
copy.go
crlf.go
ddd1.go
ddd2.go
ddd.go
decl.go
declbad.go
defer.go
defererrcheck.go
deferfin.go
defernil.go
deferprint.go
deferprint.out
devirt.go
directive2.go
directive.go
divide.go
divmod.go
embedfunc.go
embedvers.go
empty.go
env.go
eof1.go
eof.go
escape2.go
escape2n.go
escape3.go
escape4.go test: skip inlining check in escape4.go 2022-10-01 01:52:17 +00:00
escape5.go
escape_array.go
escape_calls.go
escape_closure.go
escape_field.go
escape_goto.go
escape_hash_maphash.go
escape_iface_nounified.go
escape_iface_unified.go
escape_iface.go
escape_indir.go
escape_level.go
escape_map.go
escape_param.go
escape_runtime_atomic.go
escape_selfassign.go
escape_slice.go
escape_struct_param1.go
escape_struct_param2.go
escape_struct_return.go
escape_sync_atomic.go
escape_unsafe.go
escape.go
fibo.go
finprofiled.go
float_lit2.go
float_lit3.go
float_lit.go
floatcmp.go
for.go
func1.go
func2.go
func3.go
func4.go
func5.go
func6.go
func7.go
func8.go
func.go
funcdup2.go
funcdup.go
fuse.go
gc1.go
gc2.go
gc.go
gcgort.go
gcstring.go
goprint.go
goprint.out
goto.go
heapsampling.go
helloworld.go
helloworld.out
if.go
import1.go
import2.go
import4.go
import5.go
import6.go
import.go
index0.go
index1.go
index2.go
index.go
indirect1.go
indirect.go
init1.go
init.go
initcomma.go
initexp.go
initialize.go cmd/compile: handle simple inlined calls in staticinit 2022-11-16 04:04:52 +00:00
initializerr.go
initloop.go
inline_big.go
inline_caller.go
inline_callers.go
inline_endian.go
inline_literal.go
inline_math_bits_rotate.go
inline_nounified.go
inline_sync.go
inline_unified.go
inline_variadic.go
inline.go cmd/compile: reenable inlstaticinit 2022-11-23 21:54:55 +00:00
int_lit.go
intcvt.go
intrinsic_atomic.go
intrinsic.go
iota.go
label1.go
label.go
linkmain_run.go test: update test/run.go and some tests to use importcfg 2022-10-12 23:16:41 +00:00
linkmain.go
linkname3.go
linkname.go
linkobj.go test: update test/run.go and some tests to use importcfg 2022-10-12 23:16:41 +00:00
linkx_run.go
linkx.go
literal2.go
literal.go
live1.go
live2.go
live_regabi.go
live_uintptrkeepalive.go
live.go
loopbce.go
mainsig.go
makechan.go
makemap.go
makenew.go
makeslice.go
mallocfin.go
map1.go
map.go
mapclear.go
maplinear.go
maymorestack.go
mergemul.go
method1.go
method2.go
method3.go
method4.go
method5.go
method6.go
method7.go
method.go
named1.go
named.go
nil.go
nilcheck.go
nilptr2.go
nilptr3.go
nilptr4.go
nilptr5_aix.go
nilptr5_wasm.go
nilptr5.go
nilptr_aix.go
nilptr.go
noinit.go cmd/compile: reenable inlstaticinit 2022-11-23 21:54:55 +00:00
nosplit.go
nowritebarrier.go
nul1.go
opt_branchlikely.go
parentype.go
peano.go
phiopt.go
print.go
print.out
printbig.go
printbig.out
prove_constant_folding.go
prove.go cmd/compile: recognize when the result of append has a constant length 2022-10-27 17:09:50 +00:00
range.go
README.md
recover1.go
recover2.go
recover3.go
recover4.go
recover5.go
recover.go
reflectmethod1.go
reflectmethod2.go
reflectmethod3.go
reflectmethod4.go
reflectmethod5.go
reflectmethod6.go
reflectmethod7.go
reflectmethod8.go
rename1.go
rename.go
reorder2.go
reorder.go
retjmp.go
return.go
rotate0.go
rotate1.go
rotate2.go
rotate3.go
rotate.go
run.go test: remove optimizationOff 2022-11-17 16:06:03 +00:00
rune.go
runtime.go
shift1.go
shift2.go
shift3.go
sieve.go
sigchld.go
sigchld.out
simassign.go
sizeof.go
slice3.go
slice3err.go
slicecap.go
sliceopt.go
solitaire.go
stack.go
stackobj2.go
stackobj3.go
stackobj.go
strcopy.go
strength.go
string_lit.go
stringrange.go
struct0.go
switch2.go
switch3.go
switch4.go
switch5.go
switch6.go
switch7.go
switch.go
tinyfin.go
torture.go
turing.go
typecheck.go
typecheckloop.go
typeswitch1.go
typeswitch2.go
typeswitch2b.go
typeswitch3.go
typeswitch.go
uintptrescapes2.go
uintptrescapes3.go
uintptrescapes.go
uintptrkeepalive.go
undef.go
unsafe_slice_data.go
unsafe_string_data.go
unsafe_string.go
unsafebuiltins.go
used.go
utf.go
varerr.go
varinit.go
winbatch.go
writebarrier.go
zerodivide.go

The test directory contains tests of the Go tool chain and runtime. It includes black box tests, regression tests, and error output tests. They are run as part of all.bash.

To run just these tests, execute:

../bin/go run run.go

To run just tests from specified files in this directory, execute:

../bin/go run run.go -- file1.go file2.go ...

Standard library tests should be written as regular Go tests in the appropriate package.

The tool chain and runtime also have regular Go tests in their packages. The main reasons to add a new test to this directory are:

  • it is most naturally expressed using the test runner; or
  • it is also applicable to gccgo and other Go tool chains.