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

Thread panicks when filter is used inside C code #23

Closed
qezz opened this issue Nov 8, 2017 · 9 comments
Closed

Thread panicks when filter is used inside C code #23

qezz opened this issue Nov 8, 2017 · 9 comments

Comments

@qezz
Copy link

qezz commented Nov 8, 2017

I want to use rsaudioecho filter in C code (is it even possible?), but it panicks at gst_init() if GST_PLUGIN_PATH is specified

(macOS Sierra 10.12.6, Xcode 8.3.3 (8E3004b), clang-802.0.42, rustc 1.23.0-nightly, cargo 0.24.0-nightly, GStreamer 1.12.3)

int main(int argc, char *argv[]) {
    setenv("RUST_BACKTRACE", "1", 1);
    setenv("GST_PLUGIN_PATH","/Users/username/sources/gstreamer/gst-plugin-rs",1);

    /* Initialize GStreamer */
    gst_init (&argc, &argv);

    return 0;
}

output:

thread '<unnamed>' panicked at 'assertion failed: ::types::instance_of::<Self>(ptr as *const _)', /Users/username/.cargo/git/checkouts/gstreamer-rs-8719441e7bb90fbc/2f7ee30/gstreamer/src/auto/plugin.rs:14:0
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:69
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:381
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:397
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:577
   5: std::panicking::begin_panic
             at /Users/travis/build/rust-lang/rust/src/libstd/panicking.rs:538
   6: <gstreamer::auto::plugin::Plugin as glib::translate::FromGlibPtrBorrow<*mut gstreamer_sys::GstPlugin>>::from_glib_borrow
             at /Users/username/sources/gstreamer/gst-plugin-rs/gst-plugin-audiofx/<panic macros>:3
   7: glib::translate::from_glib_borrow
             at /Users/username/.cargo/git/checkouts/glib-928cf7b282977403/a51dc67/src/translate.rs:825
   8: gstrsaudiofx::plugin_desc::plugin_init_trampoline
             at /Users/username/sources/gstreamer/gst-plugin-rs/gst-plugin-audiofx/<plugin_define macros>:24
   9: gst_plugin_register_func
  10: _priv_gst_plugin_load_file_for_registry
  11: exchange_packets
  12: _gst_plugin_loader_client_run
  13: main
fatal runtime error: failed to initiate panic, error 5
Program ended with exit code: 9

BTW, rsaudioecho works well with gst-launch-1.0 and gst-inspect-1.0

@sdroege
Copy link
Owner

sdroege commented Nov 8, 2017

Thanks for the report. This is indeed supposed to be possible. gst-launch-1.0 is not doing anything different than what your code is doing. Which makes it even more mysterious why it is failing with your code.

Basically the problem here is that the plugin pointer here is not a GstPlugin:

unsafe extern "C" fn plugin_init_trampoline(plugin: *mut $crate::gst_ffi::GstPlugin) -> $crate::glib_ffi::gboolean {
super::$plugin_init(&from_glib_borrow(plugin)).to_glib()
}

Maybe it is NULL, maybe something completely different. It really shouldn't though.

Can you add this at the top of the function and give the output before it panics?

println!("{:?}", plugin);
let type_ = from_glib(*(plugin as *const *const glib_sys::GType));
println!("{:?}", type_);

@qezz
Copy link
Author

qezz commented Nov 9, 2017

update: The problem is on my side (since I've managed to create an rsaudioecho element on Linux host, but not on the mac); sorry for worrying.

So, I think it's OK to close this issue.

It was confusing to be able to use the custom plugins with rust, and failing with C; but at the same time gst-launch manages to find them fine. The thoughts below are just FYI.


I have managed to compile it with

unsafe extern "C" fn plugin_init_trampoline(plugin: *mut $crate::gst_ffi::GstPlugin) -> $crate::glib_ffi::gboolean {
    println!("{:?}", plugin);
    let type_: Type = from_glib((*(plugin as *const *const $crate::glib_ffi::GType)) as $crate::glib_ffi::GType);
    println!("{:?}", type_);
    super::$plugin_init(&from_glib_borrow(plugin)).to_glib()
}

Sidenote:

Without as GType cast, it fails to compile with an error the trait glib::translate::FromGlib<*const usize> is not implemented for...

so I have found possible types in FromGlib crate docs and cast it to u32 (not sure if it is correct)


... and got

0x102804180
thread '<unnamed>' panicked at 'assertion failed: !ptr.is_null()', /Users/username/.cargo/git/checkouts/glib-928cf7b282977403/a51dc67/src/translate.rs:855:8
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::_print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: std::panicking::rust_panic_with_hook
   5: std::panicking::begin_panic
   6: <alloc::string::String as glib::translate::FromGlibPtrNone<*const i8>>::from_glib_none
   7: glib::translate::from_glib_none
   8: glib::types::Type::name
   9: <glib::types::Type as core::fmt::Debug>::fmt
  10: core::fmt::write
  11: <std::io::stdio::Stdout as std::io::Write>::write_fmt
  12: std::io::stdio::_print
  13: gstrsaudiofx::plugin_desc::plugin_init_trampoline
  14: gst_plugin_register_func
  15: _priv_gst_plugin_load_file_for_registry
  16: exchange_packets
  17: _gst_plugin_loader_client_run
  18: main
fatal runtime error: failed to initiate panic, error 5

Therefore, I guess it is NULL for some reason;

@sdroege
Copy link
Owner

sdroege commented Nov 9, 2017

If it works on Linux but not on macOS, that's definitely a bug and one that has to be solved. Unfortunately I don't have access to a macOS machine myself currently (mine is waiting in a box somewhere to be set up again). I'll have to find remote access to one, or so :)

Thanks for the added output and sorry for missing that conversion is needed. That's unfortunately not too helpful either, it basically means that we get some random pointer there as plugin. It's not NULL but it's also no pointer to any GObject.

@qezz Do you maybe have multiple versions of GObject on your system, and your C application, GStreamer and/or the Rust plugin are linking to different ones?

@sdroege
Copy link
Owner

sdroege commented Nov 9, 2017

@qezz How did you install GStreamer btw, and do you have multiple installations on your system (e.g. homebrew and from the GStreamer binaries)?

@superdump
Copy link

I installed GStreamer 1.12.3 from homebrew and gst-plugin-rs from master, just running cargo build. Then I added includes for stdlib.h and gst/gst.h to the program in the first post and built it with clang -o issue23 issue23.c -Wall -O0 -g $(pkg-config --cflags --libs gstreamer-1.0).

On macOS 10.13.1 (17B48), Xcode Version 9.1 (9B55), clang Apple LLVM version 9.0.0 (clang-900.0.38), GStreamer 1.12.3 from homebrew, cargo 0.22.0 (3423351a5 2017-10-06), rustc 1.21.0 (3b72af97e 2017-10-09).

@superdump
Copy link

Oh, and: setenv("GST_PLUGIN_PATH","/Users/robertsw/src/gst-plugin-rs/target/debug",1); - I pointed GST_PLUGIN_PATH explicitly to where the .dylib files are.

@sdroege
Copy link
Owner

sdroege commented Nov 9, 2017

@qezz Maybe you can also run otool -L on a) the plugin (libgstrsaudiofx.dylib), and b) your application, and paste the output of both here?

@qezz
Copy link
Author

qezz commented Nov 9, 2017

do you have multiple installations on your system

There is some mess with Gstreamer development package for mac, so yes, I definitely have.

However, both versions are 1.12.3

otool

# rust plugin
$ otool -L target/debug/libgstrsaudiofx.dylib
target/debug/libgstrsaudiofx.dylib:
	/Users/username/sources/gstreamer/gst-plugin-rs/target/debug/deps/libgstrsaudiofx.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/local/opt/gst-plugins-base/lib/libgstaudio-1.0.0.dylib (compatibility version 1204.0.0, current version 1204.0.0)
	/usr/local/opt/gstreamer/lib/libgstbase-1.0.0.dylib (compatibility version 1204.0.0, current version 1204.0.0)
	/usr/local/opt/gstreamer/lib/libgstreamer-1.0.0.dylib (compatibility version 1204.0.0, current version 1204.0.0)
	/usr/local/opt/glib/lib/libgobject-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.1.0)
	/usr/local/opt/glib/lib/libglib-2.0.0.dylib (compatibility version 5401.0.0, current version 5401.1.0)
	/usr/local/opt/gettext/lib/libintl.8.dylib (compatibility version 10.0.0, current version 10.5.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
	/usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)

# app
$ otool -L GStCxxDynPipe
GStCxxDynPipe:
	/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/GStreamer (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.5.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.50.2)

Does it mean that I have two different versions linked?

If yes, then I'm about to purge gstreamer and glib from the system, and install them again

@sdroege
Copy link
Owner

sdroege commented Nov 9, 2017

Yes, it's using different versions. GStCxxDynPipe uses the GStreamer binaries, libgstrsaudiofx.dylib uses the Homebrew binaries. If you load both in the same process, things will fall apart :)

You can keep both versions around, but it's dangerous and this might happen again. The only thing you need to do is to make sure that you use the same PKG_CONFIG_PATH for building the plugin as for your application (so that it links/uses the same GStreamer).

@sdroege sdroege closed this as completed Nov 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants