diff -r 7a31f7298d8f -r 0c91f0baec58 crashanalysercmd/Libraries/File Formats/Plugins/XmlFilePlugin/FileFormat/CXmlDataBlock.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/Libraries/File Formats/Plugins/XmlFilePlugin/FileFormat/CXmlDataBlock.cs Wed Apr 21 09:51:02 2010 +0300 @@ -0,0 +1,803 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* The class CCrashInfoDataBlock is part of CrashAnalyser CrashInfoFile plugin. +* Provides reading methods, container and output methods for all data in a single +* datablock of crashinfo file, corresponding to one crash. Complete crashinfo file +* may contain one or more datablock. +* +*/ +using System; +using System.Collections.Generic; +using System.Text; +using CrashItemLib.Crash.Container; +using CrashItemLib.Crash.Base; +using CrashItemLib.Crash.Processes; +using CrashItemLib.Crash.InfoSW; +using CrashItemLib.Crash.Utils; +using System.Globalization; +using CrashItemLib.Crash.Threads; +using CrashItemLib.Crash.Registers; +using CrashItemLib.Crash.Symbols; +using CrashItemLib.Crash.CodeSegs; +using CrashItemLib.Crash.Memory; +using CrashItemLib.Crash.Summarisable; +using CrashItemLib.Crash.InfoHW; +using CrashItemLib.Crash.Telephony; +using CrashItemLib.Crash.Header; +using CrashItemLib.Crash.Reports; +using CrashItemLib.Crash.Stacks; +using XmlFilePlugin.FileFormat; +using CrashItemLib.Crash.Source; +using CrashItemLib.Crash.Events; +using CrashItemLib.Crash.Messages; +using System.IO; +using CrashItemLib.Crash.Traces; +using SymbianStructuresLib.Debug.Trace; +using CrashItemLib.Crash.InfoEnvironment; +using ErrorLibrary; +using MobileCrashLib; + +namespace XmlFilePlugin.PluginImplementations.FileFormat +{ + internal class CXmlDataBlock + { + #region Constructors + public CXmlDataBlock() + + { + } + + #endregion + + #region Adding data content + /** Add timestamp and uptime */ + internal void AddHeader(CIContainer aContainer) + { + CIHeader header = (CIHeader) aContainer.ChildByType( typeof( CIHeader ) ); + if (header != null) + { + //Timestamp + DateTime timeStamp = header.CrashTime; + String date = timeStamp.ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo); + int hour = timeStamp.Hour; + int minute = timeStamp.Minute; + int second = timeStamp.Second; + iTimeStampText = date + hour.ToString().PadLeft(2, '0') + minute.ToString().PadLeft(2, '0') + second.ToString().PadLeft(2, '0'); + + //UpTime + iUptime = header.UpTime.TotalSeconds; + + // Crash source + iCrashSource = header.CrashSource; + } + } + /** Add romid, timestamp, platform, language and sw version */ + internal void AddSWInfos(CIContainer aContainer) + { + CIInfoSW info = (CIInfoSW) aContainer.ChildByType( typeof( CIInfoSW ) ); + if (info != null) + { + //RomID + if (info.ImageCheckSum != 0) + { + iRomId = info.ImageCheckSum; + } + //Platform + iPlatform = info.Platform; + + //Language + iLanguage = info.Language; + + //Version + const string KInfoSW_Version_Runtime = "Runtime Version"; + const string KInfoSW_Version_Variant = "Variant Version"; + const string KInfoSW_Version_S60 = "S60 Version"; + foreach ( CIVersionInfo version in info ) + { + if (version.IsValid && version.Name == KInfoSW_Version_Runtime) + { + iSWVersion = version.Value; + } + if (version.IsValid && version.Name == KInfoSW_Version_Variant) + { + iVariantVersion = version.Value; + } + if (version.IsValid && version.Name == KInfoSW_Version_S60) + { + iS60Version = version.Value; + } + } + + //Timestamp + DateTime timeStamp = info.ImageTimeStamp; + String date = timeStamp.ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo); + int hour = timeStamp.Hour; + int minute = timeStamp.Minute; + int second = timeStamp.Second; + iTimeStampText = date + hour.ToString().PadLeft(2, '0') + minute.ToString().PadLeft(2, '0') + second.ToString().PadLeft(2, '0'); + + } + } + + + + internal void AddThreadAndExitInfo(CIContainer aContainer) + { + + CIElementList threads = aContainer.ChildrenByType( CIElement.TChildSearchType.EEntireHierarchy ); + if (threads.Count > 1) + { + System.Console.WriteLine("Warning: XmlFilePlugin found multiple threads. XML file output can handle only one thread!"); + } + foreach (CIThread thread in threads) + { + iPanicCategory = thread.ExitInfo.Category; + iPanicID = thread.ExitInfo.Reason; + iPanicDescription = XmlErrorLibrary.GetPanicDescription(iPanicCategory, iPanicID.ToString()); + iCrashedModuleName = thread.FullName; + } + + } + + internal void AddPanicedProcess(CIContainer aContainer) + { + CIElementList processes = aContainer.ChildrenByType(CIElement.TChildSearchType.EEntireHierarchy); + if (processes.Count > 1) + { + System.Console.WriteLine("Warning: CrashInfoFilePlugin found multiple processes. CI file output can handle only one process!"); + } + foreach (CIProcess process in processes) + { + iProcess = process.Name; + iUID = process.Uids.MostSignificant; + } + + } + + internal void AddRegisterLists(CIContainer aContainer) + { + CIElementList regListCols = aContainer.ChildrenByType(CIElement.TChildSearchType.EEntireHierarchy); + foreach (CIRegisterListCollection regListCol in regListCols) + { + foreach (CIRegisterList regList in regListCol) + { + iRegStorage.ReadRegisterData(regList); + } + } + + } + + internal void AddStacks(CIContainer aContainer) + { + CIElementList stacks = aContainer.ChildrenByType(CIElement.TChildSearchType.EEntireHierarchy); + foreach (CIStack stack in stacks) + { + CXmlCallStack callStack = new CXmlCallStack(); + callStack.Read(stack); + callStack.CleanStack(); + iCallStacks.Add(callStack); + + } + } + + internal void AddCodeSegments(CIContainer aContainer) + { + // Get the code segments + CIElementList codeSegs = aContainer.ChildrenByType(CIElement.TChildSearchType.EEntireHierarchy); + + // Sort them + Comparison comparer = delegate(CICodeSeg aLeft, CICodeSeg aRight) + { + return string.Compare(aLeft.Name, aRight.Name, true); + }; + codeSegs.Sort(comparer); + + // List them + foreach (CICodeSeg codeSeg in codeSegs) + { + uint start = codeSeg.Range.Min; + uint end = codeSeg.Range.Max; + string name = codeSeg.Name; + + CXmlCodeSegItem ciCodeSeg = new CXmlCodeSegItem(start, end, name); + iCodeSegs.Add(ciCodeSeg); + } + } + + internal void AddMemoryInfo(CIContainer aContainer) + { + CIElementList list = aContainer.ChildrenByType(CIElement.TChildSearchType.EEntireHierarchy); + foreach ( CIMemoryInfo info in list ) + { + if ( info.Type == CIMemoryInfo.TType.ETypeRAM ) + { + iFreeMomery = info.Free; + } + if (info.Type == CIMemoryInfo.TType.ETypeDrive) + { + iDiskInfo = info.Free; + } + } + } + + internal void AddHWInfo(CIContainer aContainer) + { + CIInfoHW info = (CIInfoHW)aContainer.ChildByType(typeof(CIInfoHW)); + if (info != null) + { + iProductType = info.ProductType; + iProductCode = info.ProductCode.Trim(); + iSerialNumber = info.SerialNumber.Trim(); + iProductionMode = info.ProductionMode; + } + } + + internal void AddTelephony(CIContainer aContainer) + { + CITelephony info = (CITelephony)aContainer.ChildByType(typeof(CITelephony)); + if (info != null) + { + iPhoneNumber = info.PhoneNumber; + iImei = info.IMEI; + iImsi = info.IMSI; + + CITelephonyNetworkInfo networkInfo = info.NetworkInfo; + + iNetworkCountry = networkInfo.Country; + iNetworkIdentity = networkInfo.Identity; + iNetworkCell = networkInfo.CellId; + iLocInfo = networkInfo.CGI; + + } + + } + + internal void AddEnvInfo(CIContainer aContainer) + { + CIInfoEnvironment info = (CIInfoEnvironment)aContainer.ChildByType(typeof(CIInfoEnvironment)); + if (info != null) + { + iTestSet = info.TestSet; + } + + } + + internal void AddReportParameters(CIContainer aContainer) + { + CIReportInfo report = (CIReportInfo)aContainer.ChildByType(typeof(CIReportInfo)); + if (report != null) + { + iReportType = report.Type; + if (iReportType != string.Empty) + { + iFileType = XmlConsts.MobileCrashFileType.ETypeCrashAPIReport; + } + + + iReportCategory = report.Category; + iReportOK = report.CountSuccess; + iReportFail = report.CountFail; + IEnumerator parameters = report.GetEnumerator(); + if (parameters.MoveNext()) //has first parameter + { + iReportParamName1 = parameters.Current.Name; + iReportParamValue1 = parameters.Current.Value; + + if (parameters.MoveNext()) //has second parameter + { + iReportParamName2 = parameters.Current.Name; + iReportParamValue2 = parameters.Current.Value; + if (parameters.MoveNext()) + { + iReportParamName3 = parameters.Current.Name; + iReportParamValue3 = parameters.Current.Value; + } + } + } + + iReportComments = report.Comments; + + } + + } + + internal void AddMessages(CIContainer container) + { + foreach (CIMessage message in container.Messages) + { + if (message.Title == "Miscellaneous Information") + { + + if (message.Description.Trim() == XmlConsts.KRegistrationMiscInfo) + { + iFileType = XmlConsts.MobileCrashFileType.ETypeRegistrationMessage; + } + if (message.Description.Trim() == XmlConsts.KAliveTimeMiscInfo) + { + iFileType = XmlConsts.MobileCrashFileType.ETypeAliveMessage; + } + } + } + } + + internal void AddCrashHash(CIContainer aContainer) + { + //hash is only calculated for normal crashes - registrations and reports are omitted + if (iFileType == XmlConsts.MobileCrashFileType.ETypeBasicCrash) + { + CISummarisableEntity primarySummary = aContainer.PrimarySummary; + if (primarySummary != null) + { + MobileCrashHashBuilder.TConfiguration config = MobileCrashHashBuilder.TConfiguration.EDefault; + try //CCrashInfoHashBuilder.New throws an exception if there's not enough data for hash creation + { + MobileCrashHashBuilder builder = MobileCrashHashBuilder.New(config, primarySummary); + iHash = builder.GetHash(); + } + catch (Exception /* e */) + { + //Not enough data -> no hash and no grouping + } + } + } + } + + internal void AddFileNames(CIContainer aContainer, string aArchivedFileName) + + { + iBinFilename = aArchivedFileName; + + CISource source = aContainer.Source; + string binFileOriginalName = source.MasterFileName; + + foreach (string filename in aContainer.FileNames) + { + if (filename != binFileOriginalName) //Since bin file name is stored separately, remove it from this list + { + iSymbolFiles.Add(filename); + } + } + + } + internal void AddEventlog(CIContainer aContainer) + { + CIEventList events = aContainer.Events; + foreach (CIEvent ev in events) + { + + iEventlog.Add(ev.Value.ToString()); + } + } + + + internal void AddOstTraces(CIContainer aContainer) + { + CITraceData traceData = aContainer.Traces; + // + if (traceData != null && traceData.Lines.Length > 0) + { + foreach (CITrace ciTrace in traceData) + { + System.Text.StringBuilder line = new System.Text.StringBuilder(); + + TraceLine trace = ciTrace; + + // Type + string type = string.Empty; + switch (trace.Type) + { + case TraceLine.TType.ETypeBinary: + type = "Bin"; + break; + case TraceLine.TType.ETypeRaw: + type = "Raw"; + break; + case TraceLine.TType.ETypeText: + type = "Text"; + break; + default: + type = "Unknown"; + break; + } + if (string.IsNullOrEmpty(type) == false) + { + line.Append(type); + } + + // Context id + if (trace.ContextId != 0) + { + line.Append(" " + "0x" + trace.ContextId.ToString("x8")); + } + + // Time stamp + line.Append(" " + trace.TimeStamp.ToString()); + + // Prefix + string prefix = trace.Prefix; + if (string.IsNullOrEmpty(prefix) == false) + { + line.Append(" " + prefix); + } + + // Suffix + string suffix = trace.Suffix; + if (string.IsNullOrEmpty(suffix) == false) + { + line.Append(" " + suffix); + } + + if (trace.HasIdentifier) + { + // Component/group/id triplet + TraceIdentifier identifier = trace.Identifier; + line.Append(" C:" + "0x" + identifier.Component.ToString("x8")); + line.Append(" G:" + identifier.Group.ToString()); + line.Append(" I:" + identifier.Id.ToString()); + // File & line + TraceLocation location = identifier.Location; + // + string file = location.File; + string lineNumber = location.Line.ToString(); + // + if (string.IsNullOrEmpty(file) == false && string.IsNullOrEmpty(lineNumber) == false) + { + line.Append(" " +file); + line.Append(":" + lineNumber); + } + } + + // Payload + string payload = trace.Payload; + line.Append(" " + payload); + iOstTraces.Add(line.ToString()); + } + } + } + + #endregion + + #region Getters + + internal XmlConsts.MobileCrashFileType FileType() + { + return iFileType; + } + + internal string GetMiscInfo() + { + string mInfo = "NotFound"; + if (iFileType == XmlConsts.MobileCrashFileType.ETypeRegistrationMessage) + { + mInfo = XmlConsts.KRegistrationMiscInfo; + } + if (iFileType == XmlConsts.MobileCrashFileType.ETypeAliveMessage) + { + mInfo = XmlConsts.KAliveTimeMiscInfo; + } + return mInfo; + } + + internal string TimeStampText() + { + return iTimeStampText; + } + + internal uint? RomId() + { + return iRomId; + } + + internal string Platform() + { + return iPlatform; + } + + internal string SWVersion() + { + return iSWVersion; + } + + internal string S60Version() + { + return iS60Version; + } + + internal string VariantVersion() + { + return iVariantVersion; + } + + internal int? PanicId() + { + return iPanicID; + } + + internal string PanicCategory() + { + return iPanicCategory; + } + + internal string PanicDescription() + { + return iPanicDescription; + } + + internal string Language() + { + return iLanguage; + } + + internal string Process() + { + return iProcess; + } + + internal CXmlRegisterStorage RegStorage() + { + return iRegStorage; + } + + internal string CrashedModuleName() + { + return iCrashedModuleName; + } + + internal List CodeSegs() + { + return iCodeSegs; + } + + internal ulong? FreeMemory() + { + return iFreeMomery; + } + + internal string ProductType() + { + return iProductType; + } + + internal int? ProductionMode() + { + return iProductionMode; + } + + internal int? CrashSource() + { + return iCrashSource; + } + + internal string ProductCode() + { + return iProductCode; + } + + internal string SerialNumber() + { + return iSerialNumber; + } + + internal string PhoneNumber() + { + return iPhoneNumber; + } + + internal string Imei() + { + return iImei; + } + + internal string Imsi() + { + return iImsi; + } + + internal string NetworkCountry() + { + return iNetworkCountry; + } + + internal string NetworkIdentity() + { + return iNetworkIdentity; + } + + internal string NetworkCell() + { + return iNetworkCell; + } + + internal string LocInfo() + { + return iLocInfo; + } + + internal string TestSet() + { + return iTestSet; + } + + internal double? Uptime() + { + return iUptime; + } + + internal uint? UID() + { + return iUID; + } + + internal ulong? DiskInfo() + { + return iDiskInfo; + } + + internal string ReportType() + { + return iReportType; + } + + internal string ReportCategory() + { + return iReportCategory; + } + + internal uint? ReportOK() + { + return iReportOK; + } + + internal uint? ReportFail() + { + return iReportFail; + } + + internal string ReportParamName1() + { + return iReportParamName1; + } + + internal uint? ReportParamValue1() + { + return iReportParamValue1; + } + + internal string ReportParamName2() + { + return iReportParamName2; + } + + internal uint? ReportParamValue2() + { + return iReportParamValue2; + } + + internal string ReportParamName3() + { + return iReportParamName3; + } + + internal uint? ReportParamValue3() + { + return iReportParamValue3; + } + + internal string ReportComments() + { + return iReportComments; + } + + internal string Hash() + { + return iHash; + } + + internal List CallStacks() + { + return iCallStacks; + } + + internal string BinFilename() + { + return iBinFilename; + } + + internal List SymbolFiles() + { + return iSymbolFiles; + } + + internal List Eventlog() + { + return iEventlog; + } + + internal List OstTraces() + { + return iOstTraces; + } + + #endregion + + #region Data members + private XmlConsts.MobileCrashFileType iFileType = XmlConsts.MobileCrashFileType.ETypeBasicCrash; + + private string iTimeStampText = string.Empty; //YearMonthDayHourMinSec + private uint? iRomId = null; //aka rom's checksum word + private string iPlatform = string.Empty; //usually SOS + private string iSWVersion = string.Empty; //The "main" version number + private string iS60Version = string.Empty; + private string iVariantVersion = string.Empty; + + private int? iPanicID = null; + private string iPanicCategory = string.Empty; + private string iPanicDescription = string.Empty; + + private string iLanguage = string.Empty; //english, finnish etc + + private string iProcess = string.Empty; + + private CXmlRegisterStorage iRegStorage = new CXmlRegisterStorage(); //registers + + private string iCrashedModuleName = string.Empty; //thread name + + private List iCodeSegs = new List(); //crash time loaded dlls + + private ulong? iFreeMomery = null; //free ram + + private string iProductType = string.Empty; //aka RM-code + private string iProductCode = string.Empty; //7-digit HW variant code + private string iSerialNumber = string.Empty; //aka PSN + private int? iProductionMode = null; // 1: production mode phone, 0: RnD phone + private int? iCrashSource = null; // 1: crash from user side, 0: from kernel side. + + private string iPhoneNumber = "NotFound"; + private string iImei = string.Empty; + private string iImsi = string.Empty; + private string iNetworkCountry = string.Empty; + private string iNetworkIdentity = string.Empty; + private string iNetworkCell = string.Empty; + private string iLocInfo = string.Empty; + private string iTestSet = string.Empty; + private double? iUptime = null; + private uint? iUID = null; + private ulong? iDiskInfo = null; + private string iReportType = string.Empty; + private string iReportCategory = string.Empty; + private uint? iReportOK = null; + private uint? iReportFail = null; + private string iReportParamName1 = string.Empty; + private uint? iReportParamValue1 = null; + private string iReportParamName2 = string.Empty; + private uint? iReportParamValue2 = null; + private string iReportParamName3 = string.Empty; + private uint? iReportParamValue3 = null; + private string iReportComments = string.Empty; + private string iHash = string.Empty; + + private List iCallStacks = new List(); //Call stacks + + private string iBinFilename = string.Empty; + List iSymbolFiles = new List(); + List iEventlog = new List(); + List iOstTraces = new List(); + + #endregion + + + + } +}