diff -r 7a31f7298d8f -r 0c91f0baec58 crashanalysercmd/Libraries/File Formats/Plugins/XmlFilePlugin/FileFormat/CXmlCallStack.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/Libraries/File Formats/Plugins/XmlFilePlugin/FileFormat/CXmlCallStack.cs Wed Apr 21 09:51:02 2010 +0300 @@ -0,0 +1,227 @@ +/* +* 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 CCrashInfoCallStack is part of CrashAnalyser CrashInfoFile plugin. +* It is a temporary container for thread call stack. +* Call stack is stored in fully decoded form as lines of text +* +*/ + +using System; +using System.Collections.Generic; +using System.Text; +using CrashItemLib.Crash.Stacks; +using CrashItemLib.Crash.Registers; +using CrashItemLib.Crash.Symbols; +using XmlFilePlugin.PluginImplementations.FileFormat; + +namespace XmlFilePlugin.FileFormat +{ + class CXmlCallStack + { + + #region Constructors + public CXmlCallStack() + { + + } + #endregion + + + + public void Read(CIStack aStack) + { + foreach (CIStackEntry entry in aStack) + { + CCrashInfoCSItem csItem = new CCrashInfoCSItem(); + if (entry.IsCurrentStackPointerEntry) + { + iStackPointerLocation = iCallStack.Count; + csItem.iIsStackPointer = true; + } + + CIRegister register = entry.Register; + if (register != null) //entry is from registers + { + csItem.iIsRegisterEntry = true; + if (register.Name == "PC") + { + csItem.iRegisterName = "Program counter"; + } + else if (register.Name == "LR") + { + csItem.iRegisterName = "Link register"; + } + else //other register + { + csItem.iRegisterName = register.Name; + } + } + else //entry is from memory (normal case) + { + csItem.iMemoryAddress = entry.Address; + } + + //Add data contained in the memory location + csItem.iItemData = entry.Data; + csItem.iItemDataString = entry.DataAsString; + + if (entry.Symbol != null) //add symbol if possible + { + csItem.iHasSymbol = true; + csItem.iSymbolName = entry.Symbol.Symbol.Name; + csItem.iSymbolOffset = entry.FunctionOffset; + csItem.iSymbolObject = entry.Symbol.Symbol.Object; + + + } + // else symbol is not available + + iCallStack.Add(csItem); + + } + + } + public void CleanStack() + { + //Clean elements far above stack pointer + if (iStackPointerLocation != null) + { + int removeAmount = (int)iStackPointerLocation - XmlConsts.KMaxItemAboveSP; + + if (removeAmount > 0) + { + iCallStack.RemoveRange(0, removeAmount); + } + + //Clean symbolless items far below stack pointer + for (int i = (int)iStackPointerLocation + XmlConsts.KNonSymbolItemsAfterSP; i < iCallStack.Count; ) + { + if (!iCallStack[i].iHasSymbol) + { + iCallStack.RemoveAt(i); + } + else + { + ++i; + } + } + } + } + + + public override string ToString() + { + MakeWritableStack(); + + System.Text.StringBuilder output = new System.Text.StringBuilder(); + foreach (string line in iTextContent) + { + if (output.Length + line.Length + XmlConsts.Kxml_EOL.Length >= XmlConsts.KMaxStackSize) + { + break; + } + + output.AppendLine(line); + } + return output.ToString(); + + } + + private void MakeWritableStack() + { + + foreach (CCrashInfoCSItem csItem in iCallStack) + { + System.Text.StringBuilder line = new System.Text.StringBuilder(); + if (csItem.iIsStackPointer) + { + line.Append("This is current stack pointer "); + } + + + if (csItem.iIsRegisterEntry) //entry is from registers + { + line.Append(csItem.iRegisterName + " "); + } + else //entry is from memory (normal case) + { + line.Append(csItem.iMemoryAddress.ToString("X").PadLeft(8, '0')); + } + + line.Append(" " + csItem.iItemData.ToString("X").PadLeft(8, '0')); + + + + if (csItem.iHasSymbol) //symbol if available + { + line.Append(" " + csItem.iSymbolName); + + line.Append(" " + csItem.iSymbolOffset.ToString("X").PadLeft(4, '0')); + + line.Append(" " + csItem.iSymbolObject); + } + else //symbol is not available, print content in ascii (may contain some readable text) + { + line.Append(" " + csItem.iItemDataString); + } + iTextContent.Add(line.ToString()); + + } + } + + #region Data Members + + + private List iTextContent = new List(); + + private List iCallStack = new List(); + private int? iStackPointerLocation = null; + #endregion + + #region Nested Classes + private class CCrashInfoCSItem + { + #region Constructors + public CCrashInfoCSItem() + { + + } + #endregion + + #region Data Members + + public uint iMemoryAddress = 0; + public uint iItemData = 0; + public string iItemDataString = string.Empty; + + public bool iIsStackPointer = false; + public bool iIsRegisterEntry = false; + public string iRegisterName = string.Empty; + + public bool iHasSymbol = false; + public string iSymbolName = string.Empty; + public string iSymbolObject = string.Empty; + public uint iSymbolOffset = 0; + + #endregion + } + + #endregion + + } + + + +} \ No newline at end of file