-
Notifications
You must be signed in to change notification settings - Fork 167
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
Read access violation when refreshing SubscriptionSet #2952
Comments
Do you have a full stacktrace of this failure? |
➤ Jonathan Reams commented: [~daniel.tabacaru], can you take a look at this with [~ferdinando.papale] ? |
➤ Daniel Tabacaru commented: [~jonathan.reams] I'm looking into it. |
@danieltabacaru I'm not feeling really well, but the failing test is here (#2797). Feel free to take it with someone else of the .NET team, they should be able to run it with you. |
@papafe No worries |
Okay, so this turned out to be a combination of 2 bugs.
The reason for 2. manifesting here is that we were hitting a timeout due to 1., which fails the test, then we would close all Realm instances created during the test, triggering 2. A pseudocode repro case for 2, should be something like: auto realm = Realm::get_shared_realm(config);
auto subs = realm.get_latest_subscription_set();
realm.close();
// this should crash as `m_mgr` should have been invalidated
subs.refresh(); |
Are we safe to close this then? |
The second bug is a core bug. We should either change |
I'm still able to reproduce the access violation crash. This is the .NET test: var testGuid = Guid.NewGuid();
Task waitTask = null;
using (var realm = await GetFLXIntegrationRealmAsync())
{
realm.Subscriptions.Update(() =>
{
var query = realm.All<SyncAllTypesObject>().Where(o => o.GuidProperty == testGuid);
realm.Subscriptions.Add(query);
});
waitTask = realm.Subscriptions.WaitForSynchronizationAsync();
}
await waitTask; This roughly translates into: auto realm = Realm::get_shared_realm(config);
auto subs = realm.get_latest_subscription_set();
subs.update(...);
subs->get_state_change_notification(SubscriptionSet::State::Complete)
.get_async([task_completion_source, subs](StatusWith<SubscriptionSet::State> status) mutable noexcept {
// this crashes as `m_mgr` has been invalidated
subs->refresh();
});
realm.close(); |
➤ Jonathan Reams commented: in your example
|
Apologies, I translated the C# code too sloppily. // replace subs.update with below
auto mut_subs = subs.make_mutable_copy();
mut_subs.insert_or_assign(query);
subs = std::move(mut_subs).commit();
subs->get_state_change_notification(...); So yes, I'm reassigning subs to the return value of |
➤ Jonathan Reams commented: and does the |
➤ Daniel Tabacaru commented: [~nikola.irinchev@mongodb.com] do you have a stracktrace? |
Apologies for the delay here - I've been swamped with other stuff, so didn't have time to come back to this. Here's the stacktrace
So I think this may be due to the design of the .NET SDK. My overly simplified translation is missing key details. In reality, we're using pointers, not values and when the Realm gets closed, we delete the pointer to the subscriptions. I guess a more realistic translation would be: auto realm = Realm::get_shared_realm(config);
auto subs = new SubscriptionSet(realm.get_latest_subscription_set());
auto mut_subs = subs.make_mutable_copy();
mut_subs.insert_or_assign(query);
subs = new SubscriptionSet(std::move(mut_subs).commit());
subs->get_state_change_notification(SubscriptionSet::State::Complete)
.get_async([task_completion_source, subs](StatusWith<SubscriptionSet::State> status) mutable noexcept {
// subs here seems to be pointing to garbage data
subs->refresh();
});
realm.close();
delete subs; So as far as I can tell, this is a bug in the .NET wrapper code and not in Core. I'll try and investigate more with @fealebenpae and will get back to you if anything from Core is needed. |
We are getting a "Read access violation" in here:
https://github.com/realm/realm-core/blob/6b05da97d0a9bd0bf61522a0342222443b35e196/src/realm/sync/subscriptions.cpp#L708
when refreshing the
SubscriptionSet
(line 335) in the callback ofget_state_change_notification
:realm-dotnet/wrappers/src/subscription_set_cs.cpp
Lines 329 to 350 in db0d902
This happens only when previously we committed an empty write to the
SubscriptionSet
. By "empty", I mean that no query was added or removed, so the refresh should probably be a no-op.The text was updated successfully, but these errors were encountered: