dnssd icon indicating copy to clipboard operation
dnssd copied to clipboard

panic: runtime error: cgo argument has Go pointer to Go pointer

Open brasilikum opened this issue 8 years ago • 9 comments

package main

import (
    "log"

    "github.com/andrewtj/dnssd"
)

func main() {
    op, err := dnssd.StartBrowseOp("_http._tcp", cb)
    if err != nil {
        log.Printf("Could not browse: %s", err)
        return
    }
    defer op.Stop()
}

func cb(op *dnssd.BrowseOp, err error, add bool, interfaceIndex int, name string, serviceType string, domain string) {
    if err != nil {
        // op is now inactive
        log.Printf("Browse operation failed: %s", err)
        return
    }
    change := "lost"
    if add {
        change = "found"
    }
    log.Printf("Browse operation %s %s service “%s” in %s on interface %d", change, serviceType, name, domain, interfaceIndex)
}

results in

panic: runtime error: cgo argument has Go pointer to Go pointer

goroutine 1 [running]:
panic(0x40f9300, 0xc82000a300)
    /usr/local/Cellar/go/1.6/libexec/src/runtime/panic.go:464 +0x3e6
/georg/mdns/vendor/github.com/andrewtj/dnssd.createConnection(0x41cad20, 0x0, 0x0)
    /georg/mdns/vendor/github.com/andrewtj/dnssd/os_unix.go:235 +0x58
/georg/mdns/vendor/github.com/andrewtj/dnssd.(*pollServerState).establishSharedConnection(0x41cad00)
    /georg/mdns/vendor/github.com/andrewtj/dnssd/poller.go:105 +0x5b
/georg/mdns/vendor/github.com/andrewtj/dnssd.(*pollServerState).startOp(0x41cad00, 0x42961e8, 0xc820014230, 0x0, 0x0)
    /georg/mdns/vendor/github.com/andrewtj/dnssd/poller.go:48 +0x186
/georg/mdns/vendor/github.com/andrewtj/dnssd.(*BrowseOp).Start(0xc820014230, 0x0, 0x0)
    /georg/mdns/vendor/github.com/andrewtj/dnssd/browse.go:87 +0x112
/georg/mdns/vendor/github.com/andrewtj/dnssd.StartBrowseOp(0x4122d00, 0xa, 0x4152af0, 0x40943f3, 0x0, 0x0)
    /georg/mdns/vendor/github.com/andrewtj/dnssd/browse.go:27 +0x54
main.main()
    /georg/mdns/mdns.go:10 +0x3c

I am using go 1.6, so it might be a change in the way pointers to c are handled.

brasilikum avatar Mar 09 '16 10:03 brasilikum

I am using go 1.6, so it might be a change in the way pointers to c are handled.

Yep it is. I haven't looked into the specifics yet and probably won't till the end of next week at the earliest.

andrewtj avatar Mar 09 '16 10:03 andrewtj

If anyone's interested in taking on this issue or maintaining this package more generally please drop me a note.

andrewtj avatar Apr 19 '16 04:04 andrewtj

Any update on this? I'm running into the same problem...

pieterclaerhout avatar Sep 23 '16 12:09 pieterclaerhout

@pieterclaerhout It is as it appears: in need of work.

andrewtj avatar Sep 24 '16 03:09 andrewtj

Well, same problem here in Go 1.7.3, with almost the same trace:

`panic: runtime error: cgo argument has Go pointer to Go pointer

goroutine 1 [running]: panic(0x4ba280, 0xc42000c380) /usr/local/go/src/runtime/panic.go:500 +0x1a1 github.com/andrewtj/dnssd.createConnection(0x748f60, 0xc42004dd68, 0x450850) /home/remi/Go/src/github.com/andrewtj/dnssd/os_unix.go:235 +0x56 github.com/andrewtj/dnssd.(_pollServerState).establishSharedConnection(0x748f40) /home/remi/Go/src/github.com/andrewtj/dnssd/poller.go:105 +0x60 github.com/andrewtj/dnssd.(_pollServerState).startOp(0x748f40, 0x73d700, 0xc420018280, 0x0, 0x0) /home/remi/Go/src/github.com/andrewtj/dnssd/poller.go:48 +0x125 github.com/andrewtj/dnssd.(*QueryOp).Start(0xc420018280, 0x0, 0x0) /home/remi/Go/src/github.com/andrewtj/dnssd/queryrecord.go:111 +0xac github.com/andrewtj/dnssd.StartQueryOp(0x0, 0x4d7c0c, 0x1d, 0xc40001000c, 0x4dffd8, 0x73d300, 0xc42002e010, 0xc42004def8) /home/remi/Go/src/github.com/andrewtj/dnssd/queryrecord.go:33 +0x74 main.queryAllServices(0xc42004def8, 0x1, 0x1) /home/remi/Go/src/github.com/rdeg/sq/sq.go:279 +0x57 main.main() /home/remi/Go/src/github.com/rdeg/sq/sq.go:305 +0x12d exit status 2 ` This is initiated by a:

op, err = dnssd.StartQueryOp(0, "_services._dns-sd._udp.local.", 12, 1, queryCallback)

Sorry for not being able to help but I am quite new to Linux (and Go) and I am not sure how I could debug this.

Anyway, thank for your work: under Windows, it does perform very well ;-)

[EDIT] Setting GODEBUG=cgocheck=0 (export GODEBUG=cgocheck=0) allows the program to run, along with a bunch of warnings:

*** WARNING *** The program 'sq' uses the Apple Bonjour compatibility layer of Avahi. *** WARNING *** Please fix your application to use the native API of Avahi! *** WARNING *** For more information see http://0pointer.de/avahi-compat?s=libdns_sd&e=sq *** WARNING *** The program 'sq' called 'DNSServiceCreateConnection()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi. *** WARNING *** Please fix your application to use the native API of Avahi! *** WARNING *** For more information see http://0pointer.de/avahi-compat?s=libdns_sd&e=sq&f=DNSServiceCreateConnection

I suppose that, as Andrew stated, there is some work to provide...

rdeg avatar Oct 20 '16 12:10 rdeg

@rdeg good to know it still works on Windows. If I were to try getting this going I'd first look back at the 1.6 release notes to review the CGO changes. I'd then write a minimal test using just DNSServiceRegister (setting port and callback only) and DNSServiceProcessResult (this guide might help if you're unfamiliar with them) before coming back to this package. My guess is there'll be a lot of churn under the covers but that the public API won't need to change (mind you, I still haven't read up on the changes so I could be way off).

EDIT: Also you can hide that Avahi warning with an environment variable: AVAHI_COMPAT_NOWARN=1

andrewtj avatar Oct 20 '16 22:10 andrewtj

I have switched to https://github.com/oleksandr/bonjour which does the same for what I need and does work fine on the recent versions of Go.

pieterclaerhout avatar Oct 21 '16 14:10 pieterclaerhout

@andrewtj

Thanks for the Avahi warning tip.

The offending instruction is:

func createConnection(ref *uintptr) error {return getError(int32(C.DNSServiceCreateConnection((*C.DNSServiceRef)(unsafe.Pointer(ref)))))}

in createConnection and, supposedly, in every function in os_unix.go that takes 'ref *uintptr' as a parameter and pass it to a C function (refSockFd, platformDeallocateRef).

The point is that Go thinks that ref is a Go pointer to another Go pointer, even if it is a pointer to an uintptr, described as being an integer type in the documentation ("uintptr is an integer type that is large enough to hold the bit pattern of any pointer."). Maybe Go does something wrong here...

In case someone is interested in a complete sample of code using your package, I wrote a simple DNS-SD browser in Go [(https://drive.google.com/file/d/0B9hKAVKYGzfUbXluZ1R6LWQtaFk/view?usp=sharing)]. Please be indulgent: it was my first Go program ;-)

Have a nice day. Remi

rdeg avatar Oct 21 '16 15:10 rdeg

I opened a PR with a fix for this issue: https://github.com/andrewtj/dnssd/pull/6

It's working well on my mac, but I could use some help testing on Windows and other platforms (and with various versions of golang).

tmm1 avatar Sep 20 '18 05:09 tmm1