Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exit code 11 (segfault?) when converting a java class to a JObject #13

Open
theoparis opened this issue Feb 14, 2022 · 3 comments
Open
Labels
bug Something isn't working

Comments

@theoparis
Copy link

So I have this java class binded through rust:

    #[derive(Signature, TryIntoJavaValue, IntoJavaValue, TryFromJavaValue)]
    #[package(com.theoparis.elementalbridge.core)]
    pub struct Item<'env: 'borrow, 'borrow> {
        #[instance]
        raw: AutoLocal<'env, 'borrow>,
        #[field]
        pub id: Field<'env, 'borrow, String>,
        #[field]
        pub name: Field<'env, 'borrow, String>,
    }

    impl<'env: 'borrow, 'borrow> Item<'env, 'borrow> {
        #[constructor]
        pub extern "java" fn new(
            env: &'borrow JNIEnv<'env>,
            id: String,
            name: String,
        ) -> JniResult<Self> {
        }
    }

And I have a rust function that needs to convert the Item struct to a JObject so it can be used in another struct method (that I'm using to "register the item").

pub fn register_item<'a>(ctx: &ModContext<'a>, mod_info: ModInfo, item: &Item) {
    let registry =
        Registry::new(ctx.jni, mod_info.id, "item".to_string()).unwrap();

    let java_item =
        crate::jni::Item::new(ctx.jni, item.id.clone(), item.name.clone())
            .unwrap();

    debug!("Registering item: {}", item.name);

    let java_obj =
        robusta_jni::convert::IntoJavaValue::into(java_item, ctx.jni);
    debug!("Java object: {:?}", java_obj);
    registry.register(ctx.jni, java_obj).unwrap();
    info!("Registered item: {}", item.name);
}

It does print the registering item message, but then after a second or two the whole java process crashes with exit code 11 - which I'm assuming is a segmentation fault since im on linux.

Any ideas as to why this could be happening? There isn't a discussions page so I assumed creating an issue would be the best place to get help...

@giovanniberti giovanniberti added the bug Something isn't working label Feb 14, 2022
@giovanniberti
Copy link
Owner

There isn't a discussions page so I assumed creating an issue would be the best place to get help...

It seems like a bug, so issues are definitely the best place!

First of all could you try to use TryIntoJavaValue instead and unwrap? This way rust generates a panic (if it's a problem from Rust) and we can inspect the backtrace (make sure to have the environment variable RUST_BACKTRACE set to 1)

@uvlad7
Copy link
Contributor

uvlad7 commented Jan 14, 2024

I reproduced this problem when tried to pass User struct as an argument in tests to check its signature.

Initialized env logger with level: info
error: test failed, to rerun pass `--test mod`

Caused by:
  process didn't exit successfully: `/home/vladimir/robusta/target/debug/deps/mod-f46496b2644f0906 --test-threads=1` (signal: 11, SIGSEGV: invalid memory reference)

uvlad7 added a commit to uvlad7/robusta that referenced this issue Jan 14, 2024
@uvlad7
Copy link
Contributor

uvlad7 commented Jan 16, 2024

So, it appears to be a stack overflow. This is how that TryIntoJavaValue derive expands:

    #[automatically_derived]
    impl<'env: 'borrow, 'borrow> ::robusta_jni::convert::TryIntoJavaValue<'env>
    for User<'env, 'borrow> {
        type Target = ::robusta_jni::jni::objects::JObject<'env>;
        fn try_into(
            self,
            env: &::robusta_jni::jni::JNIEnv<'env>,
        ) -> ::robusta_jni::jni::errors::Result<Self::Target> {
            ::robusta_jni::convert::TryIntoJavaValue::try_into(self, env)
        }
    }
    #[automatically_derived]
    impl<'env: 'borrow, 'borrow> ::robusta_jni::convert::TryIntoJavaValue<'env>
    for &User<'env, 'borrow> {
        type Target = ::robusta_jni::jni::objects::JObject<'env>;
        fn try_into(
            self,
            env: &::robusta_jni::jni::JNIEnv<'env>,
        ) -> ::robusta_jni::jni::errors::Result<Self::Target> {
            Ok(self.raw.as_obj())
        }
    }
    #[automatically_derived]
    impl<'env: 'borrow, 'borrow> ::robusta_jni::convert::TryIntoJavaValue<'env>
    for &mut User<'env, 'borrow> {
        type Target = ::robusta_jni::jni::objects::JObject<'env>;
        fn try_into(
            self,
            env: &::robusta_jni::jni::JNIEnv<'env>,
        ) -> ::robusta_jni::jni::errors::Result<Self::Target> {
            ::robusta_jni::convert::TryIntoJavaValue::try_into(self, env)
        }
    }

I just copy-pasted it and debugger stuck on the first conversion
Screenshot from 2024-01-16 02-59-33
Screenshot from 2024-01-16 02-59-45

And then I replaced it with Ok(self.raw.as_obj()) and tests passed, both in embedded java in tests/mod.rs and inside a "jni" method called from java

        pub extern "jni" fn getInt(self, _env: &JNIEnv, v: i32) -> i32 {
            User::selfSignatureCheck(&_env,self).expect("selfSignatureCheck failed");
            v
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants