microsoft/GraphEngine

System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'

TaviTruman opened this issue · 4 comments

            foreach (var userAuthenticationSessionDataNode in Global.LocalStorage.UserAuthenticationCache_Selector())
            {
                var userAuthInfoSetCellId = userAuthenticationSessionDataNode.CellId;
                var userAuthInfoSet = userAuthenticationSessionDataNode.UserAuthInfoSet;
            }

This is bad! I was only expecting a single cell here but the code stalls in the debugger and then I get the follwing error:

image

here is the preceeding code:

UserAuthenticationSessionData userAuthenticationSessionData = new UserAuthenticationSessionData()
{
AdalAuthority = authResult.Authority,
AuthExpireDateTimeStamp = authResult.ExpiresOn.DateTime,
ClientAppId = config.clientId,
GraphServiceClientEndpoint = config.graphEndpoint,
QuasarUserRegistrationId = Guid.NewGuid(),
RedirectUrl = config.redirectUri,
SaveUserPassword = true,
UsersFamilyName = authResult.UserInfo.FamilyName,
UsersPassword = UsersPassword.Value,
UsersGivenName = authResult.UserInfo.GivenName
};

        UserAuthenticationCache userAuthenticationCache = new UserAuthenticationCache()
                                                          {
                                                              CellId = Trinity.Core.Lib.CellIdFactory.NewCellId(),
                                                              AddtionalUserConfigData = null,
                                                              UserAuthInfoSet =  userAuthenticationSessionData
                                                          };

        Global.LocalStorage.SaveUserAuthenticationCache(Trinity.TSL.Lib.CellAccessOptions.StrongLogAhead, userAuthenticationCache);

        Global.LocalStorage.SaveStorage();

        if (Global.LocalStorage.IsUserAuthenticationCache(userAuthenticationCache.CellId))
        {
            foreach (var useAuthContext in Global.LocalStorage.UserAuthenticationCache_Accessor_Selector())
            {
                var userName = useAuthContext.UserAuthInfoSet.UsersGivenName;
            }
        }

According to the Graph Engine Developer Guide my code should have worked:

Enumerable Collection Operators

Custom logic can be performed on the cells when iterating through them. The .NET framework provides a set of static methods for querying enumerable collections. For a complete list of query methods, refer to MSDN.

With the extension methods provided by System.Linq.Enumerable, we can use the cell selectors to manipulate data in a succinct style. Instead of writing data processing logic in a foreach loop, we can use the query interfaces to extract and aggregate information in a declarative way.

In this application, Graph Data Services are composed of .NET assemblies that implement TSL for discrete Graph Data models; the client WPF MVVM assemblies reference these Graph Data Services and during processing, the applications store content in the Graph Engine Data Cells and save the local memory cloud to disk. The application once restarted tries to load memory cloud dump into memory; that seems to work but when iterating over Graph Engine Selectors and Accessor from end to end memory access violation errors are encountered. If I limit and or constrain foreach processing via ".Take(n)", the application is able to access in-memory cloud but the behavior of the application is not expected and incorrect. In the debugger one typed accessor is able to access the data the marked with ownership to another TSL DSL production. In one use-case I know that 1000 items where save vai the generated typed Save API call; if I instruct the API to take the first 500 cells the API returns 56 items?!

Okay - after a bit more testing of my GE server implementation I am not getting this error during the initialization process: [ ERROR ] Inconsistent cell type signature for type #0.
[ ERROR ] Expecting: {{string|string|string|DateTime|bool|string|string|string|string|Guid}|List}.
[ ERROR ] Got: {string|string|string|string|string|string|string|string|DateTime|DateTime|string|string|string|string|string|string|string|string|string|string|string|string|string|string|string|string|string|string|List|List|List|List|List|List<{string|string|string|string|string}>|List<{string|string|string|string|string}>|List<{string|string|string|string|string}>|List}.

I have an idea of what this means - can anyone shed more light on what is going on here?

I think I know what the problem here is now; this would be a miss-use of the API on my part. I'm running the app in "embedded" mode and I did not use the RegisterCommunicationModule API but instead used a standard approach to using reference assemblies in C#. The Trinity API has its own specialized version of DI via the RegisterCommunicationModule and GetCommunicationModule APIs. These API must be called in order to set up the Trinity Networking Runtime - but I do not see a way to do this, to use multiple modules, in the "embedded" configuration. This issue is in part, related to issue #308.

I found the problem here. I found the answer after reading very closely the documentation again. I made the assumption the Trinity API RegisterCommunicationModule and GetCommunicationModule work like typical DI APIs - they don't! I was using the API incorrectly. I'm don't like it but I do understand it now.