crashanalysercmd/Libraries/File Formats/Plugins/CrashInfoFilePlugin/FileFormat/CCrashInfoCallStack.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/Libraries/File Formats/Plugins/CrashInfoFilePlugin/FileFormat/CCrashInfoCallStack.cs Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,231 @@
+/*
+* 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 CrashInfoFilePlugin.PluginImplementations.FileFormat;
+
+namespace CrashInfoFilePlugin.FileFormat
+{
+ class CCrashInfoCallStack
+ {
+
+ #region Constructors
+ public CCrashInfoCallStack()
+ {
+
+ }
+ #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 - CrashInfoConsts.KMaxItemAboveSP;
+
+ if (removeAmount > 0)
+ {
+ iCallStack.RemoveRange(0, removeAmount);
+ }
+
+ //Clean symbolless items far below stack pointer
+ for (int i = (int)iStackPointerLocation + CrashInfoConsts.KNonSymbolItemsAfterSP; i < iCallStack.Count; )
+ {
+ if (!iCallStack[i].iHasSymbol)
+ {
+ iCallStack.RemoveAt(i);
+ }
+ else
+ {
+ ++i;
+ }
+ }
+ }
+ }
+
+
+ public void WriteToStream(System.IO.StreamWriter aOutput)
+ {
+ MakeWritableStack();
+
+ aOutput.Write(CCrashInfoFileUtilities.BlockStartMarker(CrashInfoConsts.Kcall_stack_text));
+ System.Text.StringBuilder output = new System.Text.StringBuilder();;
+ foreach (string line in iTextContent)
+ {
+ if (output.Length + line.Length + CrashInfoConsts.KEOL.Length >= CrashInfoConsts.KMaxStackSize)
+ {
+ break;
+ }
+
+ output.AppendLine(line);
+ }
+
+ aOutput.Write(output);
+
+ aOutput.Write((CCrashInfoFileUtilities.BlockEndMarker(CrashInfoConsts.Kcall_stack_text)));
+
+ }
+
+ 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<string> iTextContent = new List<string>();
+
+ private List<CCrashInfoCSItem> iCallStack = new List<CCrashInfoCSItem>();
+ 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