Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove -pie from LDFLAGS if buildmode is not pie #3691

Open
siddharthab opened this issue Sep 13, 2023 · 3 comments · May be fixed by #3693
Open

Remove -pie from LDFLAGS if buildmode is not pie #3691

siddharthab opened this issue Sep 13, 2023 · 3 comments · May be fixed by #3693

Comments

@siddharthab
Copy link
Contributor

What version of rules_go are you using?

0.41.0

What version of gazelle are you using?

N/A

What version of Bazel are you using?

6.3.2

Does this issue reproduce with the latest releases of all the above?

Yes

What operating system and processor architecture are you using?

Debian 12

Any other potentially useful information about your toolchain?

LLVM 15 with LLD. On Debian like systems, can be set up with:

sudo apt-get install clang-15 lld-15

What did you do?

CASE 1: Tried to build and run a cgo test target within this project with the --force_pic flag.

CC=clang-15 bazel run --force_pic //tests/core/cgo:c_srcs

CASE 2: Instead of one of the tests from this repo, a simpler Go program can also be:

// File main.go
package main

// #cgo LDFLAGS: -lm
// #include <math.h>
import "C"
import "fmt"

func main() {
	fmt.Println(int(C.sqrt(100.0)))
}

with a build target that is simply:

go_binary(
  name = "main",
  srcs = ["main.go"],
  cgo = True,
)

What did you expect to see?

The test target run completing successfully, and/or the simpler Go program run completing successfully.

What did you see instead?

runtime: pcHeader: magic= 0xfffffff1 pad1= 0 pad2= 0 minLC= 1 ptrSize= 8 pcHeader.textStart= 0x9dc40 text= 0x5611882ecc40 pluginpath= 
fatal error: invalid function symbol table
runtime: panic before malloc heap initialized

runtime stack:
runtime.throw({0x561188274f78?, 0x0?})
	GOROOT/src/runtime/panic.go:1047 +0x5d fp=0x7ffd1e384c80 sp=0x7ffd1e384c50 pc=0x56118831cefd
runtime.moduledataverify1(0x7ffd1e384dac?)
	GOROOT/src/runtime/symtab.go:627 +0x806 fp=0x7ffd1e384d80 sp=0x7ffd1e384c80 pc=0x5611883384e6
runtime.moduledataverify(...)
	GOROOT/src/runtime/symtab.go:613
runtime.schedinit()
	GOROOT/src/runtime/proc.go:710 +0x3a fp=0x7ffd1e384de0 sp=0x7ffd1e384d80 pc=0x5611883209da
runtime.rt0_go()
	src/runtime/asm_amd64.s:349 +0x11c fp=0x7ffd1e384de8 sp=0x7ffd1e384de0 pc=0x561188347ddc

Notes

This crash is happening because force_pic is sending the -pie flag to the linker, which gets passed along as part of CGO_LDFLAGS. But because the buildmode is not set to "pie" in the go_binary target, I think the stdlib is mismatched.

This is not a problem with the standard Go toolchain because it filters out the "-pie" flag from CGO_LDFLAGS.

Building under normal buildmode, will filter out "-pie" from the linker command. Notice that there were no -extldflags set for the link step.

CC=clang-15 CGO_LDFLAGS='-v -fuse-ld=lld -pie' go build -x main.go

To force sending "-pie" to the linker, you will have to explicitly set -extldflags.

CC=clang-15 CGO_LDFLAGS='-v -fuse-ld=lld' go build -ldflags -extldflags='-pie' -x main.go
@fmeum
Copy link
Collaborator

fmeum commented Sep 14, 2023

The analysis looks just right, thanks!

Would you be interested in sending a fix?

if go.mode != LINKMODE_NORMAL:
for opt_list in (copts, cxxopts, objcopts, objcxxopts):
if "-fPIC" not in opt_list:
opt_list.append("-fPIC")
seems like a good spot to place this in.

siddharthab added a commit to siddharthab/rules_go that referenced this issue Sep 14, 2023
@siddharthab
Copy link
Contributor Author

Thanks. I sent a PR that works for this specific example. But I am not sure if I am matching all the conditions right. Will you be able to take a look at the TODO I have in my change?

@mmellin
Copy link

mmellin commented Feb 3, 2024

I see the same error when trying to build a go_proto_library target on my Ubuntu 22.04 using LLVM @v16.0.4. If I remove LLVM, it seems to work fine.

 fatal error: invalid function symbol table
runtime: panic before malloc heap initialized

runtime stack:
runtime.throw({0x564b54c01542?, 0x0?})
        GOROOT/src/runtime/panic.go:1047 +0x5d fp=0x7ffd201b67e0 sp=0x7ffd201b67b0 pc=0x564b54f26f5d
runtime.moduledataverify1(0x564b552c47a0?)
        GOROOT/src/runtime/symtab.go:627 +0x806 fp=0x7ffd201b68e0 sp=0x7ffd201b67e0 pc=0x564b54f44866
runtime.moduledataverify(...)
        GOROOT/src/runtime/symtab.go:613
runtime.schedinit()
        GOROOT/src/runtime/proc.go:710 +0x3a fp=0x7ffd201b6940 sp=0x7ffd201b68e0 pc=0x564b54f2aa3a
runtime.rt0_go()
        src/runtime/asm_amd64.s:349 +0x11c fp=0x7ffd201b6948 sp=0x7ffd201b6940 pc=0x564b54f5619c
--grpc-gateway_out: protoc-gen-grpc-gateway: Plugin failed with status code 2.

Rule:

go_proto_library(
    name = "v1_go_proto",
    compilers = [
        "@io_bazel_rules_go//proto:go_grpc",
        "@com_github_grpc_ecosystem_grpc_gateway_v2//protoc-gen-grpc-gateway:go_gen_grpc_gateway",
    ],
    importpath = "mydomain.com/mysrvc/proto/mysrvc/v1",
    proto = ":v1_proto",
    visibility = ["//visibility:public"],
    deps = ["@googleapis//google/api:annotations_go_proto"],
)

Bazel 6.3.2
Rules_go 0.44.0
rules_proto_grpc 4.5.0
toolchains_llvm 0.10.3
Go 1.20.7
grpc-ecosystem/grpc-gateway/v2 @v2.16.2

I seemed to solve it by upgrading the grpc-gateway compiler lib github.com/grpc-ecosystem/grpc-gateway/v2 pkg to v2.19.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants