Skip to content

Handle leaks#883

Merged
nulltoken merged 4 commits into
vNextfrom
ntk/leaks
Dec 7, 2014
Merged

Handle leaks#883
nulltoken merged 4 commits into
vNextfrom
ntk/leaks

Conversation

@nulltoken

Copy link
Copy Markdown
Member

I've recently repaved my box and switched back from the Resharper test runner to Testdriven.net.

And... we're leaking handles. The issue with that is that the dll gets locked and cannot be rewritten over. That would correlate with some reports I've had of such issues from @Allov and @davidebbo.

For instance UnstageFixture.UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrows() leaks one DiffSafeHandle.

I'm currently investigating this further and trying to identify and fix those leaks.

However, I'd be a taker if you had an idea regarding how we could abort the test suite when that happens.

@nulltoken nulltoken added the Bug label Dec 5, 2014
@nulltoken

Copy link
Copy Markdown
Member Author

Hmmm. I'm a bit lost here. I've transmuted this issue into a PR to share my current debugging process.

Below the output from the test run of UnstageFixture.UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrows().

Handle 2377eb1b-fdc6-4216-9ab4-bd9383717191 is finalized instead of being disposed. I've tried to tweak Diff.Compare() implementation to force the disposal, but with little luck.

Any idea??? Please ????

------ Test started: Assembly: LibGit2Sharp.Tests.dll ------

Output from LibGit2Sharp.Tests.UnstageFixture.UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrows(relativePath: "where-am-I.txt", currentStatus: Nonexistent):
  Alloc LibGit2Sharp.Core.Handles.RepositorySafeHandle - 58ac395e-f906-4575-9684-023897b0960f
  Alloc LibGit2Sharp.Core.Handles.IndexSafeHandle - 7c2eff54-6fea-4370-a443-c8917b59d07b
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 330196f7-8047-4a1f-881b-cb9ebacbf51f
  Alloc LibGit2Sharp.Core.Handles.ReferenceSafeHandle - 105b0c74-d99a-479c-a686-862d3b291c84
  Disposing LibGit2Sharp.Core.Handles.ReferenceSafeHandle - 105b0c74-d99a-479c-a686-862d3b291c84
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 330196f7-8047-4a1f-881b-cb9ebacbf51f
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - cfb04040-8e6c-4dd9-9502-78ecf72006bd
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 5c58a8fa-82d1-4ce5-8e77-8ad46726d23b
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - cfb04040-8e6c-4dd9-9502-78ecf72006bd
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 5c58a8fa-82d1-4ce5-8e77-8ad46726d23b
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - e41a7603-5288-4989-ad04-a42833028441
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - e41a7603-5288-4989-ad04-a42833028441
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - ef13b383-e4c8-4c4a-a22c-1e1f118acd36
  Alloc LibGit2Sharp.Core.Handles.DiffSafeHandle - 2377eb1b-fdc6-4216-9ab4-bd9383717191
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - ef13b383-e4c8-4c4a-a22c-1e1f118acd36
  Disposing LibGit2Sharp.Core.Handles.IndexSafeHandle - 7c2eff54-6fea-4370-a443-c8917b59d07b
  Disposing LibGit2Sharp.Core.Handles.RepositorySafeHandle - 58ac395e-f906-4575-9684-023897b0960f

Output from LibGit2Sharp.Tests.UnstageFixture.UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrows(relativePath: "new_untracked_file.txt", currentStatus: Untracked):
  !Finalizing LibGit2Sharp.Core.Handles.DiffSafeHandle - 2377eb1b-fdc6-4216-9ab4-bd9383717191
  A DiffSafeHandle handle wrapper has not been properly disposed.
     at LibGit2Sharp.Core.NativeMethods.git_diff_tree_to_index(DiffSafeHandle& diff, RepositorySafeHandle repo, GitObjectSafeHandle oldTree, IndexSafeHandle index, GitDiffOptions options)
     at LibGit2Sharp.Core.Proxy.git_diff_tree_to_index(RepositorySafeHandle repo, IndexSafeHandle index, ObjectId oldTree, GitDiffOptions options) in f:\libgit2sharp\LibGit2Sharp\Core\Proxy.cs:line 657
     at LibGit2Sharp.Diff.<>c__DisplayClasse.<IndexToTree>b__d(ObjectId oh, ObjectId nh, GitDiffOptions o) in f:\libgit2sharp\LibGit2Sharp\Diff.cs:line 323
     at LibGit2Sharp.Diff.BuildDiffList(ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever, DiffModifiers diffOptions, IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) in f:\libgit2sharp\LibGit2Sharp\Diff.cs:line 335
     at LibGit2Sharp.Diff.Compare[T](Tree oldTree, DiffTargets diffTargets, IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) in f:\libgit2sharp\LibGit2Sharp\Diff.cs:line 216
     at LibGit2Sharp.Repository.Reset(Commit commit, IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions) in f:\libgit2sharp\LibGit2Sharp\Repository.cs:line 813
     at LibGit2Sharp.RepositoryExtensions.Reset(IRepository repository, String committish, IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions) in f:\libgit2sharp\LibGit2Sharp\RepositoryExtensions.cs:line 197
     at LibGit2Sharp.Repository.Unstage(IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions) in f:\libgit2sharp\LibGit2Sharp\Repository.cs:line 1541
     at LibGit2Sharp.Repository.Unstage(String path, ExplicitPathsOptions explicitPathsOptions) in f:\libgit2sharp\LibGit2Sharp\Repository.cs:line 1518
     at LibGit2Sharp.Tests.UnstageFixture.<>c__DisplayClass5.<UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrows>b__1() in f:\libgit2sharp\LibGit2Sharp.Tests\UnstageFixture.cs:line 96
     at Xunit.Record.Exception(ThrowsDelegate code)
     at Xunit.Assert.Throws(Type exceptionType, ThrowsDelegate testCode)
     at Xunit.Assert.Throws[T](ThrowsDelegate testCode)
     at LibGit2Sharp.Tests.UnstageFixture.UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrows(String relativePath, FileStatus currentStatus) in f:\libgit2sharp\LibGit2Sharp.Tests\UnstageFixture.cs:line 96
     at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
     at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
     at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
     at Xunit.Sdk.Reflector.ReflectionMethodInfo.Invoke(Object testClass, Object[] parameters)
     at Xunit.Extensions.TheoryCommand.Execute(Object testClass)
     at Xunit.Sdk.FixtureCommand.Execute(Object testClass)
     at Xunit.Sdk.BeforeAfterCommand.Execute(Object testClass)
     at Xunit.Sdk.LifetimeCommand.Execute(Object testClass)
     at Xunit.Sdk.ExceptionAndOutputCaptureCommand.Execute(Object testClass)
     at Xunit.Sdk.TimedCommand.Execute(Object testClass)
     at Xunit.Sdk.TestClassCommandRunner.Execute(ITestClassCommand testClassCommand, List`1 methods, Predicate`1 startCallback, Predicate`1 resultCallback)
     at Xunit.Sdk.Executor.RunTests.<>c__DisplayClass12.<.ctor>b__f()
     at Xunit.Sdk.Executor.ThreadRunner(Object threadStart)
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
     at System.Threading.ThreadHelper.ThreadStart(Object obj)


  Alloc LibGit2Sharp.Core.Handles.RepositorySafeHandle - 99de2f14-a9e6-4048-8abd-36539db3b481
  Alloc LibGit2Sharp.Core.Handles.IndexSafeHandle - b19f0fc6-b2ef-4986-b266-4cbfec077ea2
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 6469c16b-6e5d-45d7-b83b-2c82b7d9ab1c
  Alloc LibGit2Sharp.Core.Handles.ReferenceSafeHandle - 299d4ad2-bd66-4ff7-aaa7-c6a227d1a991
  Disposing LibGit2Sharp.Core.Handles.ReferenceSafeHandle - 299d4ad2-bd66-4ff7-aaa7-c6a227d1a991
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 6469c16b-6e5d-45d7-b83b-2c82b7d9ab1c
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - de884804-f8c0-4c66-9da5-b65d14c2c8e9
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 19533777-39ce-4071-83fc-0fbf393e288e
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - de884804-f8c0-4c66-9da5-b65d14c2c8e9
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 19533777-39ce-4071-83fc-0fbf393e288e
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 5ea2ee00-ae8c-4b69-930c-fd912ac41967
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 5ea2ee00-ae8c-4b69-930c-fd912ac41967
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - be21b11c-d60e-4094-b5ff-f348d937cc1f
  Alloc LibGit2Sharp.Core.Handles.DiffSafeHandle - d873c475-78fd-43fd-b202-afa2a7bca092
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - be21b11c-d60e-4094-b5ff-f348d937cc1f
  Disposing LibGit2Sharp.Core.Handles.IndexSafeHandle - b19f0fc6-b2ef-4986-b266-4cbfec077ea2
  Disposing LibGit2Sharp.Core.Handles.RepositorySafeHandle - 99de2f14-a9e6-4048-8abd-36539db3b481

2 passed, 0 failed, 0 skipped, took 1,59 seconds (xUnit.net 1.9.0 build 1566).

@nulltoken

Copy link
Copy Markdown
Member Author

Ok. I'm completely lost now. Or maybe a tad underslept.

I've added some more tracing around the building/disposing of the handle and some expected output is not executed.

I need another pair of 👀 here.

------ Test started: Assembly: LibGit2Sharp.Tests.dll ------

Output from LibGit2Sharp.Tests.UnstageFixture.UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrows(relativePath: "where-am-I.txt", currentStatus: Nonexistent):
  Alloc LibGit2Sharp.Core.Handles.RepositorySafeHandle - b9800551-6de1-4f5b-b8c9-84828cb75495
  Alloc LibGit2Sharp.Core.Handles.IndexSafeHandle - 0d77215c-09a0-4522-85dc-8f97a0e5637c
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 27d4fea9-6908-4409-aa39-86e0902d31e8
  Alloc LibGit2Sharp.Core.Handles.ReferenceSafeHandle - 2e04f67f-1944-49e2-bb49-04b70ed34b72
  Disposing LibGit2Sharp.Core.Handles.ReferenceSafeHandle - 2e04f67f-1944-49e2-bb49-04b70ed34b72
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 27d4fea9-6908-4409-aa39-86e0902d31e8
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - fb419c35-5570-49d3-b517-a748de1d045c
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - db2e96f6-ea51-45d3-a846-88622f1558a2
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - fb419c35-5570-49d3-b517-a748de1d045c
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - db2e96f6-ea51-45d3-a846-88622f1558a2
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - fa9bbba8-7512-4a87-bc03-c0ff9bec5534
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - fa9bbba8-7512-4a87-bc03-c0ff9bec5534
  * Building DiffSafeHandle
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 73452e36-203b-48e7-a264-7ad64c06a137
  Alloc LibGit2Sharp.Core.Handles.DiffSafeHandle - 058aef31-0829-4253-819d-4be5aa97d708
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 73452e36-203b-48e7-a264-7ad64c06a137
  * Start finally
  * End finally
  Disposing LibGit2Sharp.Core.Handles.IndexSafeHandle - 0d77215c-09a0-4522-85dc-8f97a0e5637c
  Disposing LibGit2Sharp.Core.Handles.RepositorySafeHandle - b9800551-6de1-4f5b-b8c9-84828cb75495

Output from LibGit2Sharp.Tests.UnstageFixture.UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrows(relativePath: "new_untracked_file.txt", currentStatus: Untracked):
  !Finalizing LibGit2Sharp.Core.Handles.DiffSafeHandle - 058aef31-0829-4253-819d-4be5aa97d708
  A DiffSafeHandle handle wrapper has not been properly disposed.
     at LibGit2Sharp.Core.NativeMethods.git_diff_tree_to_index(DiffSafeHandle& diff, RepositorySafeHandle repo, GitObjectSafeHandle oldTree, IndexSafeHandle index, GitDiffOptions options)
     at LibGit2Sharp.Core.Proxy.git_diff_tree_to_index(RepositorySafeHandle repo, IndexSafeHandle index, ObjectId oldTree, GitDiffOptions options) in f:\libgit2sharp\LibGit2Sharp\Core\Proxy.cs:line 657
     at LibGit2Sharp.Diff.<>c__DisplayClasse.<IndexToTree>b__d(ObjectId oh, ObjectId nh, GitDiffOptions o) in f:\libgit2sharp\LibGit2Sharp\Diff.cs:line 332
     at LibGit2Sharp.Diff.BuildDiffList(ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever, DiffModifiers diffOptions, IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) in f:\libgit2sharp\LibGit2Sharp\Diff.cs:line 344
     at LibGit2Sharp.Diff.Compare[T](Tree oldTree, DiffTargets diffTargets, IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) in f:\libgit2sharp\LibGit2Sharp\Diff.cs:line 217
     at LibGit2Sharp.Repository.Reset(Commit commit, IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions) in f:\libgit2sharp\LibGit2Sharp\Repository.cs:line 813
     at LibGit2Sharp.RepositoryExtensions.Reset(IRepository repository, String committish, IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions) in f:\libgit2sharp\LibGit2Sharp\RepositoryExtensions.cs:line 197
     at LibGit2Sharp.Repository.Unstage(IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions) in f:\libgit2sharp\LibGit2Sharp\Repository.cs:line 1541
     at LibGit2Sharp.Repository.Unstage(String path, ExplicitPathsOptions explicitPathsOptions) in f:\libgit2sharp\LibGit2Sharp\Repository.cs:line 1518
     at LibGit2Sharp.Tests.UnstageFixture.<>c__DisplayClass5.<UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrows>b__1() in f:\libgit2sharp\LibGit2Sharp.Tests\UnstageFixture.cs:line 96
     at Xunit.Record.Exception(ThrowsDelegate code)
     at Xunit.Assert.Throws(Type exceptionType, ThrowsDelegate testCode)
     at Xunit.Assert.Throws[T](ThrowsDelegate testCode)
     at LibGit2Sharp.Tests.UnstageFixture.UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrows(String relativePath, FileStatus currentStatus) in f:\libgit2sharp\LibGit2Sharp.Tests\UnstageFixture.cs:line 96
     at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
     at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
     at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
     at Xunit.Sdk.Reflector.ReflectionMethodInfo.Invoke(Object testClass, Object[] parameters)
     at Xunit.Extensions.TheoryCommand.Execute(Object testClass)
     at Xunit.Sdk.FixtureCommand.Execute(Object testClass)
     at Xunit.Sdk.BeforeAfterCommand.Execute(Object testClass)
     at Xunit.Sdk.LifetimeCommand.Execute(Object testClass)
     at Xunit.Sdk.ExceptionAndOutputCaptureCommand.Execute(Object testClass)
     at Xunit.Sdk.TimedCommand.Execute(Object testClass)
     at Xunit.Sdk.TestClassCommandRunner.Execute(ITestClassCommand testClassCommand, List`1 methods, Predicate`1 startCallback, Predicate`1 resultCallback)
     at Xunit.Sdk.Executor.RunTests.<>c__DisplayClass12.<.ctor>b__f()
     at Xunit.Sdk.Executor.ThreadRunner(Object threadStart)
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
     at System.Threading.ThreadHelper.ThreadStart(Object obj)


  Alloc LibGit2Sharp.Core.Handles.RepositorySafeHandle - 43e20cb1-d257-487f-a4aa-eeca29fe98b0
  Alloc LibGit2Sharp.Core.Handles.IndexSafeHandle - 8f947ffd-2fc9-4acd-9d94-64afef743ec0
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - aac8c1ef-c20c-42e8-89fe-7d81b0450307
  Alloc LibGit2Sharp.Core.Handles.ReferenceSafeHandle - 7c6299f3-fd5d-4c11-922e-cb1ecd5d741a
  Disposing LibGit2Sharp.Core.Handles.ReferenceSafeHandle - 7c6299f3-fd5d-4c11-922e-cb1ecd5d741a
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - aac8c1ef-c20c-42e8-89fe-7d81b0450307
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 663ab125-51da-45d9-90e4-4b0525661cc8
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 5214eb46-9114-4359-b2df-d7faba2496fb
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 663ab125-51da-45d9-90e4-4b0525661cc8
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 5214eb46-9114-4359-b2df-d7faba2496fb
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - f00b4648-c96c-4601-ba96-efa536f3a321
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - f00b4648-c96c-4601-ba96-efa536f3a321
  * Building DiffSafeHandle
  Alloc LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 8068f458-f71d-499e-a078-46227cf3fad2
  Alloc LibGit2Sharp.Core.Handles.DiffSafeHandle - 2baaa606-c263-4337-81b4-76053cad3f76
  Disposing LibGit2Sharp.Core.Handles.GitObjectSafeHandle - 8068f458-f71d-499e-a078-46227cf3fad2
  * Start finally
  * End finally
  Disposing LibGit2Sharp.Core.Handles.IndexSafeHandle - 8f947ffd-2fc9-4acd-9d94-64afef743ec0
  Disposing LibGit2Sharp.Core.Handles.RepositorySafeHandle - 43e20cb1-d257-487f-a4aa-eeca29fe98b0

2 passed, 0 failed, 0 skipped, took 1,51 seconds (xUnit.net 1.9.0 build 1566).

Comment thread LibGit2Sharp/Diff.cs Outdated

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those two lines above do not appear in the output

@nulltoken

Copy link
Copy Markdown
Member Author

facepalm I've found something. Sorry for the noise....

@nulltoken

Copy link
Copy Markdown
Member Author

Ok. A first batch of leaks have been plugged. Some remain though. Working on plugging them.

Still, I'd be interested in failing the test suite when some are detected. Ideas?

@Therzok

Therzok commented Dec 5, 2014

Copy link
Copy Markdown
Member

Okay so, my idea would be the following:

  • Add a property in CI that would set an MSBuild property i.e. FailOnLeak.
  • [Optional] Add a local switch for it?
  • MSBuild parses that Property and defines constant FAIL_ON_LEAK. (To do this, in the csproj add a line below it with: <DefineConstants Condition="$(FailOnLeak) != '">$(DefineConstants);FAIL_ON_LEAK</DefineConstants>)
  • Change DiffSafeHandle to throw WeScrewedUpException() on a leak.

@nulltoken

Copy link
Copy Markdown
Member Author

@Therzok 👍 You made my day!

@nulltoken

Copy link
Copy Markdown
Member Author

@Therzok Here's what I came with.

with. Unfortunately, throwing from the Dispose() method invoked by the finalizer doesn't work... Or, I haven't been able to make it work...

@Therzok

Therzok commented Dec 6, 2014

Copy link
Copy Markdown
Member

Okay, so including the comment above, why not use Debug.Fail instead of an exception?

@Therzok

Therzok commented Dec 6, 2014

Copy link
Copy Markdown
Member

Want me to jump in on the PR and do the changes so it's easier to understand after?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outut output

@nulltoken

Copy link
Copy Markdown
Member Author

@Therzok

I've tried different approaches (Environment.FailFast, trying to output the messages, ...) without much success. FailFast was crashing the process but the Console buffer wasn't flushed so no useful information for the user....

Latest one is to make the test suite monitor some shared container for reported leaked handles and fail the current test. Works on AppVeyor but completely ignored on Travis 😕

I didn't think of Debug.Fail() though. Would it output something in Travus/AppVeyor output?

Want me to jump in on the PR and do the changes so it's easier to understand after?

Yes, please!!!! I think I can't think straight any longer for now. ❤️

@nulltoken

Copy link
Copy Markdown
Member Author

@Therzok The PR is yours, Sir!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Therzok If you think going down this path makes sense (and we actually succeed in making it work on Travis), maybe should we clear the LeaksContainer once we've failed the test in order to avoid polluting (too much) the build log.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm not getting anything useful when defining LEAKS_IDENTIFYING on Mac. Hmmm, something is stale over here.

@Therzok

Therzok commented Dec 6, 2014

Copy link
Copy Markdown
Member

Okay, will do. Starting on it now.

@nulltoken

Copy link
Copy Markdown
Member Author

@Therzok

Therzok commented Dec 6, 2014

Copy link
Copy Markdown
Member

Actually, depending on XUnit on this thing is way better for unit tests.

@Therzok

Therzok commented Dec 6, 2014

Copy link
Copy Markdown
Member

Debug.Fail won't do any good. We're rolling the Release configuration on CI.

@Therzok

Therzok commented Dec 6, 2014

Copy link
Copy Markdown
Member

I would like to do one more fixup. We need to split each define into a separate msbuild property. i.e. calling build.libgit2sharp.cmd with 'LEAKS_TRACKING;LEAKS_IDENTIFYING' won't work.

regex_replace("([a-zA-Z_]+)", \1=\1)
regex_replace("[^:]", /p:)

@Therzok

Therzok commented Dec 6, 2014

Copy link
Copy Markdown
Member

@nulltoken you made some manual changes to the AppVeyor build and that keeps your old behaviour on the msbuild targets.

@Therzok

Therzok commented Dec 7, 2014

Copy link
Copy Markdown
Member

On mono, disposing is always true in BaseFixture. Still trying to dig it down.

Switched from ConcurrentBag to HashSet since we're doing locks. ConcurrentBag is unstable from what I read on the internets.

@Therzok

Therzok commented Dec 7, 2014

Copy link
Copy Markdown
Member

Yeah, SafeHandle is bugged in mono. We can't rely on any useful info from SafeHandle on Mono. Trying to check how easy it would be to import the ReferenceSource for it.

mono vs .NET

@nulltoken
nulltoken force-pushed the ntk/leaks branch 2 times, most recently from 8e0ae9a to 6139777 Compare December 7, 2014 09:46
@nulltoken

Copy link
Copy Markdown
Member Author

@dahlbyk @ethomson @jamill @carlosmn Ready for review, I think... Unless @Therzok is willing to polish this further.

This will fail the AppVeyor build when leaked handled are detected.

  • Travis build doesn't detect leaks because of a bug in SafeHandle
  • Build with LEAKS_IDENTIFYING constant shouldn't be used in production (as it introduces a LeaksContainer type and add some overhead to every handle disposal)
  • Commit "Injecting leaks on purpose to check CI server logs" is, of course, supposed to be dropped before merge time

@Therzok

Therzok commented Dec 7, 2014

Copy link
Copy Markdown
Member

As I said, my only remaining improvement is to split ExtraDefines into LeaksTracking and Leaks Identifying, since msbuild doesn't seem to support multiple values in the parameter. I.e. we can't do /p:ExtraDefines="LEAKS_TRACKING;LEAKS_IDENTIFYING". So we'd add conditional msbuild parameters for each extra define.

@Therzok

Therzok commented Dec 7, 2014

Copy link
Copy Markdown
Member

That is, if we ever end up wanting to define more than one extra symbol.

@Therzok

Therzok commented Dec 7, 2014

Copy link
Copy Markdown
Member

Let's just merge as-is, imo. Other than "ExtraDefines" to "ExtraDefine" or per-define specific property, I have nothing else to add. I can go either route if it's wanted.

@nulltoken

Copy link
Copy Markdown
Member Author

Renamed to ExtraDefine.

@Therzok

Therzok commented Dec 7, 2014

Copy link
Copy Markdown
Member

You forgot CI/build.msbuild changes.

@nulltoken

Copy link
Copy Markdown
Member Author

You forgot CI/build.msbuild changes.

This is why I pushed the fix in the first place. I knew I was going to forget something 😉

@nulltoken

Copy link
Copy Markdown
Member Author

Ok. Cleaning up the PR, now...

@Therzok

Therzok commented Dec 7, 2014

Copy link
Copy Markdown
Member

selfie-0

Edit: My failed attempt at making a gif.

@nulltoken

Copy link
Copy Markdown
Member Author

Hmmm. Something's fishy here. This should have failed. There are still some purposefully injected leaks

@nulltoken

Copy link
Copy Markdown
Member Author

Where did I mess up?

@nulltoken

Copy link
Copy Markdown
Member Author

Found. I've forgot to change the AppVeyor settings.

@nulltoken

Copy link
Copy Markdown
Member Author

Ok. AppVeyor detected the leak. Now let's drop the injection of fake leaks

@nulltoken
nulltoken merged commit 55b3c42 into vNext Dec 7, 2014
@nulltoken
nulltoken deleted the ntk/leaks branch December 7, 2014 18:49
@nulltoken nulltoken added this to the v0.21 milestone Dec 7, 2014
@nulltoken

Copy link
Copy Markdown
Member Author

@Therzok I'd like to thank you very much with the help you've provided with nailing this. I'm pretty psyched about this! We should now be protected about future leaks! 💯

@Therzok

Therzok commented Dec 7, 2014

Copy link
Copy Markdown
Member

@nulltoken it was my pleasure to have this handled! ❤️ I've pushed a bug report about SafeHandle issues on Mono. Luckily, AppVeyor runs after travis so we don't miss results.

@Therzok

Therzok commented Dec 8, 2014

Copy link
Copy Markdown
Member

SafeHandle is now fixed in mono master.

@nulltoken

Copy link
Copy Markdown
Member Author

Wow! That was fast!

@Therzok

Therzok commented Dec 8, 2014

Copy link
Copy Markdown
Member

Getting a test case that covers expected results gets a commit that fixes the behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants