Skip to content

Commit 4cb44a7

Browse files
Copilotbrianrob
andauthored
Fix universal symbol conversion for overlapping mappings (#2252)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: brianrob <[email protected]> Co-authored-by: Brian Robbins <[email protected]>
1 parent 4510075 commit 4cb44a7

File tree

1 file changed

+35
-13
lines changed

1 file changed

+35
-13
lines changed

src/TraceEvent/TraceLog.cs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7109,20 +7109,30 @@ internal TraceModuleFile UniversalMapping(ProcessMappingTraceData data, ProcessM
71097109
int index;
71107110

71117111
// A loaded and managed modules depend on a module file, so get or create one.
7112+
// The key is the file name. For jitted code on Linux, this will be a memfd with a static name, which is OK
7113+
// because this path will use the StartAddress to ensure that we get the right one.
71127114
// TODO: We'll need to store FileOffset as well to handle elf images.
71137115
TraceModuleFile moduleFile = process.Log.ModuleFiles.GetOrCreateModuleFile(data.FileName, data.StartAddress);
7114-
moduleFile.imageSize = (long)(data.EndAddress - data.StartAddress);
7116+
long newImageSize = (long)(data.EndAddress - data.StartAddress);
7117+
7118+
// New mappings will have an imageSize of 0 and will get set.
7119+
// Existing mappings that have the same StartAddress but increase in length will get updated here.
7120+
if (moduleFile.imageSize < newImageSize)
7121+
{
7122+
moduleFile.imageSize = newImageSize;
7123+
}
71157124

7116-
// Get or create the loaded module.
7125+
// The loaded module is looked up by StartAddress and time to ensure that we don't use a module that hasn't been loaded yet.
7126+
// If the StartAddress or size don't match, then create a new one. This handles overlapping cases.
71177127
TraceLoadedModule loadedModule = FindModuleAndIndexContainingAddress(data.StartAddress, data.TimeStampQPC, out index);
7118-
if (loadedModule == null)
7119-
{
7128+
if (loadedModule == null || loadedModule.ImageBase != data.StartAddress || loadedModule.ModuleFile.imageSize != newImageSize)
7129+
{
71207130
// The module file is what is used when looking up the module for an arbitrary address, so it must save both the start address and image size.
71217131
loadedModule = new TraceLoadedModule(process, moduleFile, data.StartAddress);
7122-
7123-
// All mappings are enumerated at the beginning of the trace.
7124-
loadedModule.loadTimeQPC = process.Log.sessionStartTimeQPC;
7125-
7132+
7133+
// Set the timestamp from the mapping data
7134+
loadedModule.loadTimeQPC = data.TimeStampQPC;
7135+
71267136
InsertAndSetOverlap(index + 1, loadedModule);
71277137
}
71287138

@@ -7131,6 +7141,7 @@ internal TraceModuleFile UniversalMapping(ProcessMappingTraceData data, ProcessM
71317141
if (managedModule == null)
71327142
{
71337143
managedModule = new TraceManagedModule(process, moduleFile, (long)data.StartAddress);
7144+
managedModule.loadTimeQPC = data.TimeStampQPC;
71347145
modules.Insert(index + 1, managedModule);
71357146
}
71367147

@@ -8525,15 +8536,26 @@ internal void AddUniversalDynamicSymbol(ProcessSymbolTraceData data, TraceProces
85258536
{
85268537
int index;
85278538
TraceLoadedModule loadedModule = process.LoadedModules.FindModuleAndIndexContainingAddress(data.StartAddress, data.TimeStampQPC, out index);
8528-
module = process.LoadedModules.GetOrCreateManagedModule(loadedModule.ModuleID, data.TimeStampQPC);
8529-
moduleFileIndex = module.ModuleFile.ModuleFileIndex;
8530-
methodIndex = methods.NewMethod(data.Name, moduleFileIndex, (int)data.Id);
8539+
8540+
// We should always get a loadedModule here because if we have a symbol, then we should have a module that contains it.
8541+
// Assert so that we can detect bugs here during development.
8542+
Debug.Assert(loadedModule != null, "loadedModule is missing for symbol");
8543+
8544+
if (loadedModule != null)
8545+
{
8546+
module = process.LoadedModules.GetOrCreateManagedModule(loadedModule.ModuleID, data.TimeStampQPC);
8547+
moduleFileIndex = module.ModuleFile.ModuleFileIndex;
8548+
methodIndex = methods.NewMethod(data.Name, moduleFileIndex, (int)data.Id);
8549+
}
85318550

85328551
// When universal traces support re-use of address space, we'll need to support it here.
85338552
}
85348553

8535-
// Set the info
8536-
info.SetMethodIndex(this, methodIndex);
8554+
// Set the info (only if we found a module)
8555+
if (module != null)
8556+
{
8557+
info.SetMethodIndex(this, methodIndex);
8558+
}
85378559
}
85388560
});
85398561
}

0 commit comments

Comments
 (0)