1
- using System ;
1
+ // This activates a lightweight mode which will help put under the light
2
+ // incorrectly released handles by outputing a warning message in the console.
3
+ //
4
+ // This should be activated when tests are being run of the CI server.
5
+ //
6
+ // Uncomment the line below or add a conditional symbol to activate this mode
7
+
8
+ // #define LEAKS_IDENTIFYING
9
+
10
+ // This activates a more throrough mode which will show the stack trace of the
11
+ // allocation code path for each handle that has been improperly released.
12
+ //
13
+ // This should be manually activated when some warnings have been raised as
14
+ // a result of LEAKS_IDENTIFYING mode activation.
15
+ //
16
+ // Uncomment the line below or add a conditional symbol to activate this mode
17
+
18
+ // #define LEAKS_TRACKING
19
+
20
+ using System ;
21
+ using System . Linq ;
22
+ using System . Diagnostics ;
23
+ using System . Globalization ;
24
+ using System . Collections . Generic ;
25
+
26
+ #if LEAKS_IDENTIFYING
27
+ namespace LibGit2Sharp . Core
28
+ {
29
+ /// <summary>
30
+ /// Holds leaked handle type names reported by <see cref="Core.Handles.Libgit2Object"/>
31
+ /// </summary>
32
+ public static class LeaksContainer
33
+ {
34
+ private static readonly HashSet < string > _typeNames = new HashSet < string > ( ) ;
35
+ private static readonly object _lockpad = new object ( ) ;
36
+
37
+ /// <summary>
38
+ /// Report a new leaked handle type name
39
+ /// </summary>
40
+ /// <param name="typeName">Short name of the leaked handle type.</param>
41
+ public static void Add ( string typeName )
42
+ {
43
+ lock ( _lockpad )
44
+ {
45
+ _typeNames . Add ( typeName ) ;
46
+ }
47
+ }
48
+
49
+ /// <summary>
50
+ /// Removes all previously reported leaks.
51
+ /// </summary>
52
+ public static void Clear ( )
53
+ {
54
+ lock ( _lockpad )
55
+ {
56
+ _typeNames . Clear ( ) ;
57
+ }
58
+ }
59
+
60
+ /// <summary>
61
+ /// Returns all reported leaked handle type names.
62
+ /// </summary>
63
+ public static IEnumerable < string > TypeNames
64
+ {
65
+ get
66
+ {
67
+ string [ ] result = null ;
68
+ lock ( _lockpad )
69
+ {
70
+ result = _typeNames . ToArray ( ) ;
71
+ }
72
+ return result ;
73
+ }
74
+ }
75
+ }
76
+ }
77
+ #endif
2
78
3
79
namespace LibGit2Sharp . Core . Handles
4
80
{
5
81
internal unsafe abstract class Libgit2Object : IDisposable
6
82
{
83
+ #if LEAKS_TRACKING
84
+ private readonly string trace ;
85
+ private readonly Guid id ;
86
+ #endif
87
+
7
88
protected void * ptr ;
8
89
9
90
internal void * Handle
@@ -21,12 +102,17 @@ internal unsafe Libgit2Object(void* handle, bool owned)
21
102
{
22
103
this . ptr = handle ;
23
104
this . owned = owned ;
105
+
106
+ #if LEAKS_TRACKING
107
+ id = Guid . NewGuid ( ) ;
108
+ Trace . WriteLine ( string . Format ( CultureInfo . InvariantCulture , "Allocating {0} handle ({1})" , GetType ( ) . Name , id ) ) ;
109
+ trace = new StackTrace ( 2 , true ) . ToString ( ) ;
110
+ #endif
24
111
}
25
112
26
113
internal unsafe Libgit2Object ( IntPtr ptr , bool owned )
114
+ : this ( ptr . ToPointer ( ) , owned )
27
115
{
28
- this . ptr = ptr . ToPointer ( ) ;
29
- this . owned = owned ;
30
116
}
31
117
32
118
~ Libgit2Object ( )
@@ -51,6 +137,15 @@ internal IntPtr AsIntPtr()
51
137
52
138
void Dispose ( bool disposing )
53
139
{
140
+ #if LEAKS_IDENTIFYING
141
+ bool leaked = ! disposing && ptr != null ;
142
+
143
+ if ( leaked )
144
+ {
145
+ LeaksContainer . Add ( GetType ( ) . Name ) ;
146
+ }
147
+ #endif
148
+
54
149
if ( ! disposed )
55
150
{
56
151
if ( owned )
@@ -62,6 +157,19 @@ void Dispose(bool disposing)
62
157
}
63
158
64
159
disposed = true ;
160
+
161
+ #if LEAKS_TRACKING
162
+ if ( ! leaked )
163
+ {
164
+ Trace . WriteLine ( string . Format ( CultureInfo . InvariantCulture , "Disposing {0} handle ({1})" , GetType ( ) . Name , id ) ) ;
165
+ }
166
+ else
167
+ {
168
+ Trace . WriteLine ( string . Format ( CultureInfo . InvariantCulture , "Unexpected finalization of {0} handle ({1})" , GetType ( ) . Name , id ) ) ;
169
+ Trace . WriteLine ( trace ) ;
170
+ Trace . WriteLine ( "" ) ;
171
+ }
172
+ #endif
65
173
}
66
174
67
175
public void Dispose ( )
0 commit comments