]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: delete panicstring; move its checks into gopanic
authorRuss Cox <rsc@golang.org>
Thu, 18 Sep 2014 18:49:24 +0000 (14:49 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 18 Sep 2014 18:49:24 +0000 (14:49 -0400)
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

src/runtime/error.go
src/runtime/malloc.c
src/runtime/panic.go
src/runtime/proc.c
src/runtime/runtime.h

index 3ea93680ce971f809e078918f412db946abefc6b..0b40c702b029aeb0fc27e8306eb8fc0d4eb35252 100644 (file)
@@ -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
 }
index d5f2b9ab80b91d1ef53cdd97bbd07171daa88a10..60d20a992deeb4e6ea515f4fdea46cc92101fd2f 100644 (file)
@@ -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);
 }
 
index 927b6db44bc3ff32bf378b360813daa0bba93f69..3cc31053e8413cc19ab5c6258101fc09a6a2c195 100644 (file)
@@ -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)
-}
index 4282a145e11018253cf1f194e1e5fd8f4736f6ad..860701ee583b27e92004b618630dccb055864060 100644 (file)
@@ -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();
index c034f3aa9770957f81623640c6dceed397aa9a2c..386b09b96bc70f1e466ee1906dce97243bb2fdec 100644 (file)
@@ -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*);