Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: Interface conversion error misreported in 1.7beta #16130

Closed
gtownsend opened this issue Jun 20, 2016 · 3 comments
Closed

runtime: Interface conversion error misreported in 1.7beta #16130

gtownsend opened this issue Jun 20, 2016 · 3 comments
Milestone

Comments

@gtownsend
Copy link

Please answer these questions before submitting your issue. Thanks!

  1. What version of Go are you using (go version)?
    go version go1.7beta2 darwin/amd64
  2. What operating system and processor architecture are you using (go env)?
    GOARCH="amd64"
    GOBIN=""
    GOEXE=""
    GOHOSTARCH="amd64"
    GOHOSTOS="darwin"
    GOOS="darwin"
    GOPATH="/Users/gmt/go"
    GORACE=""
    GOROOT="/usr/local/go"
    GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
    CC="clang"
    GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/75/4258h9pr8xj7dr0059bpx1400000gn/T/go-build875379403=/tmp/go-build -gno-record-gcc-switches -fno-common"
    CXX="clang++"
    CGO_ENABLED="1"
  3. What did you do? / 4. What did you expect to see? / 5. What did you see instead?

This is a followup to my golang-dev posting
https://groups.google.com/forum/#!topic/golang-dev/3ffx1UPftAA

Deep down in the Goaldi programming language interpreter,
one runtime interface assertion error has type and value
runtime.errorString [note: not a pointer]
runtime error: invalid memory address or nil pointer dereference
where in Go 1.6 it had type and value
*runtime.TypeAssertionError
interface conversion: *runtime.VNumber is not runtime.IVariable: missing method Assign

I was unable to reproduce this in a small example.
Here is, I hope, a working recipe for reproducing it in its original context.
It’s very possible that I’ve missed something — please don’t hesitate to e-mail
me with any questions (gmt@cs.arizona.edu).

Download or clone the latest Goaldi package from
github.com/proebsting/goaldi

Make the downloaded file tree the current directory.

Apply the patch below, which has the effect of showing the problem immediately
instead of passing it around and obscuring it.

Run “make boot” followed by “make build”.
(I’m assuming that "go" is in the command search path,
$GOPATH is set, and $GOPATH/bin is writable.)

Copy this code into a file “expt.gd”:

    procedure main() {
        1 := 2
    }

Run “./goaldi -c expt.gd” followed by “./goaldi -x expt.gir”.

(I broke that into two explicit steps because the usual “goaldi expt.gd” command
actually runs the interpreter twice, with an implicit exec in the middle.
That can be really confusing if you want to set breakpoints etc.;
it’s the second run that demonstrates the problem.)

Expect to see:
PANIC(runtime.errorString) IN OPERATE():runtime error: invalid memory address or nil pointer dereference
Correct result would be:
PANIC(*runtime.TypeAssertionError) IN OPERATE():interface conversion: *runtime.VNumber is not runtime.IVariable: missing method Assign


Install this patch for quick reporting of the panic:

diff --git a/interp/operator.go b/interp/operator.go
index 887683a..bc99541 100644
--- a/interp/operator.go
+++ b/interp/operator.go
@@ -3,6 +3,7 @@
 package main

 import (
+       "os"
        "fmt"
        "goaldi/ir"
        g "goaldi/runtime"
@@ -68,6 +69,13 @@ func getOperator(i *ir.Ir_OpFunction) *iOperator {
 //  operate() executes an iOperator insn corresponding to a Goaldi operator
 func operate(env *g.Env, f *pr_frame, i *iOperator) (g.Value, *g.Closure) {

+defer func() {
+if x := recover(); x != nil {
+       fmt.Printf("PANIC(%T) IN OPERATE():%v\n", x, x)
+       os.Exit(1)
+}
+}()
+
        // load and possibly dereference arguments
        var lval, arg0, arg1, arg2 g.Value
        arg0 = argval(f, i.Arg0, i.Flags&VAR0)
@quentinmit quentinmit added this to the Go1.7 milestone Jun 20, 2016
@quentinmit quentinmit changed the title Interface conversion error misreported in 1.7beta runtime: Interface conversion error misreported in 1.7beta Jun 20, 2016
@ianlancetaylor
Copy link
Contributor

Here is a standalone test case.

package main

import (
    "fmt"
    "runtime"
    "strings"
)

type I interface {
    Get() int
}

func main() {
    defer func() {
        r := recover()
        if r == nil {
            panic("expected panic")
        }
        re, ok := r.(runtime.Error)
        if !ok {
            panic(fmt.Sprintf("got %T, expected runtime.Error", r))
        }
        if !strings.Contains(re.Error(), "interface conversion") {
            panic(fmt.Sprintf("got %q, expected interface conversion error", re.Error()))
        }
    }()
    e := (interface{})(0)
    if _, ok := e.(I); ok {
        panic("unexpected interface conversion success")
    }
    fmt.Println(e.(I))
    panic("unexpected interface conversion success")
}

@ianlancetaylor
Copy link
Contributor

Almost certainly caused by https://golang.org/cl/20900 (CC @walken-google).

@ianlancetaylor ianlancetaylor self-assigned this Jun 20, 2016
@gopherbot
Copy link

CL https://golang.org/cl/24284 mentions this issue.

@golang golang locked and limited conversation to collaborators Jun 21, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants