Conversation
|
@anthonyray @Deluvi 👋 care for a review ? |
Deluvi
left a comment
There was a problem hiding this comment.
The unit enum support looks great ! 👍
The rest is a bit of nitpicks and such for the ASan / MSan tests, but it's good to have that covered ! (though through a very parkoury interpretation of a Rust test)
Feel free to dig into it. If that's irrelevant, ship it ![]()
I don't know how much is relevant here, but maybe mind that cross-language ASan and MSan might require extra caution because there might two conflicting ASan/MSan Clang runtimes, see: https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html#working-with-other-languages
| printf("Triggering ASan canary (should crash):\n"); | ||
| test_asan_canary(); | ||
| printf("ERROR: ASan did not catch use-after-free!\n"); | ||
| return 1; |
There was a problem hiding this comment.
When you run the ASan canary, you expect the binary to return a non-zero status:
assert!(
!canary.status.success(),
"Sanitizer canary ({}) should have crashed but didn't",
canary_flag
);That's because ASan will make exit the program with a non-zero status.
By doing return 1; here, you won't actually signal to the test program that ASan did not catch the use-after-free.
I think you should be doing a return 0; here
There was a problem hiding this comment.
Did that ! I also made sure the test won't actually segfault when doing the violation so we can actually get there if asan/msan is not enabled
| printf("Triggering MSan canary (should crash):\n"); | ||
| test_msan_canary(); | ||
| printf("ERROR: MSan did not catch uninitialized read!\n"); | ||
| return 1; |
There was a problem hiding this comment.
Same here, I think you should return 0; here
|
|
||
| /// Helper: set the env vars that the cc crate expects outside of build.rs. | ||
| fn setup_cc_env(host_target: &str) { | ||
| std::env::set_var("TARGET", host_target); |
There was a problem hiding this comment.
Note: std::env::set_var is not thread-safe:
This function is safe to call in a single-threaded program.
...
In multi-threaded programs on other operating systems, the only safe option is to not use set_var or remove_var at all.
cargo test will make several tests run in parallel in the same process but in different threads
Thankfully, for now, your tests are mutually exclusives because of #[cfg(feature = "msan")], but that's something to note
There was a problem hiding this comment.
I got rid of that, there are actually proper functions to configure CC
| compile_c_test( | ||
| tmp_dir.path(), | ||
| &target_dir, | ||
| "-fsanitize=address", |
There was a problem hiding this comment.
We build the C binary with ASan, but we don't build the Rust cdylib with ASan
Is there a reason why not?
There was a problem hiding this comment.
oversight, fixed, we now have the normal C round trip test that won't do asan/msan and will run on stable rust. We also have 2 nightly runs of the tests, enabling asan/msan on the rust code (at two levels, once for the full rust tests, and once when building the test cdylib
| let tmp_dir = tempfile::tempdir().expect("Failed to create temp dir"); | ||
|
|
||
| // Are we calling cargo from inside the test binary to make sure the cdylib is built ? | ||
| // yes, watch me. |
There was a problem hiding this comment.
Yeah that feels wrong, that's probably something that should be done outside of a cargo test, especially because tinkering with the build flags will probably render the cache of the cargo test invalid when running cargo build with such things as -Zsanitizer=memory, making the iteration loop a bit cumbersome
But hey, at least the CI and the developer will run them with a simple cargo test, so I guess it's not that so wrong 😂 (until it becomes annoying for the developer I guess)
There was a problem hiding this comment.
I made sure to change the cargo target dir when we do that now. This is actually quite fast once you have built it once (and first build is ok) this will prevent having weird things with the cargo lock on the build dir, this did work previously but was not really solid
| let stderr = String::from_utf8_lossy(&canary.stderr); | ||
| assert!( | ||
| stderr.contains(expected_stderr), | ||
| "Canary ({}) crashed but not from expected sanitizer: {}", |
There was a problem hiding this comment.
Ah right, you check for AddressSanitizer / MemorySanitizer in the logs. I don't know how much checking for such log is reliable and will not result in false positives
Maybe checking for return 0; is less finicky ?
There was a problem hiding this comment.
configured asan/msan to return 42 on violation and checking that, should be more robust
| pub flattened_range: Range<i64>, | ||
| pub field_with_specific_rust_name: String, | ||
| pub pancake_data: Option<Vec<u8>>, | ||
| pub extra_ice_cream_flavor: Flavor, |
There was a problem hiding this comment.
it's getting yummier and yummier
This adds support for unit enums. Fixes #57
I also expanded the roundtrip test we have; this will now generate a C header and compile C \o/