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

Make context current when dropping glow::Context to allow for debug callback cleanup #6114

Merged
merged 1 commit into from
Aug 27, 2024

Conversation

Imberflur
Copy link
Contributor

@Imberflur Imberflur commented Aug 14, 2024

Description

Previously when running tests via cargo xtask test, I noticed some of the tests randomly segfaulting on opengl. This was due to the debug message callback running after its state was freed when glow::Context is dropped (i.e. an instance of grovesNL/glow#270).

The latest version of glow fixes this by clearing the debug message callback in its Drop impl. This requires the context to be current when dropping glow::Context (which is now documented in https://docs.rs/glow/0.14.0/glow/trait.HasContext.html#safety).

This PR adds some logic to make the context current when the glow::Context will be dropped and utilizes ManuallyDrop to control specifically when the drop occurs as well as preventing accidental drops from unwinding.

Presumably the context is always current for gles/web.rs?

Testing

Running cargo xtask test on a Linux machine.

Unfortunately in the latest version of wgpu, I'm not able to reproduce this segfault by running the tests, probably due to timing changes. So it is hard to confirm that this is fixing things. But it should theoretically be correct and my previous experimentation showed this fixing the bug.

Checklist

  • Run cargo fmt.
  • Run cargo clippy. If applicable, add:
    • --target wasm32-unknown-unknown
    • --target wasm32-unknown-emscripten
  • Run cargo xtask test to run tests.
  • Add change to CHANGELOG.md. See simple instructions inside file.

@Imberflur Imberflur requested a review from a team as a code owner August 14, 2024 05:59
@Imberflur Imberflur force-pushed the gl-context-current-drop branch 4 times, most recently from 8cf4091 to 5d781e8 Compare August 14, 2024 06:40
wgpu-hal/src/gles/egl.rs Outdated Show resolved Hide resolved
@Imberflur Imberflur force-pushed the gl-context-current-drop branch from 5d781e8 to b6103cb Compare August 14, 2024 06:52
Cleanup code in glow needs the context to be current (mainly for debug
message callbacks).

See https://docs.rs/glow/0.14.0/glow/trait.HasContext.html#safety
@Imberflur Imberflur force-pushed the gl-context-current-drop branch from b6103cb to 7969a50 Compare August 19, 2024 04:03
Copy link
Member

@cwfitzgerald cwfitzgerald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@cwfitzgerald
Copy link
Member

Presumably the context is always current for gles/web.rs?

Yeah there's no concept of non-current contexts

@cwfitzgerald cwfitzgerald merged commit fccd298 into gfx-rs:trunk Aug 27, 2024
25 checks passed
@Imberflur Imberflur deleted the gl-context-current-drop branch August 27, 2024 16:20
Comment on lines +1085 to +1086
// Avoid accidental drop when the context is not current.
let gl = ManuallyDrop::new(gl);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a stale comment? You're not avoiding a drop when the context is not current, instead you're forcing it to be current Before dropping.

Copy link
Contributor Author

@Imberflur Imberflur Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is noting the reason to wrap in ManuallyDrop before calling unmake_current on the line below. This prevents the glow::Context from being dropped if there is some panic between when we call unmake_current and when gl is placed into the AdapterContext (where the drop impl will handle making the context current before dropping glow::Context).

FWIW the comment could probably be clarified.

Copy link
Contributor

@MarijnS95 MarijnS95 Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarification is happening in #6152 where I ran into a few conflicts with this PR. Panics (except inside the drop handler) should still cause Drop to be called while unwinding. I'll add a mention that the only skipped case is between let gl and when Self {} is finally constructed.

Fwiw when a debug callback is specified by the user (in this case wgpu), it's common to skip messages when panicking:

if thread::panicking() {
return vk::FALSE;
}

Not sure if that can be done in EGL/WGL as well? Otherwise it seems this solution is a litle bit overengineered if it's just about making the context current in drop()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Panics (except inside the drop handler) should still cause Drop to be called while unwinding

Yes, this is why it needs to be wrapped in ManuallyDrop in the intermittent time before AdapterContext is constructed since panics would drop the glow::Context which could lead to UB if it isn't current.

Fwiw when a debug callback is specified by the user (in this case wgpu), it's common to skip messages when panicking:

Something like this won't help here with the way the Drop impl for glow::Context works, by the time the callback is invoked there is already UB.

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

Successfully merging this pull request may close these issues.

3 participants