question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Managed Debugging Assistant 'PInvokeStackImbalance' : 'A call to PInvoke function 'Microsoft.Azure.Cosmos.Direct!Microsoft.Azure.Cosmos.Core.Trace.EtwNativeInterop::EventWriteString' has unbalanced the stack

See original GitHub issue

We are in the process of upgrading from the 2.x document client to the 3.1 Cosmo client. I have created a repository class to generalize/isolate some of the cosmo sdk code. In my upsert method, I am attempting to construct the cosmo client in a using statement - this seemed to be supported by documentation and runs properly when NOT DEBUGGING.

To Reproduce I don’t want to share the full code base if I can avoid it. My test is set up this this:


        [Fact]
        public async void TestRepositoryExample()
        {
            await activityPlayRepository.UpdateActivityPlayDocument(new ActivityPlayDocument()
            {
                GameID = new Guid("896BB422-5A9F-E511-80E7-000D3A001FE3"),
                TenantUserID = new Guid("896BB422-5A9F-E511-80E7-000D3A001FE3")
            });

            // method has no return - just a bs assertion to prove the test
            Assert.NotEmpty(new List<string>(){"f"});

        }

Which calls a collection specific repo class (basically just a configured wrapper for the actual cosmo repo class we have):


        public async Task UpdateActivityPlayDocument(ActivityPlayDocument activityPlayDocument)
        {
            await _cosmoDbCollectionRepository.Upsert(new CosmoDBCollectionUpsertQuery<ActivityPlayDocument>()
            {
                AccessConfiguration = _accessConfiguration,
                CosmoIDResolver = x => x.GameSetScoreID.ToString(),
                CosmoPartitionResolver = x => new PartitionKey(x.GameID.ToString()),
                Data = activityPlayDocument,
                InsertionRuleType = InsertionRuleType.ErrorIfOldRecordDoesNotExist
            });
        }

Which then calls my actual cosmo connection class:


        public async Task<CosmoDBCollectionUpsertQueryResult> Upsert<T>(CosmoDBCollectionUpsertQuery<T> cosmoDbCollectionUpsertQuery)
        {
            var result = new CosmoDBCollectionUpsertQueryResult();

            try
            {
                using (CosmosClient cosmosClient = new CosmosClient(cosmoDbCollectionUpsertQuery.AccessConfiguration.AccountEndPoint,
                    cosmoDbCollectionUpsertQuery.AccessConfiguration.AccountKey))
                {
                    var propertyResolver =
                        cosmoDbCollectionUpsertQuery.CosmoIDResolver(cosmoDbCollectionUpsertQuery.Data);

                    var partitionResolver = cosmoDbCollectionUpsertQuery.CosmoPartitionResolver(cosmoDbCollectionUpsertQuery.Data);

                    var container = cosmosClient
                        .GetContainer(cosmoDbCollectionUpsertQuery.AccessConfiguration.DatabaseId,
                            cosmoDbCollectionUpsertQuery.AccessConfiguration.ContainerId);
                    try
                    {

                        // see if the record exists already - if it doesn't, an error will be throw
                        await container.ReadItemAsync<T>(propertyResolver, partitionResolver);

                        switch (cosmoDbCollectionUpsertQuery.InsertionRuleType)
                        {
                            case InsertionRuleType.UseImplementationRuleChoice: // impl choice is merge here
                            case InsertionRuleType.MergeOldRecordIfExists:
                                await container.UpsertItemAsync(cosmoDbCollectionUpsertQuery.Data, partitionResolver);
                                break;
                            case InsertionRuleType.DeleteOldRecordIfExists:
                                await container.DeleteItemAsync<T>(propertyResolver, partitionResolver);
                                await container.CreateItemAsync<T>(cosmoDbCollectionUpsertQuery.Data, partitionResolver);
                                break;
                            default:
                                throw new ArgumentOutOfRangeException(nameof(cosmoDbCollectionUpsertQuery
                                    .InsertionRuleType));
                        }
                    }
                    catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.NotFound
                                                     && cosmoDbCollectionUpsertQuery.InsertionRuleType != InsertionRuleType.ErrorIfOldRecordDoesNotExist)
                    {
                        await container.CreateItemAsync<T>(cosmoDbCollectionUpsertQuery.Data, partitionResolver);
                    }
                }
            }
            catch (Exception e)
            {
                result.Exception = e;
            }

            return result;
        }


The using statement is where things go bad for me. I get the following error as soon as it hits the using statement:

Managed Debugging Assistant 'PInvokeStackImbalance' : 'A call to PInvoke function 'Microsoft.Azure.Cosmos.Direct!Microsoft.Azure.Cosmos.Core.Trace.EtwNativeInterop::EventWriteString' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.'

Expected behavior I should be able to debug my methods and skip over unmanaged code or get an exception that I can act on (if my call signature is wrong, etc).

Actual behavior Exception is thrown when debugging from a unit test but exception does not occur if the test is run without debugging. Information is persisted to cosmo repo as expected when “Run”, but fails when “Debug”.

Environment summary SDK Version: Microsoft.Azure.Cosmos 3.1.0 xunit 2.4.0 / .NET Framework 4.71 OS Version: Windows 10 17134.885

Additional context Please let me know if I’ve excluded any critical details. Thanks

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
ausfeldtcommented, Aug 7, 2019

Root cause found. Working on an action plan now.

0reactions
JohnSpencerTerrycommented, Aug 15, 2019

Thanks for the quick turn around. Appreciate the help!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Rdlc Report in MVC project - Managed Debugging ...
I'm running Microsoft. ... According to this answer, PInvokeStackImbalance is more of a "debugging assistant" than an exception. So.
Read more >
pInvokeStackImbalance MDA - .NET Framework
A call to PInvoke function 'SampleMethod' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the ...
Read more >
Troubleshoot slow requests in Azure Cosmos DB .NET SDK
This article explains the different root causes for this problem. Request rate too large. Request throttling is the most common reason for slow ......
Read more >
Diagnose and troubleshoot issues when using Azure ...
Log metrics by using the Azure portal. Portal metrics show the Azure Cosmos DB telemetry, which is helpful to determine if the issue...
Read more >
Azure Cosmos DB performance tips for .NET SDK v3
Scaling up and down is as easy as making a single API call. To learn more, see provision container throughput or provision database...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found