mirror of
https://github.com/golang/go
synced 2024-11-23 07:50:05 -07:00
runtime: delete panicstring; move its checks into gopanic
In Go 1.3 the runtime called panicstring to report errors like divide by zero or memory faults. Now we call panic (gopanic) with pre-allocated error values. That new path is missing the checking that panicstring did, so add it there. The only call to panicstring left is in cnew, which is problematic because if it fails, probably the heap is corrupt. In that case, calling panicstring creates a new errorCString (no allocation there), but then panic tries to print it, invoking errorCString.Error, which does a string concatenation (allocating), which then dies. Replace that one panicstring with a throw: cnew is for allocating runtime data structures and should never ask for an inappropriate amount of memory. With panicstring gone, delete newErrorCString, errorCString. While we're here, delete newErrorString, not called by anyone. (It can't be: that would be C code calling Go code that might block or grow the stack.) Found while debugging a malloc corruption. This resulted in 'panic during panic' instead of a more useful message. LGTM=khr R=khr CC=golang-codereviews https://golang.org/cl/138290045
This commit is contained in:
parent
98a5f52ef0
commit
c3b5db895b
@ -71,28 +71,6 @@ func (e errorString) Error() string {
|
||||
return "runtime error: " + string(e)
|
||||
}
|
||||
|
||||
// For calling from C.
|
||||
func newErrorString(s string, ret *interface{}) {
|
||||
*ret = errorString(s)
|
||||
}
|
||||
|
||||
// An errorCString represents a runtime error described by a single C string.
|
||||
// Not "type errorCString unsafe.Pointer" because of http://golang.org/issue/7084.
|
||||
// Not uintptr because we want to avoid an allocation if interfaces can't hold
|
||||
// uintptrs directly (and cstr _is_ a pointer).
|
||||
type errorCString struct{ cstr unsafe.Pointer }
|
||||
|
||||
func (e errorCString) RuntimeError() {}
|
||||
|
||||
func (e errorCString) Error() string {
|
||||
return "runtime error: " + gostringnocopy((*byte)(e.cstr))
|
||||
}
|
||||
|
||||
// For calling from C.
|
||||
func newErrorCString(s unsafe.Pointer, ret *interface{}) {
|
||||
*ret = errorCString{s}
|
||||
}
|
||||
|
||||
type stringer interface {
|
||||
String() string
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ static void*
|
||||
cnew(Type *typ, intgo n)
|
||||
{
|
||||
if(n < 0 || (typ->size > 0 && n > MaxMem/typ->size))
|
||||
runtime·panicstring("runtime: allocation size out of range");
|
||||
runtime·throw("runtime: allocation size out of range");
|
||||
return runtime·mallocgc(typ->size*n, typ, typ->kind&KindNoPointers ? FlagNoScan : 0);
|
||||
}
|
||||
|
||||
|
@ -281,6 +281,35 @@ func gopanic(e interface{}) {
|
||||
if gp.m.curg != gp {
|
||||
gothrow("panic on m stack")
|
||||
}
|
||||
|
||||
// m.softfloat is set during software floating point.
|
||||
// It increments m.locks to avoid preemption.
|
||||
// We moved the memory loads out, so there shouldn't be
|
||||
// any reason for it to panic anymore.
|
||||
if gp.m.softfloat != 0 {
|
||||
gp.m.locks--
|
||||
gp.m.softfloat = 0
|
||||
gothrow("panic during softfloat")
|
||||
}
|
||||
if gp.m.mallocing != 0 {
|
||||
print("panic: ")
|
||||
printany(e)
|
||||
print("\n")
|
||||
gothrow("panic during malloc")
|
||||
}
|
||||
if gp.m.gcing != 0 {
|
||||
print("panic: ")
|
||||
printany(e)
|
||||
print("\n")
|
||||
gothrow("panic during gc")
|
||||
}
|
||||
if gp.m.locks != 0 {
|
||||
print("panic: ")
|
||||
printany(e)
|
||||
print("\n")
|
||||
gothrow("panic holding locks")
|
||||
}
|
||||
|
||||
var p _panic
|
||||
p.arg = e
|
||||
p.link = gp._panic
|
||||
@ -431,33 +460,3 @@ func gothrow(s string) {
|
||||
dopanic(0)
|
||||
*(*int)(nil) = 0 // not reached
|
||||
}
|
||||
|
||||
func panicstring(s *int8) {
|
||||
// m.softfloat is set during software floating point,
|
||||
// which might cause a fault during a memory load.
|
||||
// It increments m.locks to avoid preemption.
|
||||
// If we're panicking, the software floating point frames
|
||||
// will be unwound, so decrement m.locks as they would.
|
||||
gp := getg()
|
||||
if gp.m.softfloat != 0 {
|
||||
gp.m.locks--
|
||||
gp.m.softfloat = 0
|
||||
}
|
||||
|
||||
if gp.m.mallocing != 0 {
|
||||
print("panic: ", s, "\n")
|
||||
gothrow("panic during malloc")
|
||||
}
|
||||
if gp.m.gcing != 0 {
|
||||
print("panic: ", s, "\n")
|
||||
gothrow("panic during gc")
|
||||
}
|
||||
if gp.m.locks != 0 {
|
||||
print("panic: ", s, "\n")
|
||||
gothrow("panic holding locks")
|
||||
}
|
||||
|
||||
var err interface{}
|
||||
newErrorCString(unsafe.Pointer(s), &err)
|
||||
gopanic(err)
|
||||
}
|
||||
|
@ -123,7 +123,6 @@ runtime·schedinit(void)
|
||||
{
|
||||
int32 n, procs;
|
||||
byte *p;
|
||||
Eface i;
|
||||
|
||||
// raceinit must be the first call to race detector.
|
||||
// In particular, it must be done before mallocinit below calls racemapshadow.
|
||||
@ -137,12 +136,6 @@ runtime·schedinit(void)
|
||||
runtime·mallocinit();
|
||||
mcommoninit(g->m);
|
||||
|
||||
// Initialize the itable value for newErrorCString,
|
||||
// so that the next time it gets called, possibly
|
||||
// in a fault during a garbage collection, it will not
|
||||
// need to allocated memory.
|
||||
runtime·newErrorCString(0, &i);
|
||||
|
||||
runtime·goargs();
|
||||
runtime·goenvs();
|
||||
runtime·parsedebugvars();
|
||||
|
@ -804,7 +804,6 @@ void runtime·goenvs(void);
|
||||
void runtime·goenvs_unix(void);
|
||||
void* runtime·getu(void);
|
||||
void runtime·throw(int8*);
|
||||
void runtime·panicstring(int8*);
|
||||
bool runtime·canpanic(G*);
|
||||
void runtime·prints(int8*);
|
||||
void runtime·printf(int8*, ...);
|
||||
@ -1063,8 +1062,6 @@ void runtime·panicdivide(void);
|
||||
*/
|
||||
void runtime·printany(Eface);
|
||||
void runtime·newTypeAssertionError(String*, String*, String*, String*, Eface*);
|
||||
void runtime·newErrorString(String, Eface*);
|
||||
void runtime·newErrorCString(int8*, Eface*);
|
||||
void runtime·fadd64c(uint64, uint64, uint64*);
|
||||
void runtime·fsub64c(uint64, uint64, uint64*);
|
||||
void runtime·fmul64c(uint64, uint64, uint64*);
|
||||
|
Loading…
Reference in New Issue
Block a user