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

Fix race condition in clang_macro_fallback #3111

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

HKalbasi
Copy link
Member

@HKalbasi HKalbasi commented Feb 2, 2025

Previously, bindgen by default used the same directory of the headers as the directory for temporary files of the clang_macro_fallback feature. Aside from its other problems like making temporary noises in git or failing to remove these files on failing or aborted builds, this caused a race condition in build of retina that I spend two DAYS to figure it out.

The problem is, if you run bindgen on the same set of files multiple times simultaneously (which happened in retina since a crate was included two times in the crate graph due different features, and it ran bindgen in its build script) one of them can remove clang_macro_fallback files of the other one and break it.

I fixed it by moving the files generated by clang_macro_fallback in a new temp directory each time bindgen is invoked.

@HKalbasi HKalbasi force-pushed the fix-race-condition branch 2 times, most recently from fabe930 to b002407 Compare February 2, 2025 22:30
@ojeda
Copy link
Contributor

ojeda commented Feb 4, 2025

Cc @jbaublitz since he is probably interested.

@jbaublitz
Copy link
Contributor

@HKalbasi You may want to base this PR on #3072 as that is the PR I put up to address some problems that @ojeda bumped into while using the clang fallback code.

@HKalbasi
Copy link
Member Author

HKalbasi commented Feb 7, 2025

I will do the rebase after your PR is merged so I don't have to rebase it multiple times in case your PR needs further changes, and to keep the diff clean if you or anyone else want to review it in the meantime.

@jbaublitz
Copy link
Contributor

@HKalbasi Okay, it looks like the PR got merged.

@HKalbasi
Copy link
Member Author

@jbaublitz What is your opinion on this PR?

@jbaublitz
Copy link
Contributor

@HKalbasi I'm not the maintainer so I'm not whether they're expecting concurrent builds or not. I'd assume they'd probably want to support that use case but you'd have to ask one of the maintainers.

As for my thoughts on this PR, I think this is one way to solve this problem and I'm not entirely against it but I noticed in your original statement of the issue that you mentioned that it makes temporary noise in git. This is the rationale for clang_macro_fallback_build_dir. Theoretically you should be able to not only point to a separate directory so that the temporary files don't show up anywhere in the git tree but I think on both the Rust and the bash side, it is possible to pass a separate temporary directory to each invocation of bindgen. This is an extra step that you address in this PR automatically but I'd want to hear @ojeda's opinion on whether taking control away from the user for where their temporary files are created is desirable. This may not play nicely with kernel stuff, I'm not sure.

@HKalbasi
Copy link
Member Author

The main problem this PR addresses is that if you run two instance of bindgen on the same set of files (which is easy with build scripts) you will get a hard to debug race condition on build with the default settings, and also with constant clang_macro_fallback_build_dir. If the kernel can't use the /tmp directory and needs clang_macro_fallback_build_dir I can add it again with a warn comment about this race condition.

@jbaublitz
Copy link
Contributor

@ojeda What do you think here? Is relying on /tmp when this will likely eventually be used for kernel builds doable? Based on all of the wide variety of environments in which kernel builds take place, I could imagine it not being available in some of them.

I can think of a few additional options we could also explore. For one, we could create a new randomized alphanumeric subdirectory under clang_macro_fallback_build_dir that would be distinct per invocation of bindgen. Namespacing the temporary files would likely solve this issue without needing to rely on /tmp.

@ojeda
Copy link
Contributor

ojeda commented Mar 13, 2025

In general, I would say not allowing to configure the folder for temporaries is not a good idea.

In the kernel, we create some temporary directories inside the build folder (which is configurable) rather than /tmp. On the other hand, some tools do attempt to create things in /tmp, and some even fail they are not allowed to, but as long as one configures $TMPDIR, the build seems to be intended to work even if /tmp is not accessible (e.g. I see a script allowing to customize it with $TMPDIR and I also tested a minimal kernel build without access to /tmp just to double-check).

So I would say allowing users to override the /tmp would be needed for the kernel or making bindgen respect e.g. $TMPDIR like GCC and Clang do (does tempfile support so already?).

See:

https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html#index-TMPDIR
https://clang.llvm.org/docs/CommandGuide/clang.html#envvar-TMPDIR-TEMP-TMP

@HKalbasi
Copy link
Member Author

does tempfile support so already?

tempfile uses std::env::temp_dir for finding the temp directory location, so indeed it does respect $TMPDIR.

I would say not allowing to configure the folder for temporaries is not a good idea.

Is $TMPDIR enough as a configuration, or do you prefer an explicit bindgen configuration for that?

@ojeda
Copy link
Contributor

ojeda commented Mar 14, 2025

If $TMPDIR works, then I think that should be good enough.

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