capy-language / capy

🍊 A statically typed, compiled programming language, largely inspired by Jai, Odin, and Zig.
Apache License 2.0
64 stars 4 forks source link

panic triggered in debug build when compiling some parts of core #20

Closed lenawanel closed 4 months ago

lenawanel commented 5 months ago

running the capy compiler compiled in debug mode on some files in core (currently I saw the behavior in core/fmt.capy, examples/io.capy, core/math.capy, core/meta.capy and core/strings.capy) will cause the compiler to panic in cranelift with

unsafe precondition(s) violated: ptr::copy_nonoverlapping requires that both pointer arguments are aligned and non-null and the specified memory ranges do not overlap

steps to reproduce

cargo run --bin capy -- build <one of the aforementioned files>

backtrace:

   0: rust_begin_unwind
             at /rustc/b1ec1bd65f89c1375d2cf2fb733a87ef390276d3/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_nounwind_fmt::runtime
             at /rustc/b1ec1bd65f89c1375d2cf2fb733a87ef390276d3/library/core/src/panicking.rs:110:18
   2: core::panicking::panic_nounwind_fmt
             at /rustc/b1ec1bd65f89c1375d2cf2fb733a87ef390276d3/library/core/src/panicking.rs:120:5
   3: core::panicking::panic_nounwind
             at /rustc/b1ec1bd65f89c1375d2cf2fb733a87ef390276d3/library/core/src/panicking.rs:219:5
   4: core::intrinsics::copy_nonoverlapping::precondition_check
             at /rustc/b1ec1bd65f89c1375d2cf2fb733a87ef390276d3/library/core/src/ub_checks.rs:68:21
   5: core::intrinsics::copy_nonoverlapping
             at /rustc/b1ec1bd65f89c1375d2cf2fb733a87ef390276d3/library/core/src/ub_checks.rs:75:17
   6: <cranelift_jit::backend::JITModule as cranelift_module::module::Module>::define_data
             at /home/lena/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-jit-0.104.3/src/backend.rs:881:26
   7: codegen::compiler::Compiler::compile_queued::define
             at ./crates/codegen/src/compiler/mod.rs:345:13
   8: codegen::compiler::Compiler::compile_queued
             at ./crates/codegen/src/compiler/mod.rs:476:13
   9: codegen::compiler::comptime::eval_comptime_blocks
             at ./crates/codegen/src/compiler/comptime.rs:145:5
  10: capy::compile_file
             at ./crates/capy/src/main.rs:426:5
  11: capy::main
             at ./crates/capy/src/main.rs:146:5
  12: core::ops::function::FnOnce::call_once
             at /rustc/b1ec1bd65f89c1375d2cf2fb733a87ef390276d3/library/core/src/ops/function.rs:250:5
lenawanel commented 5 months ago

This seems to be an issue with comptime in general, as even something like this:

a :: comptime { 2 };

main :: () {} 

will trigger the panic

lenawanel commented 5 months ago

running (building fmt.capy) under miri (requires commenting out the gcc linking step in codegen/src/lib.rs for cases where the error isn't hit) gives the following error:


·error: Undefined Behavior: out-of-bounds pointer arithmetic: null pointer is a dangling pointer (it has no provenance)
   --> /home/lena/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-jit-0.104.3/src/memory.rs:162:32
    |
162 |             let ptr = unsafe { self.current.ptr.add(self.position) };
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: null pointer is a dangling pointer (it has no provenance)
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE:
    = note: inside `cranelift_jit::memory::Memory::allocate` at /home/lena/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-jit-0.104.3/src/memory.rs:162:32: 162:67
    = note: inside `<cranelift_jit::backend::JITModule as cranelift_module::module::Module>::define_data` at /home/lena/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-jit-0.104.3/src/backend.rs:863:13: 865:74
    = note: inside `codegen::compiler::Compiler::<'_>::compile_queued::define` at /home/lena/capy/crates/codegen/src/compiler/mod.rs:345:13: 346:52
    = note: inside `codegen::compiler::Compiler::<'_>::compile_queued` at /home/lena/capy/crates/codegen/src/compiler/mod.rs:476:13: 482:14
    = note: inside `codegen::eval_comptime_blocks` at /home/lena/capy/crates/codegen/src/compiler/comptime.rs:145:5: 145:30
note: inside `compile_file`
   --> crates/capy/src/main.rs:426:5
    |
426 | /     codegen::eval_comptime_blocks(
427 | |         if verbose >= 4 {
428 | |             Verbosity::AllFunctions
429 | |         } else {
...   |
438 | |         target.pointer_width().unwrap().bits(),
439 | |     );
    | |_____^
note: inside `main`
   --> crates/capy/src/main.rs:146:5
    |
146 | /     compile_file(
147 | |         file,
148 | |         contents,
149 | |         entry_point,
...   |
155 | |         &libs,
156 | |     )
    | |_____^
`` 
lenawanel commented 5 months ago

updating cranelift to 108 fixes the panic, but still has miri complaining:

error: Undefined Behavior: out-of-bounds pointer arithmetic: alloc337057 has size 4096, so
 pointer to 4 bytes starting at offset -4 is out-of-bounds
   --> /home/lena/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-jit-0.108.1/src/compiled_blob.rs:55:41
    |
55  | ...t = unsafe { base.offset(isize::try_from(addend).unwrap()) };
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: alloc337057 has size 4096, so pointer to 4 bytes starting at offset -4 is out-of-bounds
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
help: alloc337057 was allocated here:
   --> crates/capy/src/main.rs:426:5
    |
426 | /     codegen::eval_comptime_blocks(
427 | |         if verbose >= 4 {
428 | |             Verbosity::AllFunctions
429 | |         } else {
...   |
438 | |         target.pointer_width().unwrap().bits(),
439 | |     );
    | |_____^
    = note: BACKTRACE (of the first span):
    = note: inside `cranelift_jit::compiled_blob::CompiledBlob::perform_relocations::<{closure@cranelift_jit::backend::JITModule::finalize_definitions::{closure#0}}, {closure@cranelift_jit::backend::JITModule::finalize_definitions::{closure#1}}, {closure@cranelift_jit::backend::JITModule::finalize_definitions::{closure#2}}>` at /home/lena/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-jit-0.108.1/src/compiled_blob.rs:55:41: 55:86
    = note: inside `cranelift_jit::backend::JITModule::finalize_definitions` at /home/lena/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cranelift-jit-0.108.1/src/backend.rs:462:13: 466:14
    = note: inside `codegen::eval_comptime_blocks` at /home/lena/capy/crates/codegen/src/compiler/comptime.rs:163:5: 163:34
note: inside `compile_file`
   --> crates/capy/src/main.rs:426:5
    |
426 | /     codegen::eval_comptime_blocks(
427 | |         if verbose >= 4 {
428 | |             Verbosity::AllFunctions
429 | |         } else {
...   |
438 | |         target.pointer_width().unwrap().bits(),
439 | |     );
    | |_____^
note: inside `main`
   --> crates/capy/src/main.rs:146:5
    |
146 | /     compile_file(
147 | |         file,
148 | |         contents,
149 | |         entry_point,
...   |
155 | |         &libs,
156 | |     )
    | |_____^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
NotAFlyingGoose commented 4 months ago

I no longer find this when running

cargo run -- run core/src/*.capy --mod-dir=.

or

cargo run -- build core/src/*.capy --mod-dir=.

or when compiling examples/io.capy on the latest commit

This might've been fixed by the recent update to cranelift 0.109, since updating to 0.108 alleviated it