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

Clang Memory Leaks with ios_system #143

Open
fredldotme opened this issue Jul 8, 2023 · 5 comments
Open

Clang Memory Leaks with ios_system #143

fredldotme opened this issue Jul 8, 2023 · 5 comments

Comments

@fredldotme
Copy link

I'm currently embedding Clang the ios_system way inside of my app, though it seems to be the case that invoking clang or clang++ results in memory leaks.

  1. clang is not (by default) running with patches against it's default policy of "disabling free" and just "buries" pointers instead of freeing them.
  2. ios_system uses thread-local storage to point to stdin/out/err, but usage of thread-local storage might cause the ios_system Framework to not be unloaded as per Apple dyld's policy to not unload Frameworks which might use said thread-local storage. The specific reason is somewhere in their manpage, I'm sure.

The result of those two points is: Apps leak memory with every invocation of clang/clang++ for compiling or linking purposes.

clang also loves to spawn different "processes" (ie when linking objects and invoking "wasm-ld" when doing so) which might additionally cause recursiveness in (un)loading "programs" as Frameworks and confuse the dyld loader when attempting to unload them.

I'm not very sure how to proceed here. I would like to release my app with as few memleaks as possible, but it seems the only proper solution is fixing it in the dynamic library loader. On the one hand asking dyld folks to reconsider their default policy of not unloading thread-local-using Frameworks would help, but I'm not sure how much burden that is to them (and how responsive they would be through the right channels).

My question is: how can it be ensured that all consumers of ios_system with external tools like a custom clang can keep the memory footprint as low as possible?

@holzschu
Copy link
Owner

holzschu commented Jul 9, 2023

That is a generic issue (not just with clang), and I'd love to be able to solve it. Some commands, like Python, have existing cleanup code that is not activated by default but can be. clang is a lot more challenging, as you said. It's also more challenging because clang tends to launch other versions of clang, and cleaning up pointers too early in the process results in one of them accessing freed memory, and hence a crash (I tried).

The real problem is with clang (the leaks from ios_system are annoying but negligible, clang leaks are orders of magnitude larger). I don't think there is any chance of changing the behaviour of dyld. You can track memory leaks when running the app from inside Xcode, and see if there is a way to keep track of the pointers and free them. Another possibility would be to link with a specific malloc library, keep track of which iOS_system "process" allocates which block, and free these when the "process" ends, as part of cleanup_function. That would make things slower, but with fewer leaks.

@fredldotme
Copy link
Author

I have also succeeded in reducing memory leaks in Clang itself (can push the changes somewhere if you're interested), so no Clang/LLVM code wastes memory anymore (at least according to Instruments), the only problem is that after some attempts dyld now fails to load libLLVM because vm_allocate fails, so I'm not sure which component really is problematic still.

@fredldotme
Copy link
Author

Alright, so I have proof that dyld indeed needs some fixing for ios_system to shine, I'm sure it would warrant an Apple Radar.

I've created an alternative to ios_system called no_system which bypasses the dynamic linker by having everything built as a static library into the app itself. The result is such that memory leaks caused by failed unload attempts (should it be caused by objc frameworks or whatever) are gone.

https://github.com/fredldotme/no_system

Now it's not a full ios_system replacement, probably never will be and I'd really see ios_system itself get better here.

@holzschu
Copy link
Owner

iOS_system started with static libraries; the issue is that the binary quickly becomes very large (since you're loading every single command in memory).

@fredldotme
Copy link
Author

That doesn't address what I mean though. What I'm on about is that Apple needs to address this, either with our involvement, or they'll stay left in the dust and just not have professional workflows covered.

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

2 participants