mirror of
https://github.com/golang/go
synced 2024-11-19 13:24:42 -07:00
runtime: fix off-by-one error finding module for PC
Also fix compiler-invoked panics to avoid a confusing "malloc deadlock" crash if they are invoked while executing the runtime. Fixes #14599. Change-Id: I89436abcbf3587901909abbdca1973301654a76e Reviewed-on: https://go-review.googlesource.com/20219 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
afd835434c
commit
1716162a9a
@ -201,3 +201,11 @@ func TestCgoPanicDeadlock(t *testing.T) {
|
||||
t.Fatalf("output does not start with %q:\n%s", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCgoCCodeSIGPROF(t *testing.T) {
|
||||
got := runTestProg(t, "testprogcgo", "CgoCCodeSIGPROF")
|
||||
want := "OK\n"
|
||||
if got != want {
|
||||
t.Errorf("expected %q got %v", want, got)
|
||||
}
|
||||
}
|
||||
|
@ -9,39 +9,56 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Calling panic with one of the errors below will call errorString.Error
|
||||
// which will call mallocgc to concatenate strings. That will fail if
|
||||
// malloc is locked, causing a confusing error message. Throw a better
|
||||
// error message instead.
|
||||
func panicCheckMalloc(err error) {
|
||||
gp := getg()
|
||||
if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
|
||||
throw(string(err.(errorString)))
|
||||
}
|
||||
}
|
||||
|
||||
var indexError = error(errorString("index out of range"))
|
||||
|
||||
func panicindex() {
|
||||
panicCheckMalloc(indexError)
|
||||
panic(indexError)
|
||||
}
|
||||
|
||||
var sliceError = error(errorString("slice bounds out of range"))
|
||||
|
||||
func panicslice() {
|
||||
panicCheckMalloc(sliceError)
|
||||
panic(sliceError)
|
||||
}
|
||||
|
||||
var divideError = error(errorString("integer divide by zero"))
|
||||
|
||||
func panicdivide() {
|
||||
panicCheckMalloc(divideError)
|
||||
panic(divideError)
|
||||
}
|
||||
|
||||
var overflowError = error(errorString("integer overflow"))
|
||||
|
||||
func panicoverflow() {
|
||||
panicCheckMalloc(overflowError)
|
||||
panic(overflowError)
|
||||
}
|
||||
|
||||
var floatError = error(errorString("floating point error"))
|
||||
|
||||
func panicfloat() {
|
||||
panicCheckMalloc(floatError)
|
||||
panic(floatError)
|
||||
}
|
||||
|
||||
var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
|
||||
|
||||
func panicmem() {
|
||||
panicCheckMalloc(memoryError)
|
||||
panic(memoryError)
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@ func (f *Func) FileLine(pc uintptr) (file string, line int) {
|
||||
|
||||
func findmoduledatap(pc uintptr) *moduledata {
|
||||
for datap := &firstmoduledata; datap != nil; datap = datap.next {
|
||||
if datap.minpc <= pc && pc <= datap.maxpc {
|
||||
if datap.minpc <= pc && pc < datap.maxpc {
|
||||
return datap
|
||||
}
|
||||
}
|
||||
|
48
src/runtime/testdata/testprogcgo/aprof.go
vendored
Normal file
48
src/runtime/testdata/testprogcgo/aprof.go
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
// Test that SIGPROF received in C code does not crash the process
|
||||
// looking for the C code's func pointer.
|
||||
|
||||
// The test fails when the function is the first C function.
|
||||
// The exported functions are the first C functions, so we use that.
|
||||
|
||||
// extern void GoNop();
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"runtime/pprof"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("CgoCCodeSIGPROF", CgoCCodeSIGPROF)
|
||||
}
|
||||
|
||||
//export GoNop
|
||||
func GoNop() {}
|
||||
|
||||
func CgoCCodeSIGPROF() {
|
||||
c := make(chan bool)
|
||||
go func() {
|
||||
for {
|
||||
<-c
|
||||
for i := 0; i < 1e7; i++ {
|
||||
C.GoNop()
|
||||
}
|
||||
c <- true
|
||||
}
|
||||
}()
|
||||
|
||||
var buf bytes.Buffer
|
||||
pprof.StartCPUProfile(&buf)
|
||||
c <- true
|
||||
<-c
|
||||
pprof.StopCPUProfile()
|
||||
|
||||
fmt.Println("OK")
|
||||
}
|
Loading…
Reference in New Issue
Block a user