crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianETMLib/ETB/StackRecon/ETBStack.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 *
       
    16 */
       
    17 
       
    18 using System;
       
    19 using System.Collections.Generic;
       
    20 using System.Text;
       
    21 using SymbianETMLib.Common.Engine;
       
    22 using SymbianETMLib.Common.Config;
       
    23 using SymbianETMLib.Common.Types;
       
    24 using SymbianETMLib.Common.Utilities;
       
    25 using SymbianStructuresLib.Arm;
       
    26 using SymbianStructuresLib.Arm.Exceptions;
       
    27 
       
    28 namespace SymbianETMLib.ETB.StackRecon
       
    29 {
       
    30     internal class ETBStack
       
    31     {
       
    32         #region Constructors
       
    33         public ETBStack( ETEngineBase aEngine, uint aContextId )
       
    34         {
       
    35             iEngine = aEngine;
       
    36             iContextId = aContextId;
       
    37         }
       
    38         #endregion
       
    39 
       
    40         #region API
       
    41         internal void HandleBranch( ETMBranch aBranch )
       
    42         {
       
    43             TETBStackEntry last = LastEntry;
       
    44             if ( last != null )
       
    45             {
       
    46                 TETBStackEntry entry = new TETBStackEntry( aBranch );
       
    47                 //
       
    48                 if ( last.SymbolAddress == entry.SymbolAddress )
       
    49                 {
       
    50                     if ( entry.SymbolOffset > last.SymbolOffset )
       
    51                     {
       
    52                         // Internal branch? E.g. if statement, or loop?
       
    53                     }
       
    54                     else
       
    55                     {
       
    56                         PushBranch( entry );
       
    57                     }
       
    58                 }
       
    59                 else if ( aBranch.SymbolAddressOffset == 0 && aBranch.Symbol != null )
       
    60                 {
       
    61                     // Guess: calling a new function
       
    62                     PushBranch( entry );
       
    63                 }
       
    64                 else
       
    65                 {
       
    66                     bool save = true;
       
    67 
       
    68                     // Check if we have branched back to an earlier function without
       
    69                     // popping back through the call stack
       
    70                     int count = iEntries.Count;
       
    71                     for ( int i = count - 2; i >= 0; i-- )
       
    72                     {
       
    73                         last = iEntries[ i ];
       
    74                         if ( last.SymbolAddress == entry.SymbolAddress )
       
    75                         {
       
    76                             if ( entry.SymbolOffset > last.SymbolOffset )
       
    77                             {
       
    78                                 // We appear to have jumped back to a calling function - so
       
    79                                 // discard later items on stack.
       
    80                                 int deleteCount = count - i - 1;
       
    81                                 iEntries.RemoveRange( i + 1, deleteCount );
       
    82                                 save = false;
       
    83                                 break;
       
    84                             }
       
    85                         }
       
    86                     }
       
    87 
       
    88                     if ( save )
       
    89                     {
       
    90                         PushBranch( entry );
       
    91                     }
       
    92                 }
       
    93             }
       
    94             else
       
    95             {
       
    96                 PushBranch( aBranch );
       
    97             }
       
    98         }
       
    99         #endregion
       
   100 
       
   101         #region Properties
       
   102         public uint ContextId
       
   103         {
       
   104             get { return iContextId; }
       
   105         }
       
   106 
       
   107         public string ContextName
       
   108         {
       
   109             get { return iEngine.Config.GetContextID( iContextId ); }
       
   110         }
       
   111         #endregion
       
   112 
       
   113         #region Internal class
       
   114         private class TETBStackEntry
       
   115         {
       
   116             #region Constructors
       
   117             public TETBStackEntry( ETMBranch aBranch )
       
   118             {
       
   119                 iBranch = aBranch;
       
   120             }
       
   121 
       
   122             #endregion
       
   123 
       
   124             #region API
       
   125             public void Print()
       
   126             {
       
   127                 string text = iBranch.ToString( iDepth );
       
   128                 System.Console.WriteLine( text );
       
   129             }
       
   130             #endregion
       
   131 
       
   132             #region Properties
       
   133             public uint SymbolAddress
       
   134             {
       
   135                 get
       
   136                 { 
       
   137                     uint ret = 0;
       
   138                     //
       
   139                     if ( iBranch.Symbol != null )
       
   140                     {
       
   141                         ret = (uint) iBranch.Symbol.Address;
       
   142                     }
       
   143                     //
       
   144                     return ret;
       
   145                 }
       
   146             }
       
   147 
       
   148             public uint SymbolOffset
       
   149             {
       
   150                 get { return iBranch.SymbolAddressOffset; }
       
   151             }
       
   152 
       
   153             public int Depth
       
   154             {
       
   155                 get { return iDepth; }
       
   156                 set { iDepth = value; }
       
   157             }
       
   158 
       
   159             public bool IsUnknown
       
   160             {
       
   161                 get
       
   162                 {
       
   163                     return ( iBranch.Symbol == null );
       
   164                 }
       
   165             }
       
   166             #endregion
       
   167 
       
   168             #region From System.Object
       
   169             public override string ToString()
       
   170             {
       
   171                 StringBuilder t = new StringBuilder();
       
   172                 t.AppendFormat( "0x{0} [+{1:x4}] {2}", iBranch.Address.AddressHex, iBranch.SymbolAddressOffset, iBranch.SymbolText );
       
   173                 return t.ToString();
       
   174             }
       
   175             #endregion
       
   176 
       
   177             #region Data members
       
   178             private readonly ETMBranch iBranch;
       
   179             private int iDepth = 0;
       
   180             #endregion
       
   181         }
       
   182         #endregion
       
   183 
       
   184         #region Internal methods
       
   185         private void PushBranch( TETBStackEntry aEntry )
       
   186         {
       
   187             if ( aEntry.IsUnknown == false )
       
   188             {
       
   189                 int lastDepth = 0;
       
   190                 //
       
   191                 TETBStackEntry lastEntry = LastEntry;
       
   192                 if ( lastEntry != null )
       
   193                 {
       
   194                     lastDepth = lastEntry.Depth + 1;
       
   195                 }
       
   196                 //
       
   197                 aEntry.Depth = lastDepth;
       
   198             }
       
   199             iEntries.Add( aEntry );
       
   200             aEntry.Print();
       
   201         }
       
   202 
       
   203         private void PushBranch( ETMBranch aBranch )
       
   204         {
       
   205             TETBStackEntry entry = new TETBStackEntry( aBranch );
       
   206             PushBranch( entry );
       
   207         }
       
   208 
       
   209         private TETBStackEntry LastEntry
       
   210         {
       
   211             get
       
   212             {
       
   213                 TETBStackEntry ret = null;
       
   214                 //
       
   215                 int count = iEntries.Count;
       
   216                 if ( count > 0 )
       
   217                 {
       
   218                     ret = iEntries[ count - 1 ];
       
   219                 }
       
   220                 //
       
   221                 return ret;
       
   222             }
       
   223         }
       
   224         #endregion
       
   225 
       
   226         #region Data members
       
   227         private readonly ETEngineBase iEngine;
       
   228         private readonly uint iContextId;
       
   229         private List<TETBStackEntry> iEntries = new List<TETBStackEntry>();
       
   230         #endregion
       
   231     }
       
   232 }