internal KeyDisplayRepresentation GetThreadDisplayValue(EventEntry ee) { KeyDisplayRepresentation result; switch (MexCore.TheCore.Options.ThreadDisplayOption) { case ThreadDisplayMode.UseDotNetThread: result = new KeyDisplayRepresentation(ee.CurrentThreadKey, ee.ThreadNetId); break; case ThreadDisplayMode.UseOSThread: result = new KeyDisplayRepresentation(ee.CurrentThreadKey, ee.ThreadID); break; case ThreadDisplayMode.DefaultUseThreadNameAndOS: if (ThreadNames.ContainsKey(ee.CurrentThreadKey)) { result = new KeyDisplayRepresentation(ee.CurrentThreadKey, ThreadNames[ee.CurrentThreadKey] + " on " + ee.ThreadID); } else { result = new KeyDisplayRepresentation(ee.CurrentThreadKey, ee.ThreadNetId + " on " + ee.ThreadID); } break; case ThreadDisplayMode.ShowFullInformation: if (ThreadNames.ContainsKey(ee.CurrentThreadKey)) { result = new KeyDisplayRepresentation(ee.CurrentThreadKey, ThreadNames[ee.CurrentThreadKey] + " on " + ee.ThreadNetId + " on os: " + ee.ThreadID); } else { result = new KeyDisplayRepresentation(ee.CurrentThreadKey, "Unknown on " + ee.ThreadNetId + " on os: " + ee.ThreadID); } break; default: throw new InvalidOperationException("This code should not be reachable"); } return(result); }
/// <summary> /// Primary filter method for known event entries. The event entry passed is compared to the filter settings and a boolean returned indicating whether /// or not it should be displayed based on the current filter settings. The event entry will also be updated to reflect the current filter settings /// so that the next time it is studied unless the filter has changed the answer is the same /// </summary> /// <param name="ee">the event entry to determine whether it should be displayed or not</param> /// <returns>Bool indicating whether or not to display the entry.</returns> internal bool IncludeThisEventEntry(EventEntry ee) { // Enable the caching on the objects themselves. This costs ram but should be way faster for most types of filter. // This routine only applies the last used filter however IF the filter is more complex than the cmd type test which is already optimised. if (ee.LastVisitedFilter == m_currentFilterIndex) { return(ee.LastVisitedFilterResult); } bool result = false; // Cache this filter index so until the filter changes this event entry can be processed rapidly. ee.LastVisitedFilter = m_currentFilterIndex; result = this.BaseIncludeEventEntry(ee); ee.LastVisitedFilterResult = result; return(result); }
internal bool ApplyDefaultHighlighting(EventEntry ee) { foreach (Coloring cr in DefaultHighlightColoring) { if (cr.matchCase.Length > 0) { if (ee.ThreadID == cr.matchCase) { bool highlightIsTheSame = ee.ViewData.isValid; highlightIsTheSame = highlightIsTheSame && ((ee.ViewData.isForegroundHighlighted && cr.ForeColorSpecified) && (ee.ViewData.foregroundHighlightColor == cr.foregroundColor)); highlightIsTheSame = highlightIsTheSame && ((ee.ViewData.isBackgroundHighlighted && cr.BackColorSpecified) && (ee.ViewData.backgroundHighlightColor == cr.backgroundColor)); if (highlightIsTheSame) { // There was a match made but it was already applied to this element. Therefore no changes. return(false); } else { if (cr.ForeColorSpecified) { ee.ViewData.foregroundHighlightColor = cr.foregroundColor; ee.ViewData.isForegroundHighlighted = true; } if (cr.BackColorSpecified) { ee.ViewData.backgroundHighlightColor = cr.backgroundColor; ee.ViewData.isBackgroundHighlighted = true; } ee.ViewData.isValid = true; return(true); } } } } return(false); }
/// <summary> /// When an event entry is to be added to the traced application this method is used - this will /// insert the event entry and then ensure that it is set active if the application itself is active. /// If the application itself is not active then an exception will be thrown. /// </summary> /// <param name="newone"></param> internal int AddEventEntry(EventEntry newone) { #region entry code //Bilge.Assert(newone != null, "cant add null event entry"); #endregion int idx = EventEntries.Add(newone); this.TimeLastMessageRecvd = newone.m_timeMessageRecieved; if (newone.cmdType == TraceCommandTypes.MoreInfo) { // If this command is a more info then tell the command before it that it has more info. if (idx > 0) { // Its possible that we start mex at a bad moment. EventEntries[idx - 1].HasMoreInfo = true; } } return(idx); } // End TracedApplication::AddEventEntry
private bool BaseIncludeEventEntry(EventEntry ee) { /* filter created in order of most likely reasons to fail therefore for performance tried to shift the types to the top then the * inclusion / exclusion fitlers as these will be used the most. Ive optimised this to be a single comparison so it should be very * quick. */ if ((m_flagsForInclude & (uint)ee.cmdType) != (uint)ee.cmdType) { return(false); } // Performance cache to stop checking all of the complex filters in the default scenario. Basically the default scenario only // filters on type therefore all of the good stuff coming up is pointless. if (!m_filterMoreComplexThanType) { return(true); } // Now we check for the more complicated filtering options such as index filtering if (m_useIndexBasedFilters) { if (UseBelowThisFilter) { if (ee.GlobalIndex < ExcludeEventsBelowThisIndex) { return(false); } } if (UseAboveThisFilter) { if (ee.GlobalIndex > ExcludeEventsAboveThisIndex) { return(false); } } } if ((m_inclusionStrings != null) && (m_inclusionStrings.Count > 0)) { // check for inclusion strings string debugCheckString; if (m_caseSensitive) { debugCheckString = ee.DebugMessage; } else { debugCheckString = ee.DebugMessage.ToLower(); } for (int i = 0; i < m_inclusionStrings.Count; i++) { if (debugCheckString.IndexOf(m_inclusionStrings[i]) >= 0) { ee.LastVisitedFilter = m_currentFilterIndex; return(true); // matched one of the inclusion strings } } // End for each of the inclusion strings return(false); // none of the inclusion strings matched } // end if there are inclusionStrings to worry about if ((m_exclusionStrings != null) && (m_exclusionStrings.Count > 0)) { // check for exclusion strings string exclusionCheckString; if (m_caseSensitive) { exclusionCheckString = ee.DebugMessage; } else { exclusionCheckString = ee.DebugMessage.ToLower(); } for (int i = 0; i < m_exclusionStrings.Count; i++) { if (exclusionCheckString.IndexOf(m_exclusionStrings[i]) >= 0) { ee.LastVisitedFilter = m_currentFilterIndex; ee.LastVisitedFilterResult = false; return(false); // found a rejected one } } }// end if there are exclusion strings to worry about //Bilge.Assert(ee.Module != null, "The module value should not be null when checked by the filter, it should be empty if not known"); if ((m_excludedModules != null) && (ee.Module.Length > 0)) { //Bilge.Assert(m_excludedModules.Count > 0, "There should not be a module list of 0 entries"); if (m_excludedModules.Contains(ee.Module)) { return(false); } } //Bilge.Assert(ee.CurrentThreadKey != null, "The thread id for an event entry should not be null when checked by the filter, if its not known it should be empty"); if ((m_excludedThreads != null) && (ee.CurrentThreadKey.Length > 0)) { //Bilge.Assert(m_excludedThreads.Count > 0, "The threads to be excluded should not be of length 0"); // check for threads we specifically dont include. This allows new threads to arrive and be included if (KeyDisplayRepresentation.ContainsKey(m_excludedThreads, ee.CurrentThreadKey)) // return true if its NOT in the exclusions { return(false); } } //Bilge.Assert(ee.MoreLocationData != null, "The additional location data should not be null when checked by the filter, if its not known it should be empty"); if ((m_excludedLocationsClass != null) && (ee.MoreLocationData.Length > 0)) { //Bilge.Assert(m_excludedLocationsClass.Count > 0, "This should not be callable when the number of excluded locations by class is 0"); int offsetOfColons = ee.MoreLocationData.IndexOf("::"); if (offsetOfColons > 0) { // There is a class look alike string locForEntry = ee.MoreLocationData.Substring(0, offsetOfColons); if (m_excludedLocationsClass.Contains(locForEntry)) { return(false); } } } if ((m_excludedLocationsFull != null) && (ee.MoreLocationData.Length > 0)) { //Bilge.Assert(m_excludedLocationsFull.Count > 0, "This should not be callable when the number of excluded locations is 0"); ee.LastVisitedFilter = m_currentFilterIndex; if (m_excludedLocationsFull.Contains(ee.MoreLocationData)) // return true if its NOT in the exclusions { return(false); } } return(true); }
internal bool ModifyEventEntryForHighlight(EventEntry ee) { // first check to see if there is any highlight data. if ((HighlightRequests == null) || (HighlightRequests.Count == 0)) { if ((ee.ViewData.isValid) && (ee.ViewData.isHighlighted)) { ee.ViewData.isHighlighted = false; return(true); } return(false); } // end if the highlight data is null or empty // ok now onto checking for the highlight data itself. foreach (AHighlightRequest ahr in HighlightRequests) { bool matchMade = false; if (ahr.MakeMatchUsingType) { if ((ee.cmdType & ahr.matchTct) == ee.cmdType) { matchMade = true; } } if ((!matchMade) && ahr.MakeMatchUsingString) { string eventEntryCombinedString = ee.DebugMessage + "#X#" + ee.SecondaryMessage + "#X#" + ee.Module + "#X#" + ee.CurrentThreadKey; if (!ahr.CaseSensitive) { ahr.ComparisonStringToMatchOn = ahr.ComparisonStringToMatchOn.ToLower(); eventEntryCombinedString = eventEntryCombinedString.ToLower(); } if (ahr.NotMatch) { matchMade = eventEntryCombinedString.IndexOf(ahr.ComparisonStringToMatchOn) < 0; } else { matchMade = eventEntryCombinedString.IndexOf(ahr.ComparisonStringToMatchOn) >= 0; } } if (matchMade) { //Bilge.Warning("PERF Warning, would be more efficient to use ViewData highlight caching rather than this comparison, or for best perf use both"); // Split this out into a few lines as it was getting too complex to read. Essentially we judge that the highlight is the same only if // the specifictions and the colors are the same between the desired highlight and the existing highlight. bool highlightIsTheSame = ee.ViewData.isValid; highlightIsTheSame = highlightIsTheSame && ((ee.ViewData.isForegroundHighlighted && ahr.ForeColorSpecified) && (ee.ViewData.foregroundHighlightColor == ahr.ForegroundColor)); highlightIsTheSame = highlightIsTheSame && ((ee.ViewData.isBackgroundHighlighted && ahr.BackColorSpecified) && (ee.ViewData.backgroundHighlightColor == ahr.BackgroundColor)); if (highlightIsTheSame) { // There was a match made but it was already applied to this element. Therefore no changes. return(false); } else { if (ahr.ForeColorSpecified) { ee.ViewData.foregroundHighlightColor = ahr.ForegroundColor; ee.ViewData.isForegroundHighlighted = true; } if (ahr.BackColorSpecified) { ee.ViewData.backgroundHighlightColor = ahr.BackgroundColor; ee.ViewData.isBackgroundHighlighted = true; } ee.ViewData.isValid = true; return(true); } } // end if there was a match made } // end for each of the highlights to apply // if we get here then there was no match for the current highlight selection. if ((ee.ViewData.isValid) && (ee.ViewData.isHighlighted)) { ee.ViewData.isHighlighted = false; return(true); } else { return(false); } }
/// <summary> /// called when there are messages queued ready to be added to the data manager - this method will take either the next one or all available /// pending messaged from the queue and add it to the data structures that atre used to store the information. /// </summary> public void ProcessNextStoredMessage(bool doAll, bool reporting) { if (m_incommingMsgQueue.Count == 0) { //Bilge.Warning("WARNING INNEFFICIENT --> ProcessNextStoredMessage Called when there are no messages on queue INC_CHECKDUPEJOBS"); return; } #if DUAL if (rapc == null) { rapc = RawEntryParserChain.CreateChain(RawEntryParserChain.VAL_LINK + RawEntryParserChain.V2_LINK + RawEntryParserChain.LEG_LINK + RawEntryParserChain.ALL_LINK, store); } if (dp == null) { dp = new DataParser(store, rapc, comparer); } #endif List <int> appIndexesAffectedByImport = new List <int>(); DateTime startTime = DateTime.Now; // how long have we been running DateTime overallStartTime = DateTime.Now; FileStream everythingStream = null; StreamWriter everythingLog = null; if (MexCore.TheCore.Options.PersistEverything) { everythingStream = new FileStream(MexCore.TheCore.Options.CurrentFilename, FileMode.Append, FileAccess.Write); everythingLog = new StreamWriter(everythingStream); } try { do { if (m_shutdownRequested) { //Bilge.Log("Aborting import as shutdown has been requested."); break; } // we have a piece of work #if !DEBUG // We only want this catch block in release code, to at least try and find out whats gone wrong, in debug code we want it // to simply explode. try { #endif IncomingEventStore nextEvent = (IncomingEventStore)m_incommingMsgQueue.Dequeue(); if (MexCore.TheCore.Options.PersistEverything) { everythingLog.WriteLine("\"" + nextEvent.MachineName + "\",\"" + nextEvent.Pid + "\",\"" + nextEvent.MessageString + "\",\"" + "DE\""); } if (MexCore.TheCore.Options.RemoveDuplicatesOnImport) { bool dupeFound = true; while ((dupeFound) && (m_incommingMsgQueue.Count > 0)) { IncomingEventStore potentialNext = (IncomingEventStore)m_incommingMsgQueue.Peek(); dupeFound = potentialNext.Equals(nextEvent); if (dupeFound) { // Throw the dupe away. m_incommingMsgQueue.Dequeue(); } } } #if DUAL RawApplicationEvent rae = new RawApplicationEvent() { ArrivalTime = nextEvent.TimeRecieved, OriginId = store.GetOriginIdentity(nextEvent.MachineName, nextEvent.Pid.ToString()), Machine = nextEvent.MachineName, Process = nextEvent.Pid.ToString(), Text = nextEvent.MessageString }; dp.AddRawEvent(rae); #endif EventEntry ee = null; string tempMachineName = null; bool legacyMode = false; bool isCommand = false; // firstly is this a truncation ? if (nextEvent.MessageString.StartsWith(Constants.MESSAGETRUNCATE)) { #region This message was a truncation of the previous one, deal with it like that // This is a truncation, it should be added to the last message that was added to the process with the same pid. //Bilge.Warning("WARNING INNEFFICIENT --> Looking for non existant GI Sux in timed view could cache this -> Global Index " + nextEvent.GlobalIndex.ToString() + " skipped as its a truncate message"); int endMachineNameIdx = nextEvent.MessageString.IndexOf(']'); int startMachineNameIdx = Constants.MESSAGETRUNCATE.Length + 1; // 1 is for length of "[" int endUniqueIdIdx = nextEvent.MessageString.IndexOf(Constants.TRUNCATE_DATAENDMARKER); if ((endMachineNameIdx < 0) || (startMachineNameIdx < 0) || (endUniqueIdIdx < 0)) { //Bilge.Warning("WARNING --> INVAID truncate join string found, probably old version of//Bilge. Ignoring this command."); MexCore.TheCore.ViewManager.AddUserNotificationMessageByIndex(ViewSupportManager.UserMessages.InvalidTruncateStringFound, ViewSupportManager.UserMessageType.WarningMessage, null); return; } string machineName = nextEvent.MessageString.Substring(startMachineNameIdx, endMachineNameIdx - startMachineNameIdx); string truncateUniqueJoinId = nextEvent.MessageString.Substring(endMachineNameIdx + 2, (endUniqueIdIdx - (endMachineNameIdx + 2))); bool anotherExpected = nextEvent.MessageString.EndsWith(Constants.MESSAGETRUNCATE); ee = MexCore.TheCore.CacheManager.CacheGet_EventEntryExpectingTruncate(nextEvent.Pid, machineName, truncateUniqueJoinId, !anotherExpected); if (ee == null) { // This can only happen following a purge i guess //Bilge.Warning("ProcessNextStoredMessage --> WARNING --> Invalid truncation message found. Couldnt find the EE in the structure to append this trunc to. Skipping it"); return; } // Patch it together, removing the truncate markers from the middle. if ((ee.SecondaryMessage != null) && (ee.SecondaryMessage.Length > 0)) { ee.SecondaryMessage = ee.SecondaryMessage.Substring(0, (ee.SecondaryMessage.Length - Constants.MESSAGETRUNCATE.Length)) + nextEvent.MessageString.Substring(Constants.MESSAGETRUNCATE.Length); } else { ee.SetDebugMessage(ee.DebugMessage.Substring(0, (ee.DebugMessage.Length - Constants.MESSAGETRUNCATE.Length)) + nextEvent.MessageString.Substring(Constants.MESSAGETRUNCATE.Length)); } #endregion continue; } // If we get here then this message is not a truncation so its either an ODS or Tex message // If it was not a truncation its either a message from another app or a tex message if (!TraceMessageFormat.IsTexString(nextEvent.MessageString)) { // Horrid workaround but whatever, patched this in after the code will refactor in phase 2 if (TraceMessageFormat.IsLegacyTexString(nextEvent.MessageString)) { legacyMode = true; goto LEGACYSUPPORT; } // if its not tex the assumption is that it has always come from this machine, although if mex gets v clever this could change NonTracedApplicationEntry newNte = new NonTracedApplicationEntry(nextEvent.Pid, nextEvent.MessageString, nextEvent.GlobalIndex); if ((MexCore.TheCore.Options.XRefMatchingProcessIdsIntoEventEntries) && (MexCore.TheCore.DataManager.IsPidAKnownApplication(nextEvent.Pid, nextEvent.MachineName))) { // We need to check whether or not this came form the same PID if it did we need to cross reference it. ee = EventEntry.CreatePseudoEE(nextEvent.GlobalIndex, nextEvent.MessageString); tempMachineName = nextEvent.MachineName; if (MexCore.TheCore.Options.XRefReverseCopyEnabled) { // If were doing cross references by PID then we need to determine whether to dupe into the NTA list too. MexCore.TheCore.DataManager.PlaceUnknownEventIntoDataStructure(newNte); } // else we just throw away the NTA as its really a traced app malformed message } else { MexCore.TheCore.DataManager.PlaceUnknownEventIntoDataStructure(newNte); continue; } } // The goto bypasses the non legacy code LEGACYSUPPORT: int nextLogicalIndexAffected = -1; if (ee == null) { // Must be at least close to legit string as it passed our validation. Therefore we create a new known event entry and provide it with // the required information to be stored in the traced applications. string tempCommandType; string tempPid; int tPid; string tempDebugMessage; ee = new EventEntry(nextEvent.GlobalIndex); // Create new entry giving it next index ee.m_timeMessageRecieved = nextEvent.TimeRecieved; if (legacyMode) { TraceMessageFormat.ReturnPartsOfStringLegacy(nextEvent.MessageString, out tempCommandType, out tempPid, out tempMachineName, out ee.ThreadID, out ee.Module, out ee.LineNumber, out tempDebugMessage); ee.ThreadNetId = "??"; ee.MoreLocationData = "LegacyTexSupport"; legacyMode = false; } else { TraceMessageFormat.ReturnPartsOfString(nextEvent.MessageString, out tempCommandType, out tempPid, out ee.ThreadNetId, out tempMachineName, out ee.ThreadID, out ee.Module, out ee.LineNumber, out ee.MoreLocationData, out tempDebugMessage); } tPid = int.Parse(tempPid); ee.SetDebugMessage(tempDebugMessage); // Checks for secondary data and splits accordingly TraceCommandTypes tct = TraceCommands.StringToTraceCommand(tempCommandType); if (tct == TraceCommandTypes.CommandXML) { TracedApplication additionalDataTracedApp = GetTracedApplicationWithCreate(tempMachineName, tPid); additionalDataTracedApp.SetStatusContentsFromXml(tempDebugMessage); nextLogicalIndexAffected = additionalDataTracedApp.VirtualIndex; isCommand = true; } else { if ((tct == TraceCommandTypes.MoreInfo) && (tempDebugMessage.StartsWith(Constants.DATAINDICATOR))) { // Data indicator messages include things like the initialisation strings sent when you call//Bilge.Initialise() - this is where additional // information is given about the process and additionally where things like the intitialisation / partial purge on init takes place. TracedApplication additionalDataTracedApp = GetTracedApplicationWithCreate(tempMachineName, tPid); #region Data indicator messages are not imported, they change the viewer behaviour. tempDebugMessage = tempDebugMessage.Substring(Constants.DATAINDICATOR.Length); ee.DebugMessage = ee.DebugMessage.Substring(Constants.DATAINDICATOR.Length); // Chopped off ~~DATA:: switch (ee.DebugMessage[0]) { case 'P': //ProcessName // If they have specified their own preferred name for the application then it is passed through here, this preferred name // should replace most of the alternative views. if ((ee.SecondaryMessage != null) && (ee.SecondaryMessage.Length > 0)) { additionalDataTracedApp.PreferredName = ee.SecondaryMessage; } // The process name is contained in ProcessName() string actualAppName = ee.DebugMessage.Substring(Consts.PROCNAMEIDENT_PREFIX.Length); actualAppName = actualAppName.Substring(0, (actualAppName.Length - Consts.PROCNAMEIDENT_POSTFIX.Length)); ee.DebugMessage = actualAppName; if (MexCore.TheCore.Options.XRefAppInitialiseToMain) { // If this option is selected we place a message into the unknown events to indicate that theres an Xref occured MexCore.TheCore.DataManager.PlaceUnknownEventIntoDataStructure(new NonTracedApplicationEntry(tPid, "Process " + actualAppName + " Started with pid : (" + tPid.ToString() + ")", nextEvent.GlobalIndex)); } if (MexCore.TheCore.Options.AutoPurgeApplicationOnMatchingName) { // BUG!!! Omg too dumb. Realised only after coding this that if oyu add autopurge as a job option it kicks // in after the import and then purges all of the new messages. Aysnchthink ftw. //Bilge.Log("Synchronous Purge By Matching Name starting. Trying to purge name " + actualAppName, "However skipping new pid which is " + tPid); MexCore.TheCore.DataManager.PurgeByName(actualAppName, tempMachineName, tPid); //MexCore.TheCore.WorkManager.ProcessJob(new Job_PartialPurgeApp(tempMachineName,tPid)); //Bilge.Log("Synchronous Purge By Matching Name Completes."); } additionalDataTracedApp.ProcessName = actualAppName; MexCore.TheCore.WorkManager.AddJob(new Job_NotifyKnownProcessUpdate(MexCore.TheCore.ViewManager.SelectedTracedAppIdx)); break; case 'M': //MainModule additionalDataTracedApp.MainModule = ee.DebugMessage; break; case 'W': additionalDataTracedApp.WindowTitle = ee.DebugMessage; break; case 'I': // Initialise(MachineName\appName) skipped. string initName = ee.DebugMessage.Substring(10, ee.DebugMessage.Length - 10); additionalDataTracedApp.AssemblyFullName = ee.SecondaryMessage; additionalDataTracedApp.InitialiseName = initName; ee.DebugMessage = initName; break; case 'C': // Calling Assembly string assemblyData = tempDebugMessage.Substring(16, tempDebugMessage.Length - 17); additionalDataTracedApp.CallingAssemblyInfo = assemblyData; break; case 'E': // Executing Assembly assemblyData = tempDebugMessage.Substring(18, tempDebugMessage.Length - 19); additionalDataTracedApp.ExecutingAssemblyInfo = assemblyData; break; case 'T': // ThreadName //Bilge.Warning("Not Implemented, thread name request recieved but this functionality is not implemented in MEX yet"); break; default: //Bilge.Assert(false, "This should not be possible, we should never reach this bit of code."); break; } #endregion continue; } // End if it starts with a data indicator // If we get here its a Tex message that is not a data indicator // This is looking like a normal message. IE Not a moreinfo / data string if (nextEvent.Pid == -1) { nextEvent.Pid = int.Parse(tempPid); } ee.cmdType = tct; // Some messages can be cross referenced into the main view if the options say that. This section deals with // creating the duplicate messages for this cross reference to work. #region support cross references to main view based on type of event if (MexCore.TheCore.Options.XRefAssertionsToMain && ee.cmdType == TraceCommandTypes.AssertionFailed) { MexCore.TheCore.DataManager.PlaceUnknownEventIntoDataStructure(new NonTracedApplicationEntry(tPid, ee.DebugMessage, ee.GlobalIndex)); } if (MexCore.TheCore.Options.XRefErrorsToMain && ee.cmdType == TraceCommandTypes.ErrorMsg) { MexCore.TheCore.DataManager.PlaceUnknownEventIntoDataStructure(new NonTracedApplicationEntry(tPid, ee.DebugMessage, ee.GlobalIndex)); } if (MexCore.TheCore.Options.XRefExceptionsToMain && ee.cmdType == TraceCommandTypes.ExceptionBlock) { MexCore.TheCore.DataManager.PlaceUnknownEventIntoDataStructure(new NonTracedApplicationEntry(tPid, ee.DebugMessage, ee.GlobalIndex)); } if (MexCore.TheCore.Options.XRefLogsToMain && ee.cmdType == TraceCommandTypes.LogMessage) { MexCore.TheCore.DataManager.PlaceUnknownEventIntoDataStructure(new NonTracedApplicationEntry(tPid, ee.DebugMessage, ee.GlobalIndex)); } if (MexCore.TheCore.Options.XRefVerbLogsToMain && ee.cmdType == TraceCommandTypes.LogMessageVerb) { MexCore.TheCore.DataManager.PlaceUnknownEventIntoDataStructure(new NonTracedApplicationEntry(tPid, ee.DebugMessage, ee.GlobalIndex)); } if (MexCore.TheCore.Options.XRefResourceMessagesToMain) { if ((ee.cmdType == TraceCommandTypes.ResourceEat) || (ee.cmdType == TraceCommandTypes.ResourcePuke) || (ee.cmdType == TraceCommandTypes.ResourceCount)) { MexCore.TheCore.DataManager.PlaceUnknownEventIntoDataStructure(new NonTracedApplicationEntry(tPid, ee.DebugMessage, ee.GlobalIndex)); } } if (MexCore.TheCore.Options.XRefWarningsToMain && ee.cmdType == TraceCommandTypes.WarningMsg) { MexCore.TheCore.DataManager.PlaceUnknownEventIntoDataStructure(new NonTracedApplicationEntry(tPid, ee.DebugMessage, ee.GlobalIndex)); } #endregion if (tempDebugMessage.EndsWith(Constants.MESSAGETRUNCATE)) { //Bilge.Log("IncommingMessageManager::ProcessNextStoredMessage --> Truncation message found, storing event for future"); // Truncated messages end with #TNK#JoinID#TNK# this lets us join them back together using the unique join id - however // joinIds are only unique per process/machien therefore all of this info is used as a key. int idxStart = tempDebugMessage.IndexOf(Constants.MESSAGETRUNCATE) + Constants.MESSAGETRUNCATE.Length; string joinIdentifier = tempDebugMessage.Substring(idxStart, tempDebugMessage.Length - (idxStart + Constants.MESSAGETRUNCATE.Length)); MexCore.TheCore.CacheManager.CacheAdd_EventEntryExpectingTruncate(ee, nextEvent.Pid, tempMachineName, joinIdentifier); } } } // End if it was a normal tex message (ee==null) if (!isCommand) { //Bilge.Assert(ee != null, "The event entry must be populated by now in the code"); // Whether or not it was a cross reference its imported into the data structures now. //Bilge.Assert(tempMachineName != null, "machine name must be populated by the time we add it to the data structures"); ee.SupportingData = SupportingMessageData.ParseAsMessageData(ee.cmdType, ref ee.DebugMessage, ref ee.SecondaryMessage); MexCore.TheCore.ViewManager.CurrentHighlightOptions.ModifyEventEntryForHighlight(ee); // *************** Actually add it into the structure here *************** nextLogicalIndexAffected = MexCore.TheCore.DataManager.PlaceNewEventIntoDataStructure(ee, nextEvent.Pid, tempMachineName); } if (!appIndexesAffectedByImport.Contains(nextLogicalIndexAffected)) { appIndexesAffectedByImport.Add(nextLogicalIndexAffected); } #if DUAL if (!comparer.Compare(ee)) { // This is our porting code, if this fires then we have got a problem with our new parser. //Bilge.WarningLog("FAILED A COMPARISON"); throw new InvalidOperationException("The new parser is out of sync"); } #endif #if !DEBUG } catch (Exception ex) { //Bilge.Dump(ex, "IncommingMessageManager::ProcessNextStoredMessage Trying to process a string from the stack, lost string during processing."); // DO NOT SWALLOW THIS!, results in an infinite loop throw; } #endif if (reporting) { // For long running imports make sure that we tell the client side every now and again TimeSpan ts = DateTime.Now - startTime; if ((ts.TotalSeconds > MexCore.TheCore.Options.NoSecondsForRefreshOnImport)) { startTime = DateTime.Now; TimeSpan overall = DateTime.Now - overallStartTime; MexCore.TheCore.ViewManager.AddUserNotificationMessageByIndex(ViewSupportManager.UserMessages.MessageImportLongRunning, ViewSupportManager.UserMessageType.InformationMessage, overall.TotalSeconds.ToString() + "s elapsed."); foreach (int appAffectedIdx in appIndexesAffectedByImport) { MexCore.TheCore.WorkManager.ProcessJob(new Job_NotifyNewEventAdded(appAffectedIdx)); } } } } while ((m_incommingMsgQueue.Count > 0) && (doAll)); } finally { if (MexCore.TheCore.Options.PersistEverything) { everythingLog.Close(); everythingStream.Close(); everythingLog.Dispose(); everythingStream.Dispose(); } } foreach (int appAffectedIdx in appIndexesAffectedByImport) { MexCore.TheCore.WorkManager.AddJob(new Job_NotifyNewEventAdded(appAffectedIdx)); } }