guelfey / go.dbus

Native Go bindings for D-Bus
BSD 2-Clause "Simplified" License
124 stars 42 forks source link

Compound structs where substructs contain arrays causes nil pointer exception #55

Open rifflock opened 10 years ago

rifflock commented 10 years ago

I created several compound structures to return via the dbus.

type GetFileResponse struct {
    Response
    File
}
type Response struct {
    Status int32
    Message string
}
type File struct {
    Fileid int64
    Path string
    Name string
    HashSimple string
    HashSHA1 string
    HashMD5 string
    Filecreationdate int64
    Filemodificationdate int64
    Creationdate int64
    Modificationdate int64
    Size int64
    Isdir bool
    Deleted bool
    Metadata []byte
}

I created it this way for readability and it seemed like it should work based on the documentation, however I found an interesting bug. It seems that when dealing with a compound struct such as GetFileResponse, if a sub-struct has an array in it then go panics with the following stack trace:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x4e1703]

goroutine 11 [running]:
runtime.panic(0x6ad7e0, 0xa36553)
    /usr/lib/go/src/pkg/runtime/panic.c:278 +0xf8
reflect.(*gcProg).appendProg(0xc20805d480, 0x6a23c0)
    /usr/lib/go/src/pkg/reflect/type.go:1508 +0x183
reflect.funcLayout(0x6771c0, 0x6c4700, 0x63b440, 0x18, 0x18)
    /usr/lib/go/src/pkg/reflect/type.go:1787 +0x4d2
reflect.Value.call(0x6c4700, 0xc2080425a0, 0x0, 0xb38, 0x6d9220, 0x4, 0xc20805d460, 0x1, 0x1, 0x0, ...)
    /usr/lib/go/src/pkg/reflect/value.go:535 +0xee1
reflect.Value.Call(0x6c4700, 0xc2080425a0, 0x0, 0xb38, 0xc20805d460, 0x1, 0x1, 0x0, 0x0, 0x0)
    /usr/lib/go/src/pkg/reflect/value.go:411 +0xd7
github.com/guelfey/go%2edbus.(*Conn).handleCall(0xc20807ca20, 0xc20800afc0)
    /var/go/src/github.com/guelfey/go.dbus/export.go:125 +0xf41
created by github.com/guelfey/go%2edbus.(*Conn).inWorker
    /var/go/src/github.com/guelfey/go.dbus/conn.go:328 +0x247

I dug into the reflect package trying to find why this was happening, because it seems to only be in this very complex implementation that it happens, but I was unable to come up with a reason. I figured I would post here to see if anyone else found this issue and could shed some light on it. I am working around it using simpler structs and more return values, but the readability of this method was pretty fantastic and I would prefer to use it if this issue can be easily corrected.

In the meanwhile, if I happen to figure out what's causing it then I'll submit a PR. Thanks!