-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
WASM C APIs need a rooting audit #61008
Comments
Tagging subscribers to 'arch-wasm': @lewing Issue DetailsDescriptionWe pass lots of bare managed pointers to the C APIs from JavaScript, and we don't always root those pointers. Up until this point we've been operating on the assumption that the pointer is properly rooted once it enters the runtime, but I realized that the GC can't actually reach function locals/parameters, so that may not actually be true. I expect handle-based functions are fine since they do explicit lifetime management, but almost all the stuff we call from JS doesn't use handles. We manually root things appropriately in some cases, but I think we're probably doing the wrong things in others (for example, call_method takes a raw managed pointer for 'this'.) Reproduction StepsN/A Expected behaviorN/A Actual behaviorN/A Regression?N/A Known WorkaroundsN/A ConfigurationN/A Other informationN/A
|
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
@vargaz @lambdageek (tag someone else if you think they're a better person to ask) do you know if there's a straightforward way for us to ensure all the managed pointers that hit C are reachable by the GC? Worst case, we can root them all in JS first. |
I thought that in the single-threaded runtime we only kick off a GC when there's nothing on the C stack (ie we explicitly run the GC when we return to the JS event loop). In the multi-threaded runtime I don't think we'd be able to make the same guarantee. So there we would need to ensure that all managed pointers are visible. Do we control all the JS-to-C entrypoints? |
This hasn't been true for a while runtime/src/mono/wasm/runtime/driver.c Line 1171 in 76e68db
cc @vargaz |
That's more or less what coop handles do. So my advice would be to use handles. See, for example runtime/src/mono/mono/metadata/object.c Lines 170 to 175 in 7144c2f
Essentially you'd do:
(note that nowadays you don't really need to pass the |
OK, so if we make sure every function exposed to JS uses handles internally, we can safely pass object pointers in. That sounds reasonable. |
@lambdageek so after messing around with this, one obstacle seems to be that handles aren't exposed to wasm code (driver.c), much like some other internals. Is there a straightforward way for me to address this - just add handle.h to a list somewhere? It seems like handle.h touches other stuff that is also internal and I don't have a good understanding of our internal/external header situation when it comes to handles, I would have expected them to be available. |
@lambdageek, @lewing, does any of you have a clue how to help with exposing handlers? |
@ilonatommy We're now using a slightly different plan - with @kg. There are three things that we're doing for the mono native-to-JS APIs:
The goal of this issue is to look at all the functions in |
We have some stop-gap functions with We need to discuss the remaining scenarios, where we still need to expose things like |
I believe we have comprehensively audited and revised things on our end at this point, the only remaining task is to ensure that downstream users like Blazor, Uno, etc have migrated. |
We pass lots of bare managed pointers to the C APIs from JavaScript, and we don't always root those pointers. Up until this point we've been operating on the assumption that the pointer is properly rooted once it enters the runtime, but I realized that the GC can't actually reach function locals/parameters, so that may not actually be true.
I expect handle-based functions are fine since they do explicit lifetime management, but almost all the stuff we call from JS doesn't use handles. We manually root things appropriately in some cases, but I think we're probably doing the wrong things in others (for example, call_method takes a raw managed pointer for 'this'.)
The text was updated successfully, but these errors were encountered: