These are chat archives for rust-lang/rust

23rd
Aug 2018
Andrea Moretti
@axyz
Aug 23 2018 15:08
Hi, I'm facing a segfault when calling a C function from libvips. I tried all kind of magic with pointers, castings, forget, etc..., but I'm not sure what I'm doing wrong and would be great to understand what is going on under the hood.
let vector: Vec<u8> = unsafe {
            let mut result_size: usize = 0;
            let memory: *mut u8 = vips::vips_image_write_to_memory(
                self.img,
                &mut result_size as *mut usize,
            ) as *mut u8;
            // tried to put unimplemented!(); here and the segfault happen anyway
            let slice = slice::from_raw_parts_mut(memory, result_size);
            let boxed_slice: Box<[u8]> = Box::from_raw(slice);
            let vec = boxed_slice.into_vec();
            vec
        };
Zakarum
@omni-viral
Aug 23 2018 15:09
@axyz Box::from_raw seems wrong here
You can't call this function with arbitrary pointer/slice
It must be called only with pointer that you get from Box::into_raw
Andrea Moretti
@axyz
Aug 23 2018 15:12
@omni-viral I copied that part from https://github.com/elbaro/vips-rs/blob/master/src/image/mod.rs#L567 , but segfault is happening before that point on the image_write_to_memory part. Before trying out that snippet, I was trying to just do slice.to_vec(), would that work?
Zakarum
@omni-viral
Aug 23 2018 15:25
slice.to_vec() will work since it copies slice to new vec
Zakarum
@omni-viral
Aug 23 2018 15:32
So vips_image_write_to_memory segfaults?
Maybe use use it incorrectly :)
Andrea Moretti
@axyz
Aug 23 2018 15:35
@omni-viral https://jcupitt.github.io/libvips/API/current/VipsImage.html#vips-image-write-to-memory this is the API, I also tried using *mut c_void instead of *mut u8
Zakarum
@omni-viral
Aug 23 2018 15:38
I guess segfault happens in vips_image_write_to_memory itself
Maybe self.img is not valid?
Andrea Moretti
@axyz
Aug 23 2018 15:40
self.img is pub img: *mut vips::VipsImage
Zakarum
@omni-viral
Aug 23 2018 15:40
Yeah. But is it valid pointer to vips::VipsImage?
Andrea Moretti
@axyz
Aug 23 2018 15:46
@omni-viral you are right: If I read the image from file, it works. But if I generate it from an ImgVec<RGBA<f32>> it segfaults. comparing the resulting structs they seems ok, but probably something gets broken in the way, at least I have something else to investigate now. Thanks a lot
Zakarum
@omni-viral
Aug 23 2018 16:06
@axyz Note that documentation to vips_image_write_to_memory mention that you have to free memory returned
What function must be used for freeing is unknown to me
Andrea Moretti
@axyz
Aug 23 2018 16:22
@omni-viral you are right, vips::g_object_unref(memory as *mut c_void);, but now it segfaults again with it :) if to_vec() returns a copy it should be safe to erase memory right?
Farzeen
@happycoder97
Aug 23 2018 19:13
//  ../Cargo.toml
[package]
name = "rust_test"
version = "0.1.0"

[[test]]
name="simple_test"
path="src/test.rs"
harness=false

//  foo.rs
pub fn fn_to_test() {}

#[cfg(test)]
pub mod test {
    use utils;
    pub fn test() {
        utils::util_fn();
        super::fn_to_test();
    }
}

//  main.rs
mod foo; //if I comment this line, everything works fine.
fn main() {
}

//  test.rs
pub mod utils {
    pub fn util_fn() {}
}

mod foo;
fn main() {
    foo::test::test();
}

The above code builds successfully, but cargo test fails with the following error:

   Compiling rust_test v0.1.0 (file:///home/farzeen/rust_test)                                                                                                                                                                 
error[E0432]: unresolved import `utils`
 --> src/foo.rs:5:9
  |
5 |     use utils;
  |         ^^^^^ no `utils` in the root

Could anyone please explain what is wrong with the above code?

I just figured out that changing mod foo; in main.rs to #[cfg(not(test))] mod foo; fixes the problem. But I would like to have a better understanding :)
Jan Hlavatý
@hlavaatch
Aug 23 2018 19:33
its not utils kts test::utils
Lyle Mantooth
@IslandUsurper
Aug 23 2018 19:33
@happycoder97, I think perhaps cargo test also builds main.rs and not just test.rs. So main's foo doesn't know where utils is.
Azriel Hoh
@azriel91
Aug 23 2018 19:34

main.rs: mod foo;
test.rs: mod foo; mod utils { /* things */ }
foo.rs: use utils;

so, main.rs and test.rs are independent programs.
main.rs -> use foo;
foo.rs -> use utils; // where is it? compiler errors out

test.rs -> use foo; and also declare utils;
foo.rs -> use utils; // from test.rs

note: even if test.rs compiles, the code probably shouldn't be structured that way because test.rs depends on foo.rs, and foo.rs kind of depends on test.rs (cyclic)
Farzeen
@happycoder97
Aug 23 2018 19:37
That sounds reasonable @IslandUsurper and @azriel91

note: even if test.rs compiles, the code probably shouldn't be structured that way because test.rs depends on foo.rs, and foo.rs kind of depends on test.rs (cyclic)

Could you restructure the above code?

Azriel Hoh
@azriel91
Aug 23 2018 19:37
put the utils module in a separate file
Farzeen
@happycoder97
Aug 23 2018 19:38
Roger that @azriel91 :+1:
Azriel Hoh
@azriel91
Aug 23 2018 19:38
oh, just realized my reasoning wasn't sound
Lyle Mantooth
@IslandUsurper
Aug 23 2018 19:38
Don't use test.rs at all.
Azriel Hoh
@azriel91
Aug 23 2018 19:39
submodules have visibility of everything in the parent modules, so it's not "cyclic" the way i was imagining
Lyle Mantooth
@IslandUsurper
Aug 23 2018 19:39
I'm not sure why you're using harness=false, but the default way of doing tests in Rust is rather nice. You can put #[test] on pub fn test and it'll be run as a test.
Farzeen
@happycoder97
Aug 23 2018 19:39
@IslandUsurper I can't use normal test runner because it runs tests in different threads and I need to use gtk::init(), which can't be called from two different threads in a process
@azriel91 Yeah, but I got the idea :)
I really wish if there was a flag to run all tests on the main thread.
Lyle Mantooth
@IslandUsurper
Aug 23 2018 19:42
Do the tests themselves need to run gtk::init()? That sounds like something that should be in a setup step, and then the tests run. And I was describing how unit tests are run, which doesn't sound like what you want, now.
Azriel Hoh
@azriel91
Aug 23 2018 19:43
is main thread necessary, or is single thread good enough?
Farzeen
@happycoder97
Aug 23 2018 19:43
@IslandUsurper I was testing whether the views were calling corresponding controller methods. I thought they came under unit tests.
Lyle Mantooth
@IslandUsurper
Aug 23 2018 19:43
Usually, integration tests are made as separate crates that would do extern crate rust_test to load your main.rs in the test file. Declaring mod foo; in both files is what messed you up.
Farzeen
@happycoder97
Aug 23 2018 19:43
@azriel91 Yes. Single thread is fine
Azriel Hoh
@azriel91
Aug 23 2018 19:44
you could try cargo test -- --test-threads 1, if the gtk::init() call is tolerant of being called multiple times
Farzeen
@happycoder97
Aug 23 2018 19:45
@azriel91 It can't be called multiple times :(
Azriel Hoh
@azriel91
Aug 23 2018 19:45
if it's not tolerant, then you could do some weird Arc<Mutex<something>> thing which makes sure it's called once
Farzeen
@happycoder97
Aug 23 2018 19:45
Also, calls to gtk functions must happen on the same thread that called gtk::init(), iirc

if it's not tolerant, then you could do some weird Arc<Mutex<something>> thing which makes sure it's called once

That sounds possible. Let me try that :+1:

Azriel Hoh
@azriel91
Aug 23 2018 19:51

here's a lazy_static mutex, you might need a bool instead of () to store whether it's been called
https://github.com/azriel91/amethyst_test_support/blob/master/src/amethyst_application.rs#L74-L76

this wraps the assertion (note, you shouldn't have the thread wrapper, that's a different issue). When you get the mutex successfully then u can choose whether or not to gtk::init()
https://github.com/azriel91/amethyst_test_support/blob/master/src/amethyst_application.rs#L327-L342

gonna be (away) for a while
Farzeen
@happycoder97
Aug 23 2018 19:52
thanks @azriel91 :yellow_heart:
Azriel Hoh
@azriel91
Aug 23 2018 20:05
@happycoder97 see https://github.com/rust-lang/rust/issues/43155#issuecomment-315543432 for a version that doesn't poison the mutex
cradee
@cradee_gitlab
Aug 23 2018 20:10

Hi all!

I'm stuck with some simple issue in tokio.
In mio it's pretty straightforward using several io resources for combining them in one event loop. Something like:

    poll.register(resource1, token, ...);
    poll.register(resource2, token, ...);
    poll.register(resource3, token, ...);
    ...
    loop {
        poll.poll(events);

        for event in events {
            // perform some event
            ...
        }
        ...
    }

Аnd since tokio is based on mio, I believe that in it I can achieve the same. But I could not find examples of how to do it (examples from git repo didn't cover it, im guess). How to combine several resources in tokio (for example, udp soket and serialport) or i miss somehing conceptual and this isn't possible?
Please help!