On Fri, Sep 13, 2013 at 1:17 AM, Minh Do <m...@minhdo.org> wrote:

> On 08/27/2013 12:43 AM, Minh Do wrote:
>
>> My name is Do Nhat Minh, currently a final year Computer Science student
>> at Nanyang Technological University in Singapore. I have played with Rust
>> and found the experience to be very pleasant. I think Rust make sensible
>> trade-offs and managed to stay small, compared to C++.
>>
>> I have been granted permission by my university supervisor to work on
>> rusti as my final year project. I hope with this contribution, Rust will be
>> even stronger a competitor to Go and D.
>>
>> This will be my first time working on something this size and this long a
>> duration. I would love to hear your advice or experience implementing rusti.
>>
>> Thank you for your time.
>>
>> Regards,
>> Minh
>>
> Hi,
>
> I'm working on figuring out why rusti segfaults. So far, I'm able to
> extract very little information.
>
> Attached is a backtrace from rusti using gdb. SIGSEGV is signaled inside
> jemalloc's tcache_alloc_easy, line 286. Below is the piece code where it
> fails.
>
> 274    JEMALLOC_ALWAYS_INLINE void *
> 275    tcache_alloc_easy(tcache_bin_t *tbin)
> 276    {
> 277        void *ret;
> 278
> 279        if (tbin->ncached == 0) {
> 280            tbin->low_water = -1;
> 281            return (NULL);
> 282        }
> 283        tbin->ncached--;
> 284        if ((int)tbin->ncached < tbin->low_water)
> 285            tbin->low_water = tbin->ncached;
> 286        ret = tbin->avail[tbin->ncached]; // <- XXX fail here
> 287        return (ret);
> 288    }
>
> jemalloc is trying to read from tbin->avail at tbin->ncached.
> tbin->ncached was 1227353920 (or 0x4927ef40) which is too big in my
> opinion. All the other values in tbin were unusually high or low, which
> leads me to suspect tbin is uninitialized or there is a memory overrun.
>
> I run valgrind on rusti in the hope of catching memory overruns, but it
> does not help much. Valgrind only prints some warning about conditional
> jumps depending on uninitialized variables and then reports an invalid read
> with the identical backtrace. However, at the top, valgrind prints the
> below text, which I find quite interesting.
>
> ==31583== Syscall param read(buf) points to unaddressable byte(s)
> ==31583==    at 0x40170C7: read (in /usr/lib/ld-2.18.so)
> ==31583==    by 0x400586C: open_verify (in /usr/lib/ld-2.18.so)
> ==31583==    by 0x4005CA6: open_path (in /usr/lib/ld-2.18.so)
> ==31583==    by 0x4008495: _dl_map_object (in /usr/lib/ld-2.18.so)
> ==31583==    by 0x400C281: openaux (in /usr/lib/ld-2.18.so)
> ==31583==    by 0x400E773: _dl_catch_error (in /usr/lib/ld-2.18.so)
> ==31583==    by 0x400C4E4: _dl_map_object_deps (in /usr/lib/ld-2.18.so)
> ==31583==    by 0x4002E93: dl_main (in /usr/lib/ld-2.18.so)
> ==31583==    by 0x4015174: _dl_sysdep_start (in /usr/lib/ld-2.18.so)
> ==31583==    by 0x4004AE5: _dl_start (in /usr/lib/ld-2.18.so)
> ==31583==    by 0x4001277: ??? (in /usr/lib/ld-2.18.so)
> ==31583==  Address 0x7fec7f700 is on thread 1's stack
>
> I then try linking directly with Rust's libstd (since it's the first thing
> that's linked with the code being compiled) in rusti's main() before
> anything is done. Below is the addition.
>
> diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs
> index 8d61a97..2f72cfa 100644
> --- a/src/librusti/rusti.rs
> +++ b/src/librusti/rusti.rs
> @@ -84,6 +84,9 @@ use syntax::print::pprust;
>  use program::Program;
>  use utils::*;
>
> +use rustc::lib::llvm::llvm;
> +use std::unstable::intrinsics;
> +
>  mod program;
>  pub mod utils;
>
> @@ -505,6 +508,17 @@ pub fn main() {
>  pub fn main_args(args: &[~str]) {
>      #[fixed_stack_segment]; #[inline(never)];
>
> +    unsafe {
> +        let manager = llvm::LLVMRustPrepareJIT(**
> intrinsics::morestack_addr());
> +        let path = "/path/to/rust/x86_64-unknown-**
> linux-gnu/stage2/lib/rustc/**x86_64-unknown-linux-gnu/lib/l**
> ibstd-6c65cf4b443341b1-0.8-**pre.so<http://libstd-6c65cf4b443341b1-0.8-pre.so>
> ";
> +        do path.with_c_str |buf_t| {
> +            if !llvm::LLVMRustLoadCrate(**manager, buf_t) {
> +                debug!(~"Could not link");
> +            }
> +            debug!("linked: %s", path);
> +        }
> +    }
> +
>      let input = io::stdin();
>      let out = io::stdout();
>      let mut repl = Repl {
>
> Rusti now also fails in the scheduler sometimes if it happens to switch
> threads while LLVMRustLoadCrate is being executed. Below is the backtrace.
>
> #0  rust_thread_start (ptr=0x7ffff1c1f5e0) at
> src/rt/sync/rust_thread.cpp:36
> #1  0x00007ffff548b0a2 in start_thread () from /usr/lib/libpthread.so.0
> #2  0x00007ffff3217a2d in clone () from /usr/lib/libc.so.6
>
> The above failure in the scheduler and the curious message by valgrind
> makes me wonder about the scheduler and the runtime. However, when git
> grep-ing for rust_thread, I don't see how it is hooked into Rust. Could
> someone enlighten me on this?
>
> More importantly, does anyone have any suggestion about my approach or any
> leads on this?
>
> Regards,
> Minh
>

Compile jemalloc with --enable-debug (you can add it to rt.mk) and it will
check for things like double-free.
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to