Skip to content

cmd/link: don't swallow external linker warnings #17935

@cyli

Description

@cyli

I think there may be something wrong with cgo networking DNS name resolution. I get a segfault when attempting to reach a server with an invalid TLD type name (for instance, the an alias I might put in /etc/hosts).

What version of Go are you using (go version)?

go version go1.7.3 linux/amd64

What operating system and processor architecture are you using (go env)?

Running on Ubuntu 16.04.

$ dpkg-query -s linux-headers-generic
Package: linux-headers-generic
Status: install ok installed
Priority: optional
Section: kernel
Installed-Size: 12
Maintainer: Ubuntu Kernel Team <kernel-team@lists.ubuntu.com>
Architecture: amd64
Source: linux-meta
Version: 4.4.0.47.50
Depends: linux-headers-4.4.0-47-generic
Description: Generic Linux kernel headers
 This package will always depend on the latest generic kernel headers
 available.

$ ldd --version
ldd (Ubuntu GLIBC 2.23-0ubuntu4) 2.23
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/root/Go"
GORACE=""
GOROOT="/root/go"
GOTOOLDIR="/root/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build792732901=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"

What did you do?

Built a static binary using the following file:

package main

/*
char* foo(void) { return "hello, world!"; }
*/
import "C"

// trivial example that just includes some CGO so that the binary is built with cgo

import (
	"fmt"
	"net/http"
	"os"
)

func main() {
	resp, err := http.Get(os.Args[1])
	fmt.Println(C.GoString(C.foo()), resp, err)
}
$ go build -o temp -ldflags "-extldflags -static" ./cmd/temp
$ ./temp http://not-really-a-domain-name

What did you expect to see?

$ go build -o temp -ldflags "-extldflags -static" ./cmd/temp
$ ./temp http://not-really-a-domain-name
hello, world! <nil> dial tcp: lookup not-really-a-domain-name on 8.8.8.8:53: no such host

What did you see instead?

$ go build -o temp -ldflags "-extldflags -static" ./cmd/temp
$ ./temp http://not-really-a-domain-name
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x0]

runtime stack:
runtime.throw(0x6f2071, 0x2a)
	/root/go/src/runtime/panic.go:566 +0x95
runtime.sigpanic()
	/root/go/src/runtime/sigpanic_unix.go:12 +0x2cc

goroutine 8 [syscall, locked to thread]:
runtime.cgocall(0x5b9d60, 0xc4200245f8, 0xc400000000)
	/root/go/src/runtime/cgocall.go:131 +0x110 fp=0xc4200245b0 sp=0xc420024570
net._C2func_getaddrinfo(0x2490eb0, 0x0, 0xc420017320, 0xc420026050, 0x0, 0x0, 0x0)
	??:0 +0x68 fp=0xc4200245f8 sp=0xc4200245b0
net.cgoLookupIPCNAME(0xc4200b0760, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/root/go/src/net/cgo_unix.go:146 +0x37c fp=0xc420024718 sp=0xc4200245f8
net.cgoIPLookup(0xc4200565a0, 0xc4200b0760, 0x18)
	/root/go/src/net/cgo_unix.go:198 +0x4d fp=0xc4200247a8 sp=0xc420024718
runtime.goexit()
	/root/go/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc4200247b0 sp=0xc4200247a8
created by net.cgoLookupIP
	/root/go/src/net/cgo_unix.go:208 +0xb4

goroutine 1 [select]:
net/http.(*Transport).getConn(0xc4200b4000, 0xc4200b0740, 0x0, 0x6ef4c9, 0x4, 0xc4200b0760, 0x1b, 0x0, 0x0, 0x0)
	/root/go/src/net/http/transport.go:890 +0x9d2
net/http.(*Transport).RoundTrip(0xc4200b4000, 0xc4200b40f0, 0x6ef4c9, 0x1f, 0x0)
	/root/go/src/net/http/transport.go:367 +0x307
main.main()
	/root/go/src/github.com/docker/notary/cmd/temp/temp.go:15 +0x91

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
	/root/go/src/runtime/asm_amd64.s:2086 +0x1

goroutine 5 [select]:
net.lookupIPContext(0xa041c0, 0xc4200564e0, 0xc4200b0760, 0x18, 0x0, 0x0, 0x0, 0x0, 0x444f5e)
	/root/go/src/net/lookup.go:122 +0x7bc
net.internetAddrList(0xa041c0, 0xc4200564e0, 0x6e7dc1, 0x3, 0xc4200b0760, 0x1b, 0x0, 0x0, 0x0, 0xecfbd9ed9, ...)
	/root/go/src/net/ipsock.go:241 +0x5e0
net.resolveAddrList(0xa041c0, 0xc4200564e0, 0x6e7f90, 0x4, 0x6e7dc1, 0x3, 0xc4200b0760, 0x1b, 0x0, 0x0, ...)
	/root/go/src/net/dial.go:179 +0x106
net.(*Dialer).DialContext(0xc42004c5a0, 0xa04180, 0xc42000c458, 0x6e7dc1, 0x3, 0xc4200b0760, 0x1b, 0x0, 0x0, 0x0, ...)
	/root/go/src/net/dial.go:329 +0x238
net.(*Dialer).DialContext-fm(0xa04180, 0xc42000c458, 0x6e7dc1, 0x3, 0xc4200b0760, 0x1b, 0xc42000d001, 0xc420056420, 0xc420037a38, 0x40f728)
	/root/go/src/net/http/transport.go:43 +0x73
net/http.(*Transport).dial(0xc4200b4000, 0xa04180, 0xc42000c458, 0x6e7dc1, 0x3, 0xc4200b0760, 0x1b, 0x0, 0x0, 0x0, ...)
	/root/go/src/net/http/transport.go:826 +0x227
net/http.(*Transport).dialConn(0xc4200b4000, 0xa04180, 0xc42000c458, 0x0, 0x6ef4c9, 0x4, 0xc4200b0760, 0x1b, 0x0, 0x0, ...)
	/root/go/src/net/http/transport.go:967 +0x1a85
net/http.(*Transport).getConn.func4(0xc4200b4000, 0xa04180, 0xc42000c458, 0xc420016ea0, 0xc420056180)
	/root/go/src/net/http/transport.go:885 +0x78
created by net/http.(*Transport).getConn
	/root/go/src/net/http/transport.go:887 +0x398

goroutine 7 [select]:
net.cgoLookupIP(0xa041c0, 0xc4200564e0, 0xc4200b0760, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/root/go/src/net/cgo_unix.go:209 +0x2f5
net.lookupIP(0xa041c0, 0xc4200564e0, 0xc4200b0760, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0)
	/root/go/src/net/lookup_unix.go:70 +0xf9
net.glob..func11(0xa041c0, 0xc4200564e0, 0x705450, 0xc4200b0760, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0)
	/root/go/src/net/hook.go:19 +0x52
net.lookupIPContext.func1(0x0, 0x0, 0x0, 0x0)
	/root/go/src/net/lookup.go:119 +0x5c
internal/singleflight.(*Group).doCall(0xa15ad0, 0xc42004c6e0, 0xc4200b0760, 0x18, 0xc420016fc0)
	/root/go/src/internal/singleflight/singleflight.go:93 +0x3c
created by internal/singleflight.(*Group).DoChan
	/root/go/src/internal/singleflight/singleflight.go:86 +0x339

This does not happen if attempt to reach a valid domain name, if I do ./temp http://not-a-thing.com"

It also happens if I reach a .local domain: ./temp http://not-really-a-domain-name.local

This does not happen if I compile a non-static binary:

$ ~/go/bin/go build -o temp ./cmd/temp
$ ./temp http://not-really-a-domain-name
hello, world! <nil> dial tcp: lookup not-really-a-domain-name: no such host

I think this is a duplicate of #7857, which got closed for inactivity.

I've also seen this here: prometheus/alertmanager#304

Workaround

Passing -tags netgo fixes it.

$ go build -o temp -ldflags "-extldflags -static" -tags netgo ./cmd/temp
$ ./temp
hello, world! <nil> dial tcp: lookup not-really-a-domain-name on 8.8.8.8:53: no such host

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions