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

Debugging an issue with GC seemingly not happening on Emscripten/WebAssembly #620

Open
juj opened this issue Feb 7, 2024 · 0 comments
Open

Comments

@juj
Copy link
Contributor

juj commented Feb 7, 2024

I have a scenario where memory is not being freed, and I am starting to suspect that this might be due to WebAssembly being 32-bit, and there being conservative false positive hits, or some other pathological behavior in my app that results in Boehm flagging the pointers to still be alive, or maybe a fragmentation related problem that causes an OOM.

To try to get a better sense of things, I have been looking to implement a memory trace mechanism into my local copy of Boehm. In this kind of memory trace, I'd like to call out from WebAssembly to JavaScript on every memory alloc and reclaim event. This would allow me to generate a visual map of all currently alive GC memory.

Annotating the allocation part is straightforward, and I am able to achieve it by adding a hook like

#ifdef __EMSCRIPTEN__
    EM_ASM({emscriptenMemoryProfiler.onManagedMalloc($0, $1)}, ptr, sz);
#endif

into the GC_malloc() family of functions. There each pointer ptr that points to start of usable payload of a piece of memory will then be reported out to a external widget on a HTML web page, that visualizes the linear memory map for all pointers and the call stacks that these pointers were allocated from.

I'd like to then symmetrically update the visualization map to clear up these pointers after the GC has reclaimed memory. However, given the pooled nature of the allocator, I am not sure how to do this in a fashion that would 100% encompass all kinds of payload pointers?

What I'd like to inject in somewhere suitable location would be a symmetric call to

#ifdef __EMSCRIPTEN__
    EM_ASM({emscriptenMemoryProfiler.onManagedFree$0)}, ptr);
#endif

where ptr would be the same pointer to payload memory as in malloc above, and the profiler would then know to erase the memory.

This way I think I would be able to keep an up to date visualization map of what managed pointers are allocated where, and it would allow me maybe to figure out if things aren't being reclaimed, or if my OOM might be caused by fragmentation, or something else.

Would there exist a suitable place where I could add these types of onManagedFree() calls? I see it would probably be somewhere in reclaim.c, though I don't have enough of a understanding on the structure of all the different functions to where that could be done, and my attempts may be lost on managing block headers vs user pointers?

Any tips would be welcome!

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

1 participant