crashanalysercmd/Libraries/File Formats/Plugins/XmlFilePlugin/FileFormat/CXmlDataBlock.cs
changeset 2 0c91f0baec58
child 3 045ade241ef5
--- /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<CIThread> threads = aContainer.ChildrenByType<CIThread>( 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<CIProcess> processes = aContainer.ChildrenByType<CIProcess>(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<CIRegisterListCollection> regListCols = aContainer.ChildrenByType<CIRegisterListCollection>(CIElement.TChildSearchType.EEntireHierarchy);
+            foreach (CIRegisterListCollection regListCol in regListCols)
+            {
+                foreach (CIRegisterList regList in regListCol)
+                {                                      
+                    iRegStorage.ReadRegisterData(regList);     
+                }
+            }
+
+        }
+
+        internal void AddStacks(CIContainer aContainer)
+        {
+            CIElementList<CIStack> stacks = aContainer.ChildrenByType<CIStack>(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<CICodeSeg> codeSegs = aContainer.ChildrenByType<CICodeSeg>(CIElement.TChildSearchType.EEntireHierarchy);
+
+            // Sort them
+            Comparison<CICodeSeg> 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<CIMemoryInfo> list = aContainer.ChildrenByType<CIMemoryInfo>(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<CIReportParameter> 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<CXmlCodeSegItem> 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<CXmlCallStack> CallStacks()
+        {
+             return iCallStacks;
+        }
+
+        internal string BinFilename()
+        {
+            return iBinFilename;
+        }
+
+        internal List<string> SymbolFiles()
+        {
+            return iSymbolFiles;
+        }
+
+        internal List<string> Eventlog()
+        {
+            return iEventlog;
+        }
+
+        internal List<string> 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<CXmlCodeSegItem> iCodeSegs = new List<CXmlCodeSegItem>(); //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<CXmlCallStack> iCallStacks = new List<CXmlCallStack>(); //Call stacks
+
+        private string iBinFilename = string.Empty;
+        List<string> iSymbolFiles = new List<string>();
+        List<string> iEventlog = new List<string>();
+        List<string> iOstTraces = new List<string>();
+
+        #endregion
+
+
+
+    }
+}