crashanalysercmd/Libraries/File Formats/Plugins/CrashInfoFilePlugin/FileFormat/CCrashInfoCallStack.cs
changeset 0 818e61de6cd1
equal deleted inserted replaced
-1:000000000000 0:818e61de6cd1
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 * 
       
    14 * Description:
       
    15 * The class CCrashInfoCallStack is part of CrashAnalyser CrashInfoFile plugin.
       
    16 * It is a temporary container for thread call stack.
       
    17 * Call stack is stored in fully decoded form as lines of text
       
    18 * 
       
    19 */
       
    20 
       
    21 using System;
       
    22 using System.Collections.Generic;
       
    23 using System.Text;
       
    24 using CrashItemLib.Crash.Stacks;
       
    25 using CrashItemLib.Crash.Registers;
       
    26 using CrashItemLib.Crash.Symbols;
       
    27 using CrashInfoFilePlugin.PluginImplementations.FileFormat;
       
    28 
       
    29 namespace CrashInfoFilePlugin.FileFormat
       
    30 {
       
    31     class CCrashInfoCallStack
       
    32     {
       
    33 
       
    34         #region Constructors
       
    35         public CCrashInfoCallStack()
       
    36         {
       
    37 
       
    38         }
       
    39         #endregion
       
    40 
       
    41 
       
    42 
       
    43         public void Read(CIStack aStack)
       
    44         {
       
    45             foreach (CIStackEntry entry in aStack)
       
    46             {
       
    47                 CCrashInfoCSItem csItem = new CCrashInfoCSItem();
       
    48                 if (entry.IsCurrentStackPointerEntry)
       
    49                 {
       
    50                     iStackPointerLocation = iCallStack.Count;
       
    51                     csItem.iIsStackPointer = true;
       
    52                 }
       
    53 
       
    54                 CIRegister register = entry.Register;
       
    55                 if (register != null) //entry is from registers
       
    56                 {
       
    57                     csItem.iIsRegisterEntry = true;
       
    58                     if (register.Name == "PC")
       
    59                     {
       
    60                         csItem.iRegisterName = "Program counter";
       
    61                     }
       
    62                     else if (register.Name == "LR")
       
    63                     {
       
    64                         csItem.iRegisterName = "Link register";
       
    65                     }
       
    66                     else //other register
       
    67                     {
       
    68                         csItem.iRegisterName = register.Name;
       
    69                     }
       
    70                 }
       
    71                 else //entry is from memory (normal case)
       
    72                 {
       
    73                     csItem.iMemoryAddress = entry.Address;
       
    74                 }
       
    75 
       
    76                 //Add data contained in the memory location
       
    77                 csItem.iItemData = entry.Data;
       
    78                 csItem.iItemDataString = entry.DataAsString;
       
    79 
       
    80                 if (entry.Symbol != null) //add symbol if possible
       
    81                 {
       
    82                     csItem.iHasSymbol = true;
       
    83                     csItem.iSymbolName = entry.Symbol.Symbol.Name;
       
    84                     csItem.iSymbolOffset = entry.FunctionOffset;
       
    85                     csItem.iSymbolObject = entry.Symbol.Symbol.Object;
       
    86 
       
    87                 
       
    88                 }
       
    89                 // else symbol is not available
       
    90 
       
    91                 iCallStack.Add(csItem);
       
    92 
       
    93             }
       
    94 
       
    95         }
       
    96         public void CleanStack()
       
    97         {   
       
    98             //Clean elements far above stack pointer
       
    99             if (iStackPointerLocation != null)
       
   100             {
       
   101                 int removeAmount = (int)iStackPointerLocation - CrashInfoConsts.KMaxItemAboveSP;
       
   102                                
       
   103                 if (removeAmount > 0)
       
   104                 {
       
   105                     iCallStack.RemoveRange(0, removeAmount);
       
   106                 }
       
   107 
       
   108                 //Clean symbolless items far below stack pointer
       
   109                 for (int i = (int)iStackPointerLocation + CrashInfoConsts.KNonSymbolItemsAfterSP; i < iCallStack.Count; )
       
   110                 {
       
   111                     if (!iCallStack[i].iHasSymbol)
       
   112                     {                        
       
   113                         iCallStack.RemoveAt(i);
       
   114                     }
       
   115                     else
       
   116                     {
       
   117                         ++i;
       
   118                     }
       
   119                 }
       
   120             }
       
   121         }
       
   122           
       
   123 
       
   124         public void WriteToStream(System.IO.StreamWriter aOutput)
       
   125         {
       
   126             MakeWritableStack();
       
   127             
       
   128             aOutput.Write(CCrashInfoFileUtilities.BlockStartMarker(CrashInfoConsts.Kcall_stack_text));
       
   129             System.Text.StringBuilder output = new System.Text.StringBuilder();;
       
   130             foreach (string line in iTextContent)
       
   131             {
       
   132                 if (output.Length + line.Length + CrashInfoConsts.KEOL.Length >= CrashInfoConsts.KMaxStackSize)
       
   133                 {
       
   134                     break;
       
   135                 }
       
   136 
       
   137                 output.AppendLine(line);
       
   138             }
       
   139 
       
   140             aOutput.Write(output);
       
   141 
       
   142             aOutput.Write((CCrashInfoFileUtilities.BlockEndMarker(CrashInfoConsts.Kcall_stack_text)));
       
   143 
       
   144         }
       
   145               
       
   146         private void MakeWritableStack()
       
   147         {
       
   148 
       
   149             foreach (CCrashInfoCSItem csItem in iCallStack)
       
   150             {
       
   151                 System.Text.StringBuilder line = new System.Text.StringBuilder();
       
   152                 if (csItem.iIsStackPointer)
       
   153                 {
       
   154                     line.Append("This is current stack pointer ");
       
   155                 }
       
   156 
       
   157 
       
   158                 if (csItem.iIsRegisterEntry) //entry is from registers
       
   159                 {
       
   160                     line.Append(csItem.iRegisterName + " ");
       
   161                 }
       
   162                 else //entry is from memory (normal case)
       
   163                 {
       
   164                     line.Append(csItem.iMemoryAddress.ToString("X").PadLeft(8, '0'));
       
   165                 }
       
   166 
       
   167                 line.Append(" " + csItem.iItemData.ToString("X").PadLeft(8, '0'));
       
   168 
       
   169 
       
   170 
       
   171                if (csItem.iHasSymbol) //symbol if available
       
   172                {
       
   173                    line.Append(" " + csItem.iSymbolName);
       
   174 
       
   175                    line.Append(" " + csItem.iSymbolOffset.ToString("X").PadLeft(4, '0'));
       
   176 
       
   177                    line.Append(" " + csItem.iSymbolObject);
       
   178                }
       
   179                else //symbol is not available, print content in ascii (may contain some readable text)
       
   180                {
       
   181                    line.Append(" " + csItem.iItemDataString);
       
   182                }               
       
   183                iTextContent.Add(line.ToString());
       
   184                 
       
   185            }
       
   186         }
       
   187 
       
   188         #region Data Members
       
   189 
       
   190 
       
   191         private List<string> iTextContent = new List<string>();
       
   192 
       
   193         private List<CCrashInfoCSItem> iCallStack = new List<CCrashInfoCSItem>();
       
   194         private int? iStackPointerLocation = null;
       
   195         #endregion
       
   196 
       
   197         #region Nested Classes
       
   198         private class CCrashInfoCSItem
       
   199         {
       
   200             #region Constructors
       
   201             public CCrashInfoCSItem()
       
   202             {
       
   203 
       
   204             }
       
   205             #endregion
       
   206 
       
   207             #region Data Members
       
   208 
       
   209             public uint iMemoryAddress = 0;
       
   210             public uint iItemData = 0;
       
   211             public string iItemDataString = string.Empty;
       
   212 
       
   213             public bool iIsStackPointer = false;
       
   214             public bool iIsRegisterEntry = false;
       
   215             public string iRegisterName = string.Empty;
       
   216             
       
   217             public bool iHasSymbol = false;
       
   218             public string iSymbolName = string.Empty;
       
   219             public string iSymbolObject = string.Empty;
       
   220             public uint iSymbolOffset = 0;
       
   221 
       
   222             #endregion
       
   223         }
       
   224 
       
   225         #endregion
       
   226    
       
   227     }
       
   228 
       
   229     
       
   230 
       
   231 }