crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Parsers/State/Implementation/Stacks/StateThreadStacks.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Parsers/State/Implementation/Stacks/StateThreadStacks.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,146 @@
+/*
+* Copyright (c) 2004-2008 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: 
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using SymbianParserLib.Engine;
+using SymbianParserLib.BaseStructures;
+using CrashDebuggerLib.Structures.CodeSeg;
+using CrashDebuggerLib.Structures.Thread;
+using CrashDebuggerLib.Structures.Process;
+using CrashDebuggerLib.Structures.KernelObjects;
+using CrashDebuggerLib.Threading;
+using SymbianParserLib.Elements;
+using SymbianParserLib.Enums;
+
+namespace CrashDebuggerLib.Parsers.State.Implementation
+{
+    internal class StateThreadStacks : State
+    {
+        #region Constructors
+        public StateThreadStacks( CrashDebuggerParser aParser )
+            : base( aParser )
+        {
+        }
+        #endregion
+
+        #region API
+        public override void Prepare()
+        {
+            // First, we need to know which thread we're dealing with
+            // so that means we must look for the thread info
+            ParserParagraph para = new ParserParagraph( "STACK_THREAD_INFO" );
+            //
+            ParserLine l1 = ParserLine.NewSymFormat( "STACK DATA for thread at %8x" );
+            l1.SetTargetMethod( this, "SetThreadAddress" );
+            para.Add( l1 );
+            ParserEngine.Add( para );
+        }
+
+        public override void Finalise()
+        {
+            if ( iCurrentThread != null )
+            {
+                if ( iCurrentThread.OwningProcess != null )
+                {
+                    iCurrentThread.OwningProcess.PrepareDebugView();
+                }
+                //
+                iCurrentThread.StackInfoUser.Data.BuildCallStackAsync();
+                iCurrentThread.StackInfoSupervisor.Data.BuildCallStackAsync();
+            }
+        }
+        #endregion
+
+        #region Properties
+        #endregion
+
+        #region Internal methods
+        private void SetThreadAddress( uint aAddress )
+        {
+            // Look for the thread which we're about to process...
+            iCurrentThread = CrashDebugger.ThreadByAddress( aAddress );
+            if ( iCurrentThread != null )
+            {
+                // Next we must start to process code segments for this
+                // thread. These lines contain additional information about
+                // the run address of the code segments, relative to the process.
+                ParserParagraph para = new ParserParagraph( "STACK_THREAD_INFO_CODESEGS" );
+                //
+                ParserLine l1 = ParserLine.NewSymFormat( "CodeSeg[%03d/%03d] @ %08x - %08X-%08X %S" );
+                l1.ElementComplete += new ParserElementBase.ElementCompleteHandler( CodeSegmentLineComplete );
+                //
+                para.Add( l1 );
+                ParserEngine.Add( para );
+            }
+        }
+
+        void CodeSegmentLineComplete( ParserElementBase aElement )
+        {
+            System.Diagnostics.Debug.Assert( iCurrentThread != null );
+            ParserLine line = (ParserLine) aElement;
+            //
+            int index = line[ 0 ].AsInt;
+            int count = line[ 1 ].AsInt;
+            uint codeSegAddress = line[ 2 ].AsUint;
+            uint startAddress = line[ 3 ].AsUint;
+            uint endAddress = line[ 4 ].AsUint;
+            string fileName = line[ 5 ].AsString;
+            //
+            DProcess process = iCurrentThread.OwningProcess;
+            if ( process != null )
+            {
+                ProcessCodeSegCollection codeSegs = process.CodeSegments;
+                ProcessCodeSeg codeSeg = codeSegs[ codeSegAddress ];
+                //
+                if ( codeSeg == null )
+                {
+                    // The code seg is not directly part of the process handle list
+                    // but it is some how mapped into the process?
+                    //
+                    // Try looking up the underlying code seg entry details from
+                    // the crash debugger data itself. It should be part of the code
+                    // seg listing so this should always work.
+                    codeSeg = new ProcessCodeSeg( CrashDebugger, codeSegAddress, 0 );
+                    process.CodeSegments.Add( codeSeg );
+                }
+                //
+                codeSeg.ProcessLocalRunAddress = startAddress;
+                codeSeg.Size = ( endAddress - startAddress );
+            }
+            //
+            int remaining = count - index;
+            if ( remaining == 0 )
+            {
+                // Queue up stack data...
+                iHelperStack.CreateStackParagraphs( ParserEngine, iCurrentThread );
+            }
+            else
+            {
+                // So that we capture the next line
+                aElement.SetRepetitions( 1 );
+            }
+        }
+        #endregion
+
+        #region Data members
+        private DThread iCurrentThread = null;
+        private Helpers.HelperStack iHelperStack = new CrashDebuggerLib.Parsers.State.Implementation.Helpers.HelperStack();
+        #endregion
+    }
+}