pingcap / failpoint

An implementation of failpoints for Golang.
Apache License 2.0
817 stars 63 forks source link

failpoint doesn't work if the marker function is defined in the main package #33

Open spongedu opened 5 years ago

spongedu commented 5 years ago

Bug Report

Please answer these questions before submitting your issue. Thanks!

  1. What did you do? If possible, provide a recipe for reproducing the error.

For example, we have a file named main.go:

package main

import (

    "github.com/pingcap/failpoint"
)

func F1(name string) string {

    failpoint.Inject("failpoint-name", nil)

    return "hello " + name
}

func main() {
    failpoint.Enable("failpoint-name", "panic")
    F1("ttt")
}

After transfrom the code with failpoint-ctl enable, the generated binding__failpoint_binding__.go looks like this:

package main

import "reflect"

type __failpointBindingType struct {pkgpath string}
var __failpointBindingCache = &__failpointBindingType{}

func init() {
    __failpointBindingCache.pkgpath = reflect.TypeOf(__failpointBindingType{}).PkgPath()
}
func _curpkg_(name string) string {
    return  __failpointBindingCache.pkgpath + "/" + name
}

You may notice that binding__failpoint_binding__.go is also in package main, that means binding__failpoint_binding__.go could not be found by main.go.

Run go run main.go then, you will find the following error:

 ./main.go:8:17: undefined: _curpkg_
  1. What did you expect to see?

program panics due to failpoint

  1. What did you see instead?

    ./main.go:8:17: undefined: _curpkg_
  2. Versions of the failpoint

$ ./bin/failpoint-ctl -V ReleaseVersion bf45ab2 BuildTS 2019-05-15 09:48:44 GitHash bf45ab20bfc48d624b61944a4820768c16d7db99 GitBranch master GoVersion go version go1.12 darwin/amd64

spongedu commented 5 years ago

In production environment it's unlikely for the failpoint users to define a marker function in package main, But I think people incline to use such a simple test program to try failpint at first glimpse as I have done.

spongedu commented 5 years ago

@lonng as we've discussed yesterday.

lonng commented 5 years ago

There is an imperfect solution here. go run main.go binding__failpoint_binding__.go

spongedu commented 5 years ago

@lonng Yes.... if we want to solve this thoroughly, maybe there's one method, but I'm not sure if its graceful.

  1. generate binding__failpoint_binding__.go under package github.com/pingcap/failpoint as binding__failpoint_binding_UNIQ_IDENTITY__.go
  2. rewrite the Marker function as __curpkg_UNIQ_IDENTITY__()......
lonng commented 5 years ago

@spongedu I don't think put the generated files in github.com/pingcap/failpoint/ is a good idea. We should investigate a more graceful solution, How about putting the _curpkg_ to the end of the file?

spongedu commented 5 years ago

So what about the extra import:

import "reflect"

?

lonng commented 5 years ago

@spongedu Oops