Stream: git-wasmtime

Topic: wasmtime / issue #5018 Cranelift: miscompilation causing ...


view this post on Zulip Wasmtime GitHub notifications bot (Oct 05 2022 at 11:00):

nivkner opened issue #5018:

this is a miscompilation of rust code, compiled with rustc cranelift backend.

i identified the cause to be commit 05cbd667c7e89828a45ebc5760787a6160c55c8d. before the commit the same code runs as expected and afterwards there is a segfault

.clif Test Case

i tried to produce a .clif file but because the problem is not a crash during compilation, clif-util bugpoint cant be used,
tried using --emit llvm-ir to get the clif generated by rustc, but i couldn't produce a binary from them to see if it causes a segfault.

@bjorn3 if you know how to get a usable .clif file from the backend for this scenario, please let me know

Steps to Reproduce

diff --git a/Cargo.toml b/Cargo.toml
index 09cf5b4..d20efb2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,12 +8,12 @@ crate-type = ["dylib"]

 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { version = "0.88.1", features = ["unwind", "all-arch"] }
-cranelift-frontend = "0.88.1"
-cranelift-module = "0.88.1"
-cranelift-native = "0.88.1"
-cranelift-jit = { version = "0.88.1", optional = true }
-cranelift-object = "0.88.1"
+cranelift-codegen = { version = "0.89.0", features = ["unwind", "all-arch"] }
+cranelift-frontend = "0.89.0"
+cranelift-module = "0.89.0"
+cranelift-native = "0.89.0"
+cranelift-jit = { version = "0.89.0", optional = true }
+cranelift-object = "0.89.0"
 target-lexicon = "0.12.0"
 gimli = { version = "0.26.0", default-features = false, features = ["write"]}
 object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
@@ -26,12 +26,12 @@ smallvec = "1.8.1"

 [patch.crates-io]
 # Uncomment to use local checkout of cranelift
-#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
-#cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
-#cranelift-module = { path = "../wasmtime/cranelift/module" }
-#cranelift-native = { path = "../wasmtime/cranelift/native" }
-#cranelift-jit = { path = "../wasmtime/cranelift/jit" }
-#cranelift-object = { path = "../wasmtime/cranelift/object" }
+cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
+cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
+cranelift-module = { path = "../wasmtime/cranelift/module" }
+cranelift-native = { path = "../wasmtime/cranelift/native" }
+cranelift-jit = { path = "../wasmtime/cranelift/jit" }
+cranelift-object = { path = "../wasmtime/cranelift/object" }

 #gimli = { path = "../" }
fn main() {
    std::env::args().collect::<Vec<_>>();
}

Expected Results

the binary executes successfully

Actual Results

Segmentation fault (core dumped)

Versions and Environment

Cranelift version or commit: e63771f2d921cdce440620dbf38bd3e186747b1e (latest commit on which the bug is reproduced) 05cbd667c7e89828a45ebc5760787a6160c55c8d (earliest commit on which the bug is reproduced)

Operating system: arch linux, kernel version 5.19.12-arch1-1

Architecture: x86_64

view this post on Zulip Wasmtime GitHub notifications bot (Oct 05 2022 at 11:00):

nivkner labeled issue #5018:

this is a miscompilation of rust code, compiled with rustc cranelift backend.

i identified the cause to be commit 05cbd667c7e89828a45ebc5760787a6160c55c8d. before the commit the same code runs as expected and afterwards there is a segfault

.clif Test Case

i tried to produce a .clif file but because the problem is not a crash during compilation, clif-util bugpoint cant be used,
tried using --emit llvm-ir to get the clif generated by rustc, but i couldn't produce a binary from them to see if it causes a segfault.

@bjorn3 if you know how to get a usable .clif file from the backend for this scenario, please let me know

Steps to Reproduce

diff --git a/Cargo.toml b/Cargo.toml
index 09cf5b4..d20efb2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,12 +8,12 @@ crate-type = ["dylib"]

 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { version = "0.88.1", features = ["unwind", "all-arch"] }
-cranelift-frontend = "0.88.1"
-cranelift-module = "0.88.1"
-cranelift-native = "0.88.1"
-cranelift-jit = { version = "0.88.1", optional = true }
-cranelift-object = "0.88.1"
+cranelift-codegen = { version = "0.89.0", features = ["unwind", "all-arch"] }
+cranelift-frontend = "0.89.0"
+cranelift-module = "0.89.0"
+cranelift-native = "0.89.0"
+cranelift-jit = { version = "0.89.0", optional = true }
+cranelift-object = "0.89.0"
 target-lexicon = "0.12.0"
 gimli = { version = "0.26.0", default-features = false, features = ["write"]}
 object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
@@ -26,12 +26,12 @@ smallvec = "1.8.1"

 [patch.crates-io]
 # Uncomment to use local checkout of cranelift
-#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
-#cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
-#cranelift-module = { path = "../wasmtime/cranelift/module" }
-#cranelift-native = { path = "../wasmtime/cranelift/native" }
-#cranelift-jit = { path = "../wasmtime/cranelift/jit" }
-#cranelift-object = { path = "../wasmtime/cranelift/object" }
+cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
+cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
+cranelift-module = { path = "../wasmtime/cranelift/module" }
+cranelift-native = { path = "../wasmtime/cranelift/native" }
+cranelift-jit = { path = "../wasmtime/cranelift/jit" }
+cranelift-object = { path = "../wasmtime/cranelift/object" }

 #gimli = { path = "../" }
fn main() {
    std::env::args().collect::<Vec<_>>();
}

Expected Results

the binary executes successfully

Actual Results

Segmentation fault (core dumped)

Versions and Environment

Cranelift version or commit: e63771f2d921cdce440620dbf38bd3e186747b1e (latest commit on which the bug is reproduced) 05cbd667c7e89828a45ebc5760787a6160c55c8d (earliest commit on which the bug is reproduced)

Operating system: arch linux, kernel version 5.19.12-arch1-1

Architecture: x86_64

view this post on Zulip Wasmtime GitHub notifications bot (Oct 05 2022 at 11:00):

nivkner labeled issue #5018:

this is a miscompilation of rust code, compiled with rustc cranelift backend.

i identified the cause to be commit 05cbd667c7e89828a45ebc5760787a6160c55c8d. before the commit the same code runs as expected and afterwards there is a segfault

.clif Test Case

i tried to produce a .clif file but because the problem is not a crash during compilation, clif-util bugpoint cant be used,
tried using --emit llvm-ir to get the clif generated by rustc, but i couldn't produce a binary from them to see if it causes a segfault.

@bjorn3 if you know how to get a usable .clif file from the backend for this scenario, please let me know

Steps to Reproduce

diff --git a/Cargo.toml b/Cargo.toml
index 09cf5b4..d20efb2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,12 +8,12 @@ crate-type = ["dylib"]

 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { version = "0.88.1", features = ["unwind", "all-arch"] }
-cranelift-frontend = "0.88.1"
-cranelift-module = "0.88.1"
-cranelift-native = "0.88.1"
-cranelift-jit = { version = "0.88.1", optional = true }
-cranelift-object = "0.88.1"
+cranelift-codegen = { version = "0.89.0", features = ["unwind", "all-arch"] }
+cranelift-frontend = "0.89.0"
+cranelift-module = "0.89.0"
+cranelift-native = "0.89.0"
+cranelift-jit = { version = "0.89.0", optional = true }
+cranelift-object = "0.89.0"
 target-lexicon = "0.12.0"
 gimli = { version = "0.26.0", default-features = false, features = ["write"]}
 object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
@@ -26,12 +26,12 @@ smallvec = "1.8.1"

 [patch.crates-io]
 # Uncomment to use local checkout of cranelift
-#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
-#cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
-#cranelift-module = { path = "../wasmtime/cranelift/module" }
-#cranelift-native = { path = "../wasmtime/cranelift/native" }
-#cranelift-jit = { path = "../wasmtime/cranelift/jit" }
-#cranelift-object = { path = "../wasmtime/cranelift/object" }
+cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
+cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
+cranelift-module = { path = "../wasmtime/cranelift/module" }
+cranelift-native = { path = "../wasmtime/cranelift/native" }
+cranelift-jit = { path = "../wasmtime/cranelift/jit" }
+cranelift-object = { path = "../wasmtime/cranelift/object" }

 #gimli = { path = "../" }
fn main() {
    std::env::args().collect::<Vec<_>>();
}

Expected Results

the binary executes successfully

Actual Results

Segmentation fault (core dumped)

Versions and Environment

Cranelift version or commit: e63771f2d921cdce440620dbf38bd3e186747b1e (latest commit on which the bug is reproduced) 05cbd667c7e89828a45ebc5760787a6160c55c8d (earliest commit on which the bug is reproduced)

Operating system: arch linux, kernel version 5.19.12-arch1-1

Architecture: x86_64

view this post on Zulip Wasmtime GitHub notifications bot (Oct 05 2022 at 11:08):

bjorn3 commented on issue #5018:

Yeah, found this issue already and told @cfallin about it. We haven't been able to find the problem yet. I have been able to reduce it to

<details>

#![feature(foo, allocator_api, new_uninit)]

use std::alloc::Global;
use std::collections::btree_map::{
    marker, DormantMutRef, Found, GoDown, Handle, Internal, Leaf, LeafNode, NodeRef,
    SearchResult::{self, *},
    VacantEntry,
};
use std::collections::BTreeMap;
use std::marker::PhantomData;
use std::mem::{ManuallyDrop, MaybeUninit};
use std::ptr::NonNull;

fn insert_entry(map: &mut BTreeMap<u32, u32>) {
    let node = NonNull::from(Box::leak({
        Box::new(LeafNode {
            parent: None,
            parent_idx: MaybeUninit::zeroed(),
            len: 1,
            keys: [MaybeUninit::zeroed(); 11],
            vals: [MaybeUninit::zeroed(); 11],
        })
    }));
    let _ =
        NodeRef::<marker::Mut, u32, u32, marker::Leaf> { height: 0, node, _marker: PhantomData }
            .node
            .as_ptr();
    map.root = Some(NodeRef { height: 0, node, _marker: PhantomData });
    map.length = 1;
}

fn search_tree<'a>(
    root: NodeRef<marker::Mut<'a>, u32, u32, marker::LeafOrInternal>,
    key: &'a u32,
) -> SearchResult<marker::Mut<'a>, u32, u32, marker::LeafOrInternal, marker::Leaf> {
    root.search_tree(&0xf00fbaabu32)
}

fn search_and_match(root: NodeRef<marker::Mut, u32, u32, marker::LeafOrInternal>) {
    match search_tree(root, &0xf00fbaabu32) {
        Found(_handle) => panic!(),
        GoDown(_handle) => panic!(),
    }
}

fn main() {
    println!("running");

    let mut btree_map =
        BTreeMap { root: None, length: 0, alloc: ManuallyDrop::new(Global), _marker: PhantomData };

    insert_entry(&mut btree_map);

    search_and_match(btree_map.root.as_mut().unwrap().borrow_mut());

    println!("success!");
}

</details>

with the crash happening at match search_tree(root, &0xf00fbaabu32) { after making several things in liballoc public. I've also been able to bisect it to the part of https://github.com/bytecodealliance/wasmtime/commit/05cbd667c7e89828a45ebc5760787a6160c55c8d that starts to actually use register constraints instead of pinned registers. By the way this huge reproducer is based on inlining several layers deep in

fn main() {
    let mut map = std::collections::BTreeMap::new();
    map.insert("a", "b");
    map.insert("c", "d");
}

and removing dead code.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 05 2022 at 11:10):

bjorn3 commented on issue #5018:

I found the issue as cg_clif's CI tests with cranelift main every day. Most of the time it breaks because of api changes requiring changes to cg_clif, but sometimes it breaks due to a genuine bug like this one. In any case thanks for taking the time to test cg_clif.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 07 2022 at 00:14):

cfallin closed issue #5018:

this is a miscompilation of rust code, compiled with rustc cranelift backend.

i identified the cause to be commit 05cbd667c7e89828a45ebc5760787a6160c55c8d. before the commit the same code runs as expected and afterwards there is a segfault

.clif Test Case

i tried to produce a .clif file but because the problem is not a crash during compilation, clif-util bugpoint cant be used,
tried using --emit llvm-ir to get the clif generated by rustc, but i couldn't produce a binary from them to see if it causes a segfault.

@bjorn3 if you know how to get a usable .clif file from the backend for this scenario, please let me know

Steps to Reproduce

diff --git a/Cargo.toml b/Cargo.toml
index 09cf5b4..d20efb2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,12 +8,12 @@ crate-type = ["dylib"]

 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { version = "0.88.1", features = ["unwind", "all-arch"] }
-cranelift-frontend = "0.88.1"
-cranelift-module = "0.88.1"
-cranelift-native = "0.88.1"
-cranelift-jit = { version = "0.88.1", optional = true }
-cranelift-object = "0.88.1"
+cranelift-codegen = { version = "0.89.0", features = ["unwind", "all-arch"] }
+cranelift-frontend = "0.89.0"
+cranelift-module = "0.89.0"
+cranelift-native = "0.89.0"
+cranelift-jit = { version = "0.89.0", optional = true }
+cranelift-object = "0.89.0"
 target-lexicon = "0.12.0"
 gimli = { version = "0.26.0", default-features = false, features = ["write"]}
 object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
@@ -26,12 +26,12 @@ smallvec = "1.8.1"

 [patch.crates-io]
 # Uncomment to use local checkout of cranelift
-#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
-#cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
-#cranelift-module = { path = "../wasmtime/cranelift/module" }
-#cranelift-native = { path = "../wasmtime/cranelift/native" }
-#cranelift-jit = { path = "../wasmtime/cranelift/jit" }
-#cranelift-object = { path = "../wasmtime/cranelift/object" }
+cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
+cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
+cranelift-module = { path = "../wasmtime/cranelift/module" }
+cranelift-native = { path = "../wasmtime/cranelift/native" }
+cranelift-jit = { path = "../wasmtime/cranelift/jit" }
+cranelift-object = { path = "../wasmtime/cranelift/object" }

 #gimli = { path = "../" }
fn main() {
    std::env::args().collect::<Vec<_>>();
}

Expected Results

the binary executes successfully

Actual Results

Segmentation fault (core dumped)

Versions and Environment

Cranelift version or commit: e63771f2d921cdce440620dbf38bd3e186747b1e (latest commit on which the bug is reproduced) 05cbd667c7e89828a45ebc5760787a6160c55c8d (earliest commit on which the bug is reproduced)

Operating system: arch linux, kernel version 5.19.12-arch1-1

Architecture: x86_64


Last updated: Oct 23 2024 at 20:03 UTC