diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Parsers/State/Implementation/Stacks/StateThreadStacks.cs --- /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 + } +}