@@ -14,13 +14,20 @@ namespace UnityMixedCallstack
1414 public class UnityMixedCallstackFilter : IDkmCallStackFilter , IDkmLoadCompleteNotification , IDkmModuleInstanceLoadNotification
1515 {
1616 private static List < Range > _rangesSortedByIp = new List < Range > ( ) ;
17+ private static List < Range > _legacyRanges = new List < Range > ( ) ;
1718 private static FuzzyRangeComparer _comparer = new FuzzyRangeComparer ( ) ;
1819 private static bool _enabled ;
1920 private static IVsOutputWindowPane _debugPane ;
20- private static string _currentFile ;
21+ private static Dictionary < int , PmipFile > _currentFiles = new Dictionary < int , PmipFile > ( ) ;
2122 private static FileStream _fileStream ;
2223 private static StreamReader _fileStreamReader ;
2324
25+ struct PmipFile
26+ {
27+ public int count ;
28+ public string path ;
29+ }
30+
2431 public void OnLoadComplete ( DkmProcess process , DkmWorkList workList , DkmEventDescriptor eventDescriptor )
2532 {
2633 DisposeStreams ( ) ;
@@ -30,6 +37,8 @@ public void OnLoadComplete(DkmProcess process, DkmWorkList workList, DkmEventDes
3037 IVsOutputWindow outWindow = Package . GetGlobalService ( typeof ( SVsOutputWindow ) ) as IVsOutputWindow ;
3138 Guid debugPaneGuid = VSConstants . GUID_OutWindowDebugPane ;
3239 outWindow ? . GetPane ( ref debugPaneGuid , out _debugPane ) ;
40+ if ( _debugPane != null )
41+ _debugPane . OutputString ( "MIXEDCALLSTACK WORKS NOW?!\n " ) ;
3342 }
3443 }
3544
@@ -47,12 +56,21 @@ public DkmStackWalkFrame[] FilterNextFrame(DkmStackContext stackContext, DkmStac
4756 if ( ! _enabled ) // environment variable not set
4857 return new [ ] { input } ;
4958
50- return new [ ] { UnityMixedStackFrame ( stackContext , input ) } ;
59+ try
60+ {
61+ DkmStackWalkFrame [ ] retVal = new [ ] { UnityMixedStackFrame ( stackContext , input ) } ;
62+ return retVal ;
63+ } catch ( Exception ex )
64+ {
65+ _debugPane ? . OutputString ( "UNITYMIXEDCALLSTACK :: ip : " + input . Process . LivePart . Id + " threw exception: " + ex . Message + "\n " + ex . StackTrace ) ;
66+ }
67+ return new [ ] { input } ;
5168 }
5269
5370 private static DkmStackWalkFrame UnityMixedStackFrame ( DkmStackContext stackContext , DkmStackWalkFrame frame )
5471 {
5572 RefreshStackData ( frame . Process . LivePart . Id ) ;
73+ _debugPane ? . OutputString ( "UNITYMIXEDCALLSTACK :: done refreshing data\n " ) ;
5674 string name = null ;
5775 if ( TryGetDescriptionForIp ( frame . InstructionAddress . CPUInstructionPart . InstructionPointer , out name ) )
5876 return DkmStackWalkFrame . Create (
@@ -88,96 +106,169 @@ private static void DisposeStreams()
88106 _fileStream ? . Dispose ( ) ;
89107 _fileStream = null ;
90108
91- _currentFile = null ;
92-
93109 _rangesSortedByIp . Clear ( ) ;
94110 }
95111
112+ private static bool CheckForUpdatedFiles ( FileInfo [ ] taskFiles )
113+ {
114+ bool retVal = false ;
115+ try
116+ {
117+ foreach ( FileInfo taskFile in taskFiles )
118+ {
119+ string fName = Path . GetFileNameWithoutExtension ( taskFile . Name ) ;
120+ string [ ] tokens = fName . Split ( '_' ) ;
121+ PmipFile pmipFile = new PmipFile ( )
122+ {
123+ count = int . Parse ( tokens [ 2 ] ) ,
124+ path = taskFile . FullName
125+ } ;
126+
127+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: parsing fName: " + fName + " Tokens length: " + tokens . Length + "\n " ) ;
128+
129+ // 3 is legacy and treat everything as root domain
130+ if ( tokens . Length == 3 &&
131+ ( ! _currentFiles . TryGetValue ( 0 , out PmipFile curFile ) ||
132+ curFile . count < pmipFile . count ) )
133+ {
134+ _currentFiles [ 0 ] = pmipFile ;
135+ retVal = true ;
136+ }
137+ else if ( tokens . Length == 4 )
138+ {
139+ int domainID = int . Parse ( tokens [ 3 ] ) ;
140+ if ( ! _currentFiles . TryGetValue ( domainID , out PmipFile cFile ) || cFile . count < pmipFile . count )
141+ {
142+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: adding pmip file to list: " + pmipFile . path + "\n " ) ;
143+ _currentFiles [ domainID ] = pmipFile ;
144+ retVal = true ;
145+ }
146+ }
147+ }
148+ } catch ( Exception e )
149+ {
150+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: BAD THINGS HAPPEND: " + e . Message + "\n " ) ;
151+ _enabled = false ;
152+ }
153+ return retVal ;
154+ }
155+
96156 private static void RefreshStackData ( int pid )
97157 {
98158 DirectoryInfo taskDirectory = new DirectoryInfo ( Path . GetTempPath ( ) ) ;
99159 FileInfo [ ] taskFiles = taskDirectory . GetFiles ( "pmip_" + pid + "_*.txt" ) ;
100160
161+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: taskfiles length: " + taskFiles . Length + "\n " ) ;
162+
101163 if ( taskFiles . Length < 1 )
102164 return ;
103165
104- Array . Sort ( taskFiles , ( a , b ) => GetFileNameSequenceNum ( a . Name ) . CompareTo ( GetFileNameSequenceNum ( b . Name ) ) ) ;
105- var fileName = taskFiles [ taskFiles . Length - 1 ] . FullName ;
166+ if ( ! CheckForUpdatedFiles ( taskFiles ) )
167+ return ;
106168
107- if ( _currentFile != fileName )
169+ foreach ( PmipFile pmipFile in _currentFiles . Values )
108170 {
171+
172+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: Reading pmip file: " + pmipFile . path + "\n " ) ;
109173 DisposeStreams ( ) ;
110174 try
111175 {
112- _fileStream = new FileStream ( fileName , FileMode . Open , FileAccess . Read , FileShare . ReadWrite | FileShare . Delete ) ;
176+ _fileStream = new FileStream ( pmipFile . path , FileMode . Open , FileAccess . Read , FileShare . ReadWrite | FileShare . Delete ) ;
113177 _fileStreamReader = new StreamReader ( _fileStream ) ;
114- _currentFile = fileName ;
115178 var versionStr = _fileStreamReader . ReadLine ( ) ;
116179 const char delimiter = ':' ;
117180 var tokens = versionStr . Split ( delimiter ) ;
118181
119182 if ( tokens . Length != 2 )
120- throw new Exception ( "Failed reading input file " + fileName + ": Incorrect format" ) ;
183+ throw new Exception ( "Failed reading input file " + pmipFile . path + ": Incorrect format" ) ;
121184
122185 if ( ! double . TryParse ( tokens [ 1 ] , NumberStyles . AllowDecimalPoint , CultureInfo . InvariantCulture , out var version ) )
123- throw new Exception ( "Failed reading input file " + fileName + ": Incorrect version format" ) ;
186+ throw new Exception ( "Failed reading input file " + pmipFile . path + ": Incorrect version format" ) ;
124187
125- if ( version > 1 .0)
126- throw new Exception ( "Failed reading input file " + fileName + ": A newer version of UnityMixedCallstacks plugin is required to read this file" ) ;
188+ if ( version > 2 .0)
189+ throw new Exception ( "Failed reading input file " + pmipFile . path + ": A newer version of UnityMixedCallstacks plugin is required to read this file" ) ;
127190 }
128191 catch ( Exception ex )
129192 {
130- _debugPane ? . OutputString ( "Unable to read dumped pmip file: " + ex . Message + "\n " ) ;
193+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: Unable to read dumped pmip file: " + ex . Message + "\n " ) ;
131194 DisposeStreams ( ) ;
132195 _enabled = false ;
133196 return ;
134197 }
135- }
136198
137- try
138- {
139- string line ;
140- while ( ( line = _fileStreamReader . ReadLine ( ) ) != null )
199+ try
141200 {
142- const char delemiter = ';' ;
143- var tokens = line . Split ( delemiter ) ;
144-
145- //should never happen, but lets be safe and not get array out of bounds if it does
146- if ( tokens . Length != 3 )
147- continue ;
148-
149- var startip = tokens [ 0 ] ;
150- var endip = tokens [ 1 ] ;
151- var description = tokens [ 2 ] ;
152-
153- var startiplong = ulong . Parse ( startip , NumberStyles . HexNumber ) ;
154- var endipint = ulong . Parse ( endip , NumberStyles . HexNumber ) ;
155- _rangesSortedByIp . Add ( new Range ( ) { Name = description , Start = startiplong , End = endipint } ) ;
201+ string line ;
202+ while ( ( line = _fileStreamReader . ReadLine ( ) ) != null )
203+ {
204+ const char delemiter = ';' ;
205+ var tokens = line . Split ( delemiter ) ;
206+
207+ //should never happen, but lets be safe and not get array out of bounds if it does
208+ if ( tokens . Length == 3 || tokens . Length == 4 )
209+ {
210+ string startip = tokens [ 0 ] ;
211+ string endip = tokens [ 1 ] ;
212+ string description = tokens [ 2 ] ;
213+ string file = "" ;
214+ if ( tokens . Length == 4 )
215+ file = tokens [ 3 ] ;
216+
217+ if ( startip . StartsWith ( "---" ) )
218+ {
219+ startip = startip . Remove ( 0 , 3 ) ;
220+ }
221+
222+ var startiplong = ulong . Parse ( startip , NumberStyles . HexNumber ) ;
223+ var endipint = ulong . Parse ( endip , NumberStyles . HexNumber ) ;
224+ if ( tokens [ 0 ] . StartsWith ( "---" ) )
225+ {
226+ // legacy stored in new pmip file
227+ _legacyRanges . Add ( new Range ( ) { Name = description , File = file , Start = startiplong , End = endipint } ) ;
228+ }
229+ else
230+ _rangesSortedByIp . Add ( new Range ( ) { Name = description , File = file , Start = startiplong , End = endipint } ) ;
231+ }
232+ }
233+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: map now has " + _rangesSortedByIp . Count + " entries! legacy map has: " + _legacyRanges . Count + "\n " ) ;
234+ }
235+ catch ( Exception ex )
236+ {
237+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: Unable to read dumped pmip file: " + ex . Message + "\n " ) ;
238+ DisposeStreams ( ) ;
239+ _enabled = false ;
240+ return ;
156241 }
157- }
158- catch ( Exception ex )
159- {
160- _debugPane ? . OutputString ( "Unable to read dumped pmip file: " + ex . Message + "\n " ) ;
161- DisposeStreams ( ) ;
162- _enabled = false ;
163- return ;
164242 }
165243
244+ _legacyRanges . Sort ( ( r1 , r2 ) => r1 . Start . CompareTo ( r2 . Start ) ) ;
166245 _rangesSortedByIp . Sort ( ( r1 , r2 ) => r1 . Start . CompareTo ( r2 . Start ) ) ;
167246 }
168247
169248 private static bool TryGetDescriptionForIp ( ulong ip , out string name )
170249 {
171250 name = string . Empty ;
172251
252+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: Looking for ip: " + String . Format ( "{0:X}" , ip ) + "\n " ) ;
173253 var rangeToFindIp = new Range ( ) { Start = ip } ;
174254 var index = _rangesSortedByIp . BinarySearch ( rangeToFindIp , _comparer ) ;
255+
256+ if ( index >= 0 )
257+ {
258+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: SUCCESS!!\n " ) ;
259+ name = _rangesSortedByIp [ index ] . Name ;
260+ return true ;
261+ }
175262
176- if ( index < 0 )
177- return false ;
263+ index = _legacyRanges . BinarySearch ( rangeToFindIp , _comparer ) ;
264+ if ( index >= 0 )
265+ {
266+ _debugPane ? . OutputString ( "MIXEDCALLSTACK :: LEGACY SUCCESS!! " + String . Format ( "{0:X}" , _legacyRanges [ index ] . Start ) + " -- " + String . Format ( "{0:X}" , _legacyRanges [ index ] . End ) + "\n " ) ;
267+ name = _legacyRanges [ index ] . Name ;
268+ return true ;
269+ }
178270
179- name = _rangesSortedByIp [ index ] . Name ;
180- return true ;
271+ return false ;
181272 }
182273
183274 public void OnModuleInstanceLoad ( DkmModuleInstance moduleInstance , DkmWorkList workList , DkmEventDescriptorS eventDescriptor )
0 commit comments