google / wire

Compile-time Dependency Injection for Go
Apache License 2.0
12.83k stars 614 forks source link

panic in related to Bind with a pointer #201

Open gracenoah opened 5 years ago

gracenoah commented 5 years ago

Describe the bug

Panic when running wire ./...

To Reproduce

Sorry, I can't give a specific repro because

  1. I worked around it as soon as I ran into it
  2. There's a lot of proprietary code involved and it would have been pretty hard to isolate

The error was related to a bind statement:

    wire.Bind(new(Interface), new(*Concrete)),

I don't know what was unusual about this bind statement. There was New function that returns a pointer to Concrete and Concrete implements Interface. In 0.2.2, I was able to use new(Concrete), but I had to change that to new(Concrete) after upgrading to 0.3.0 and that's when the panic happened.

I hope that the following stack trace helps. If not, we might want to wait for someone to run into this again and provide a repro.

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x64488d]

goroutine 1 [running]:
go/types.(*Package).Path(...)
        /home/<user>/.go/src/go/types/package.go:30
github.com/google/wire/internal/wire.(*objectCache).get(0xc03b480880, 0x76bb60, 0xc00008cc30, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:464 +0x7d
github.com/google/wire/internal/wire.(*objectCache).processExpr(0xc03b480880, 0xc03a9324b0, 0xc000cfdce0, 0x5b, 0x766e60, 0xc03a9394c0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:523 +0xfd3
github.com/google/wire/internal/wire.(*objectCache).processNewSet(0xc03b480880, 0xc03a9324b0, 0xc000cfdce0, 0x5b, 0xc03a9c1980, 0x0, 0xc03a905620, 0xf, 0xc000656ec0, 0x58632c, ...)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:592 +0x18a
github.com/google/wire/internal/wire.(*objectCache).processExpr(0xc03b480880, 0xc03a9324b0, 0xc000cfdce0, 0x5b, 0x766a60, 0xc03a9c1980, 0xc03a905620, 0xf, 0xf, 0xc000026500, ...)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:535 +0x519
github.com/google/wire/internal/wire.(*objectCache).get(0xc03b480880, 0x76bd40, 0xc03a9331d0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:489 +0x42e
github.com/google/wire/internal/wire.(*objectCache).processExpr(0xc03b480880, 0xc03b4684b0, 0xc0003737a0, 0x51, 0x7671a0, 0xc03b441b60, 0x0, 0x0, 0x68c340, 0xc03b4e1320, ...)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:523 +0xfd3
github.com/google/wire/internal/wire.(*objectCache).processNewSet(0xc03b480880, 0xc03b4684b0, 0xc0003737a0, 0x51, 0xc03b466e40, 0x0, 0xc03b4432a0, 0x16, 0xc0006573e8, 0x58632c, ...)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:592 +0x18a
github.com/google/wire/internal/wire.(*objectCache).processExpr(0xc03b480880, 0xc03b4684b0, 0xc0003737a0, 0x51, 0x766a60, 0xc03b466e40, 0xc03b4432a0, 0x16, 0x16, 0xc000026500, ...)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:535 +0x519
github.com/google/wire/internal/wire.(*objectCache).get(0xc03b480880, 0x76bd40, 0xc03b468550, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:489 +0x42e
github.com/google/wire/internal/wire.(*objectCache).processExpr(0xc03b480880, 0xc03b468e10, 0xc0002f6eb0, 0x49, 0x7671a0, 0xc03b4770a0, 0x0, 0x0, 0x6b2cc0, 0xc039982600, ...)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:523 +0xfd3
github.com/google/wire/internal/wire.(*objectCache).processNewSet(0xc03b480880, 0xc03b468e10, 0xc0002f6eb0, 0x49, 0xc03b467680, 0xc03b4808e0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:592 +0x18a
github.com/google/wire/internal/wire.generateInjectors(0xc03b469f90, 0xc000da5770, 0x2, 0xc0393f10a0, 0x69, 0x0, 0x0, 0xc00000c0b0)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/wire.go:176 +0xaaf
github.com/google/wire/internal/wire.Generate(0x767ca0, 0xc0000120d8, 0xc000020004, 0x40, 0xc000010c00, 0x59, 0x59, 0xc00000c0b0, 0x1, 0x1, ...)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/wire.go:99 +0x412
main.(*genCmd).Execute(0xc000047eb0, 0x767ca0, 0xc0000120d8, 0xc00005a180, 0x0, 0x0, 0x0, 0x7f97cf1e8008)
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/cmd/wire/main.go:131 +0x249
main.main()
        /home/<user>/go/pkg/mod/github.com/google/wire@v0.3.0/cmd/wire/main.go:71 +0x4a1
exit status 2

Expected behavior

No panic

Version

0.3.0

Additional context

Sorry, too much proprietary code. Hope there's something obvious that recently changed and the stack trace helps.

vangent commented 5 years ago

@shantuo can you take a look? Maybe add a new testcase with this?

shantuo commented 5 years ago

Hi @gracenoah , is your Interface a Go built-in type?

gracenoah commented 5 years ago

In this example Interface is an interface with some methods. I really don't know what's special about it because the panic happens in this one scenario, but I've used wire.Bind elsewhere without it panicking. Sorry that I can't be more helpful.

shantuo commented 5 years ago

No worries, from what I can tell in the stack trace you provided, I don't think this is a bug in Bind, but maybe in NewSet, as the panic happens while it is processing the out layer NewSet function. Also, the panic happens when it is trying to get the import path of one of the providers in your argument list you are passing into NewSet by calling "go/types".Object.Pkg().Path(), the Pkg() call returns nil "for labels and objects in the Universe scope", which means you might have some argument in the same NewSet call that is a built-in type, or a wrapper of one, maybe?

gracenoah commented 5 years ago

I think you might be right. I tried to reproduce the issue again by adding back the Bind an changing the constructor to return the struct type and I couldn't. Since, this is all the information we have, I'd be happy with a fix that just adds a better error message whenever this edge case is triggered. Hopefully if it happens again, the error will help me understand the source of the issue.

anton-dessiatov commented 5 years ago

It happened to me when I forgot a wire.Struct call. I have defined a provider like this:

wire.Build(new(CreateServiceWithMocks), "*")

instead of

wire.Build(wire.Struct(new(CreateServiceWithMocks), "*"))
gracenoah commented 4 years ago

Just got a very similar looking panic. This is the exact repro:

package main

import "github.com/google/wire"

type A struct {
    B string
}

func makeA(string) A {
    panic(wire.Build(wire.Struct(new(*A), "*")))
}
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x57f376]

goroutine 1 [running]:
go/types.writeType(0xc0024a15f0, 0x776540, 0x0, 0x0, 0xc0002353a8, 0x1, 0x8)
        /home/gracenoah/.go/src/go/types/typestring.go:120 +0x6a6
go/types.WriteType(...)
        /home/gracenoah/.go/src/go/types/typestring.go:75
go/types.TypeString(0x776540, 0x0, 0x0, 0xc0001ccb40, 0x25)
        /home/gracenoah/.go/src/go/types/typestring.go:67 +0xb1
github.com/google/wire/internal/wire.processStructProvider(0xc0000ea280, 0xc002486aa0, 0xc00247d100, 0x6, 0x1, 0x75)
        /home/gracenoah/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:806 +0xb11
github.com/google/wire/internal/wire.(*objectCache).processExpr(0xc0021b3880, 0xc002486aa0, 0xc0001d6450, 0x5, 0x778ec0, 0xc00247d100, 0x0, 0x0, 0x20, 0x6d88a0, ...)
        /home/gracenoah/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:556 +0xb6e
github.com/google/wire/internal/wire.(*objectCache).processNewSet(0xc0021b3880, 0xc002486aa0, 0xc0001d6450, 0x5, 0xc00247d140, 0xc0021b38c0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/gracenoah/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/parse.go:592 +0x18c
github.com/google/wire/internal/wire.generateInjectors(0xc002486f50, 0xc0001dcd20, 0x2, 0xc00113f590, 0x29, 0x0, 0x0, 0xc0000ac010)
        /home/gracenoah/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/wire.go:176 +0x9f4
github.com/google/wire/internal/wire.Generate(0x77a080, 0xc00008e000, 0xc000016064, 0x1d, 0xc000102000, 0x60, 0x60, 0xc0000ac010, 0x1, 0x1, ...)
        /home/gracenoah/go/pkg/mod/github.com/google/wire@v0.3.0/internal/wire/wire.go:99 +0x411
main.(*genCmd).Execute(0xc000077e78, 0x77a080, 0xc00008e000, 0xc0000a4120, 0x0, 0x0, 0x0, 0x30)
        /home/gracenoah/go/pkg/mod/github.com/google/wire@v0.3.0/cmd/wire/main.go:131 +0x247
main.main()
        /home/gracenoah/go/pkg/mod/github.com/google/wire@v0.3.0/cmd/wire/main.go:71 +0x4dc
exit status 2
zombiezen commented 4 years ago

@gracenoah, thanks for the minimal repro! I'll try to take a look in the next week or so.

zombiezen commented 4 years ago

@gracenoah and @anton-dessiatov, it seems like that Struct issue is unrelated to @gracenoah's original issue with Bind. I wasn't able to find anything more on that particular failure, but I have a fix ready for the other issue. I've opened #219 to track the Struct issue.

gracenoah commented 4 years ago

Thanks for investigating and making a separate issue.