LLVM debug output through rust - rust

I am looking for a way to read the LLVM debug output by invoking the rust compiler (through cargo). I am especially interested in output of LLVMs ASAN.
To run a build with ASAN I can do:
cargo clean && RUSTFLAGS="-Zsanitizer=address" cargo build
but I don't know the command to get the debug log ouput.
With clang I think one can add
-mllvm -debug-only=asan
as compiler-flag.
How can I supply something like this flag through rustc?
I am using the current rust source (https://github.com/rust-lang/rust/ commit 31f5d69) to build rustc myself.

The equivalent compiler argument for rustc is
-C llvm-args=-debug-only=<LLVM DEBUG_TYPE>
The -C part gives access to the options for code generation of rust.
The llvm-args part tells rustc to forward every subsequent flag to LLVM. If I understand correctly, you can specify every LLVM option that is evaluated with cl::opt() in LLVM source code.
So the full command to build a rust application with ASAN and see only the log output of ASAN would be:
cargo clean && RUSTFLAGS="-C llvm-args=-debug-only=asan -Zsanitizer=address" cargo build
Side note: I think debug mode for LLVM must be enabled in config.toml when building rust to see the respective log output.

Related

Remove default linker flags in Rust

Is there a way to remove problematic linker flags in the cargo build command? I'm trying to cross-compile a binary on windows for x86_64-unknown-linux-gnu but linking fails with the message: ld unrecognized option: --eh-frame-hdr. Is there a way to remove this argument from the linking stage without having to create a custom target specification for linux builds?
I only found the rustflags key in config.toml, but as far as I know it only allows you to add additional flags and not to strip existing ones.
Start by making sure that you are passing the right linker-flavor. rustc might have misidentified what linker you are using, and specifying that might help. Also ensure you are using the right linker. But if you really want to remove that argument, it is possible using some unstable features.
There isn't a general way to remove individual linker arguments. The eh_frame_header target attribute indicates if the linker should insert a EH (exception handling) frame header. Unstable rustc does have support for changing individual target options, but it is a bit complicated and can only handle #![no_std] binaries on some platforms. You might want to consider just calling the linker manually.
First, dump the JSON target metadata (using a nightly compiler) for the target you are compiling to, replacing [target] with a target triple like thumbv7neon-unknown-linux-musleabihf:
$ rustc -Z unstable-options --print target-spec-json --target [target] > target.json
target.json now has target-specific compilation information. On some targets (such as WASM), EH frame headers are disabled by default. If you see a line like this in target.json, you are already done (and shouldn't be getting that error):
"eh-frame-header": false,
If you don't see that line, then add it to target.json right after opening brace, like
{
"eh-frame-header": false,
...
You can now specify the path to target.json wherever a target triple would normally be. However, you now need to recompile the standard libraries (such as core and std) with the new target information. Otherwise, the compiler will tell you that the `target-17676080659170949227` target may not be installed. On unstable Cargo, you can use -Z build-std
to do that:
$ cargo +nightly run -Z build-std=core --target target.json
It will take a bit longer than normal, since it needs to recompile the core standard library. Not all platforms support compiling the fuller std library this way, but you can change the build-std=core to just build-std if you want to try to build the whole std standard library as well.

rust, WebAssembly, and passing arguments for increased total memory

I have a rust project I am compiling to webasm per http://asquera.de/blog/2017-04-10/the-path-to-rust-on-the-web/
Project compiles. When I run it in Chrome Canary, it runs out of memory and gives me a very helpful error message:
abort("Cannot enlarge memory arrays. Either (1) compile with -s
TOTAL_MEMORY=X with X higher than the current value 16777216, (2) compile
with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime,
...
Problem is, its not clear how to pass those flags to rustc / the build tool chain.
Neither setting EMMAKEN_CFLAGS or the following work:
cargo rustc -v --target=wasm32-unknown-emscripten --release -- -Clink-args="-s TOTAL_MEMORY=33554432"
This blog post offers a solution that I think can be applied in your case too:
As best as I can tell there is no way to pass most linker arguments through cargo. Instead, hack around the limitation by specifying a custom linker that is actually a shell script wrapping the real linker.
Create a shell script like emcc_link that calls emscripten with the appropriate options:
emcc "-s" "TOTAL_MEMORY=33554432" $#
(You may need other options to make it work. Check the blog post for details.)
And specify to use it for your project by editing/creating .cargo/config:
[target.wasm32-unknown-emscripten]
linker = "/your/project/dir/emcc_sdl"
[target.asmjs-unknown-emscripten]
linker = "/your/project/dir/emcc_sdl"
I ruthlessly assumed the build environment is Linux or the like. On Windows the shell script should probably be a batch script and I'm not sure if there are any differences in .cargo/config.
Disclaimer: I have not tried any of this.

"Unrecognized option 'release'" when compiling with rustc in release mode

I have a simple .rs file and want to compile it using rustc. I always heard about how important it is to compile in release mode, because otherwise my Rust program will be slow.
However, if I use the often quoted --release flag, it doesn't work. What is everyone talking about if the flag doesn't even exist?
$ rustc --release foo.rs
error: Unrecognized option: 'release'.
You made a simple mistake: The --release flag is a flag for cargo. The easiest way you can turn on optimizations with rustc is using the -O flag.
Examples:
rustc -O foo.rs
rustc -C opt-level=3 foo.rs
cargo build --release
A bit more detail:
You can compile your Rust program with various levels of optimization. rustc -C help says:
-C opt-level=val -- optimize with possible levels 0-3, s, or z
To have the most control, you should compile with rustc -C opt-level=3 foo.rs (or any other level). However, this isn't always necessary. Often, you can use -O; rustc --help says:
-O Equivalent to -C opt-level=2
Most of the time rustc -O foo.rs is the right choice.
Cargo, on the other hand, works a bit different; or at least the --release flag does. Cargo has different profiles which dictate how cargo invokes rustc. The most important ones are dev (development- or debug-mode) and release. The --release flag switches the default profile from dev to release (duh!). This potentially changes many flags of the rustc invocation. Most importantly, it changes the values for opt-level and debuginfo:
$ rustc -C debuginfo=2 -C opt-level=0 # in `dev` profile/debug mode
$ rustc -C debuginfo=0 -C opt-level=3 # in `release` profile
You can even change the settings for each profile in your Cargo.toml. You can find more information on profiles and on the default values used in this Cargo documentation.

Adding codegen flags to a Cargo build

On Macintosh, to allow some symbols to go unlinked, it is necessary to pass -C link-args='-Wl,-undefined,dynamic_lookup' to the Rust compiler. One needs to do this when building Postgres plugins, because some of the Postgres intrinsics are only compiled into the Postgres server, and not available for linking from shared libs.
At present, the project's process is as follows:
Build is run with cargo build -v.
Failing call to rustc is copied and -C link-args='-Wl,-undefined,dynamic_lookup' added to it.
Success!
This seems like a hard sell for automation. What options are available for adding codegen flags to Rust builds through cargo?
cargo provides rustc command which allows one to pass arbitrary compiler flags. The following should do it:
% cargo rustc -- -C link-args='-Wl,-undefined,dynamic_lookup'

How to pass -L linker flag to rustc for cargo based project?

How do I make cargo pass -L linker flag to rustc invocations?
It is now possible using .cargo/config.
See https://github.com/rust-lang/cargo/issues/1109 and http://doc.crates.io/config.html.
Not yet. However, you can use a custom makefile for given Cargo project instead.
For example, Servo uses the Skia library by having a Rust wrapper in the same cargo project, and a build key that calls a custom makefile.
You can do something similar in this case, for now.

Resources