@@ -29,6 +29,7 @@ public sealed class EtwConverterToFirefox : IDisposable
2929 private readonly SymbolReader _symbolReader ;
3030 private readonly ETWTraceEventSource _etl ;
3131 private readonly TraceLog _traceLog ;
32+ private readonly Dictionary < int , string > _threadNames ;
3233 private ModuleFileIndex _clrJitModuleIndex = ModuleFileIndex . Invalid ;
3334 private ModuleFileIndex _coreClrModuleIndex = ModuleFileIndex . Invalid ;
3435 private int _profileThreadIndex ;
@@ -93,6 +94,7 @@ private EtwConverterToFirefox(string traceFilePath, EtwUltraProfilerOptions opti
9394 _mapMethodIndexToFirefox = new ( ) ;
9495 _mapStringToFirefox = new ( StringComparer . Ordinal ) ;
9596 _setManagedModules = new ( ) ;
97+ _threadNames = new ( ) ;
9698 }
9799
98100 /// <inheritdoc />
@@ -118,8 +120,18 @@ public static FirefoxProfiler.Profile Convert(string traceFilePath, EtwUltraProf
118120
119121 private FirefoxProfiler . Profile Convert ( List < int > processIds )
120122 {
123+ _etl . Kernel . ThreadSetName += ( ThreadSetNameTraceData data ) =>
124+ {
125+ if ( ! string . IsNullOrEmpty ( data . ThreadName ) )
126+ {
127+ _threadNames [ data . ThreadID ] = data . ThreadName ;
128+ }
129+ } ;
130+ _etl . Process ( ) ;
131+
132+
121133 // MSNT_SystemTrace/Image/KernelBase - ThreadID="-1" ProcessorNumber="9" ImageBase="0xfffff80074000000"
122-
134+
123135 // We don't have access to physical CPUs
124136 //profile.Meta.PhysicalCPUs = Environment.ProcessorCount / 2;
125137 //profile.Meta.CPUName = ""; // TBD
@@ -206,9 +218,17 @@ private void ConvertProcess(TraceProcess process)
206218 Stack < double > gcRestartEEEvents = new ( ) ;
207219 Stack < ( double , GCEvent ) > gcStartStopEvents = new ( ) ;
208220
209- var threadBaseName = thread . ThreadInfo is not null
210- ? $ "{ thread . ThreadInfo } ({ thread . ThreadID } )"
211- : $ "Thread ({ thread . ThreadID } )";
221+ string threadBaseName ;
222+ if ( ! _threadNames . TryGetValue ( thread . ThreadID , out var dynamicThreadName ) )
223+ {
224+ threadBaseName = thread . ThreadInfo is not null
225+ ? $ "{ thread . ThreadInfo } ({ thread . ThreadID } )"
226+ : $ "Thread ({ thread . ThreadID } )";
227+ }
228+ else
229+ {
230+ threadBaseName = $ "{ dynamicThreadName } ({ thread . ThreadID } )";
231+ }
212232 var threadName = $ "{ threadIndex } - { threadBaseName } ";
213233
214234 var profileThread = new FirefoxProfiler . Thread
@@ -808,7 +828,11 @@ private int ConvertMethod(CodeAddressIndex codeAddressIndex, MethodIndex methodI
808828
809829 if ( methodIndex == MethodIndex . Invalid )
810830 {
811- funcTable . Name . Add ( GetOrCreateString ( $ "0x{ _traceLog . CodeAddresses . Address ( codeAddressIndex ) : X16} ", profileThread ) ) ;
831+ var module = _traceLog . CodeAddresses . ModuleFile ( codeAddressIndex ) ;
832+ string ? moduleName = module ? . Name ;
833+ var absoluteAddress = _traceLog . CodeAddresses . Address ( codeAddressIndex ) ;
834+
835+ funcTable . Name . Add ( GetOrCreateString ( $ "{ moduleName } !0x{ absoluteAddress : X16} ", profileThread ) ) ;
812836 funcTable . IsJS . Add ( false ) ;
813837 funcTable . RelevantForJS . Add ( false ) ;
814838 funcTable . Resource . Add ( - 1 ) ;
0 commit comments