renderdoc-rs icon indicating copy to clipboard operation
renderdoc-rs copied to clipboard

Cannot load renderdoc on Linux

Open yshui opened this issue 1 year ago • 3 comments

this crate calls libloading::open with RTLD_NOLOAD, which causes the dlopen call to return NULL, which libloading interprets as an error.

yshui avatar Mar 31 '23 08:03 yshui

Thanks for reporting, @yshui! Are you launching the application within RenderDoc when seeing this error, by chance? The use of RTLD_NOLOAD when loading the renderdoc shared object here is intentional (see #128).

ebkalderon avatar Apr 25 '23 18:04 ebkalderon

I see, then I wasn't using the api how it's intended to be used.

I think the example in the readme is probably a little misleading? as it does RenderDoc::new().expect(), which means it only works when launched by renderdoc?

Also, is it possible to provide an API that always succeeds and does nothing when the application is not launched by renderdoc?

yshui avatar Apr 28 '23 04:04 yshui

Apologies for the delayed response, @yshui! Indeed, the current README is misleading at the moment, and this is a known issue. A full rewrite of this crate is in progress over at issue #138, with a particular focus on both safety and ergonomics. Comments and/or suggestions on that ticket are welcome! The work-in-progress rewrite branch associated with said ticket also contains a DESIGN.md containing informal notes as I sketch out the new API.

This task may time to complete, unfortunately, as I'm working on renderdoc and renderdoc-sys in my free time. With that said, there are a few temporary workarounds which may satisfy your needs in the short term. One possible approach is to continue to use RenderDoc::new().expect(...) as before, but guard each use of the renderdoc API behind an off-by-default Cargo feature flag, e.g. #[cfg(feature = "debug-with-renderdoc")].

Granted, some uses cannot reasonably accommodate recompiling the application before debugging, and run-time fallback when the application is not launched by RenderDoc is preferred. In this case, a different workaround might be to instead work with a Result<RenderDoc<V>, Error> value instead of using .expect(), checking whether the API loaded successfully using if let or combinators at various points as necessary. For example:

let mut renderdoc: Result<RenderDoc<V110>, _> = RenderDoc::new();

if let Ok(rd) = renderdoc.as_mut() {
    let (major, minor, patch) = rd.get_api_version();
    assert_eq!(major, 1u32);
    assert!(minor >= 1u32);
}

If all else fails, and the current outdated API of renderdoc is not useful for your application, it should be possible to write your own bespoke safe wrapper around the low-level renderdoc-sys crate directly, until the new and improved renderdoc API lands upstream. Hope you find this helpful! :heart:

ebkalderon avatar May 10 '23 01:05 ebkalderon