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

libbacktrace symbols rexporting? #189

Closed
GregBowyer opened this issue Feb 4, 2019 · 4 comments
Closed

libbacktrace symbols rexporting? #189

GregBowyer opened this issue Feb 4, 2019 · 4 comments

Comments

@GregBowyer
Copy link
Contributor

GregBowyer commented Feb 4, 2019

This one is going to be tricky.

The rust bug report is rust-lang/rust#58132, but it could easily be something in rules_rust, since we manipulate the linker.

Looks like something is causing libbacktrace symbols hiding out in libstd to ?maybe? reappear in static library artifacts. This could be rules_rust or something in rust proper. I am leaning towards something be incorrect w.r.t the linker being GCC.

How to reproduce

This is GCC and sanitizer specific, wont trigger without sanitizer flags and wont happen on clang (for reasons outlined below)

The following builds a stub for the regex crate capi, which allows the crate to be used from C/C++.

licenses([
    "notice",
])

load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library")

rust_library(
    name = "rure_impl",
    srcs = glob(["regex-capi/**/*.rs"]),
    crate_type = "staticlib",
    deps = [
        "@bedrock//third_party/rust:regex",
        "@bedrock//third_party/rust:libc",
    ],
)

cc_library(
    name = "rure",
    srcs = [":rure_impl"],
    hdrs = ["regex-capi/include/rure.h"],
    linkstatic = 1,
    linkopts = ["-ldl"],
    strip_include_prefix = "regex-capi/include",
    nocopts = "-O3|-Ofast|-Wno-literal-suffix|-fsanitize=.*|-static-libasan",
    visibility = ["//visibility:public"],
)

cc_test(
    name = "rure_test",
    srcs = ["regex-capi/ctest/test.c"],
    deps = [":rure"],
)

... causes librure_impl.a to contain backtrace symbols (like so)

greg@gregslaptop ~/work/core-ticketing-host $ nm bazel-out/k8-fastbuild/bin/external/rure/librure_impl-444955826.a | grep backtrace_uncompress_zdebug
0000000000000000 T backtrace_uncompress_zdebug

This seems to appear at the static library step, the rlibs lack these symbols. Messing with the link args in rustc.bzl to drop out sanitizer flags does not seem to prevent the definition of libbacktrace symbols appearing in the static lib.

This does not cause an issue without doing a sanitizer link. GCC itself uses libbacktrace as part of ASAN to provide symbolisation, and it seems that those synbols are not hidden in asan. Clang does not use libbacktrace, but instead calls out to an external application (llvm-symboliser) to perform this function.

A extremely unpleasant work around is to abuse strip to rip out the unwanted symbols with the following BUILD file

licenses([
    "notice",
])

config_setting(name = "is_xsan", values = { "define": "gcc_sanitize=true" })

load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library")

rust_library(
    name = "rure_impl",
    srcs = glob(["regex-capi/**/*.rs"]),
    crate_type = "staticlib",
    deps = [
        "@bedrock//third_party/rust:regex",
        "@bedrock//third_party/rust:libc",
    ],
)

cc_library(
    name = "rure",
    srcs = [":rure_impl"],
    hdrs = ["regex-capi/include/rure.h"],
    linkstatic = 1,
    linkopts = ["-ldl"],
    strip_include_prefix = "regex-capi/include",
    nocopts = "-O3|-Ofast|-Wno-literal-suffix|-fsanitize=.*|-static-libasan",
    visibility = ["//visibility:public"],
)

genrule(
    name = "dont_ask",
    srcs = ["rure_impl"],
    outs = ["rure_impl2.a"],
    cmd = """
        strip -N backtrace_uncompress_zdebug -o "$@" "$<"
    """,
)

cc_library(
    name = "rure_backtrace_strip",
    srcs = [":dont_ask"],
    hdrs = ["regex-capi/include/rure.h"],
    linkstatic = 1,
    linkopts = ["-ldl"],
    strip_include_prefix = "regex-capi/include",
    nocopts = "-O3|-Ofast|-Wno-literal-suffix|-fsanitize=.*|-static-libasan",
    visibility = ["//visibility:public"],
)

cc_test(
    name = "rure_test",
    srcs = ["regex-capi/ctest/test.c"],
    deps = select({
        ":is_xsan": [":rure_backtrace_strip"],
        "//conditions:default": [":rure"],
    }),
)

Which I suspect is really really really fragile

Thoughts?

@mfarrugi
Copy link
Collaborator

mfarrugi commented Feb 5, 2019

I don't know enough about this space to offer useful thoughts, but this sounds vaguely related to #78

@ghost
Copy link

ghost commented Sep 25, 2019

I am also running into this, building a rust cdylib invoked from Java, depending on what code I invoke I see:

b_k8/_U_S_S_Cwrapper___U/librust-1678821589.so: undefined symbol: backtrace_syminfo
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
	at java.lang.Runtime.loadLibrary0(Runtime.java:870)
	at java.lang.System.loadLibrary(System.java:1122)
	at Main.<clinit>(Main.java:4)

looks like under the hood it's using backtrace + error-chain.

@mfarrugi
Copy link
Collaborator

@Rustacian I think your problem might be different.

I am not sure where librust's backtrace_syminfo is supposed to come from, but if I recall correctly it takes some finagling for bazel generated java binaries (ie. the wrapper jvm startup script) to include transitive native dependencies on the native library path (i think java.library.path).

@ghost
Copy link

ghost commented Sep 25, 2019

@mfarrugi thanks for the response. I'll open up a separate issue tomorrow with a minimal reproducing example if that's alright. It may very well be an unrelated issue.

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

No branches or pull requests

2 participants