public override void Check(CIContainer aContainer) { CISummarisableEntityList list = aContainer.Summaries; foreach (CISummarisableEntity entry in list) { bool stackAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementStack); if (stackAvailable) { CIStack stack = entry.Stack; // bool regsAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementRegisters); if (regsAvailable) { bool pointerAvailable = stack.Registers.Contains(TArmRegisterType.EArmReg_SP); // if (pointerAvailable == false && stack.RawDataLength > 0) { base.CreateWarning(aContainer, stack, LibResources.CIPDStackRegisterAvailability_MissingSP_Title, string.Format(LibResources.CIPDStackRegisterAvailability_MissingSP_Description, base.CreateIdentifierText(entry)) ); } } else { base.CreateWarning(aContainer, stack, LibResources.CIPDStackRegisterAvailability_MissingRegisters_Title, string.Format(LibResources.CIPDStackRegisterAvailability_MissingRegisters_Description, base.CreateIdentifierText(entry)) ); } } } }
public override void Check(CIContainer aContainer) { CISummarisableEntityList list = aContainer.Summaries; foreach (CISummarisableEntity entry in list) { bool stackAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementStack); bool regsAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementRegisters); if (stackAvailable && regsAvailable) { CIStack stack = entry.Stack; // bool pointerAvailable = stack.Registers.Contains(TArmRegisterType.EArmReg_SP); if (pointerAvailable) { CIRegister regSP = stack.Pointer; AddressRange stackDataRange = stack.RawDataRange; // if (!stackDataRange.Contains(regSP)) { base.CreateWarning(aContainer, stack, LibResources.CPIDStackDataValidator_Title, string.Format(LibResources.CPIDStackDataValidator_Description, base.CreateIdentifierText(entry)) ); } } } } }
protected override void XmlSerializeContent(CrashXmlPlugin.FileFormat.Document.CXmlDocumentSerializationParameters aParameters) { if (!iEntry.IsRegisterBasedEntry) { aParameters.Writer.WriteElementString(SegConstants.CmnAddress, iEntry.Address.ToString("x8")); } // aParameters.Writer.WriteElementString(SegConstants.CmnValue, iEntry.Data.ToString("x8")); aParameters.Writer.WriteElementString(SegConstants.CmnText, iEntry.DataAsString); if (iEntry.FunctionOffset != 0) { aParameters.Writer.WriteElementString(SegConstants.Stacks_Stack_Data_Offset, iEntry.FunctionOffset.ToString("x4")); } // if (iEntry.IsRegisterBasedEntry) { // Get the corresponding register from the stack CIStack stack = iEntry.Stack; CIRegister register = iEntry.Register; if (register != null) { CXmlNode.WriteLink(register.Id, SegConstants.Registers, aParameters.Writer); } } if (iEntry.Symbol != null) { CXmlNode.WriteLink(iEntry.Symbol.Id, SegConstants.Symbols, aParameters.Writer); } }
/// <summary> /// Preferred constructor that is called by CISummarisableEntityList during finalization. /// This constructor is used to create a summary wrapper for any stack-level objects that /// were created during container preparation. Those stack objects may be stand-alone exception /// mode stacks (IRQ, FIQ, ABT, UND et al) or then they may be associated with a specific /// Symbian OS thread (user or supervisor). /// </summary> /// <param name="aStack"></param> internal CISummarisableEntity(CIStack aStack) : base(aStack.Container) { // NB: If the stack has an associated register list, // and the register list's owner is a thread, then we // automatically know we're dealing with a thread-based stack. AddChild(aStack); }
public CIStack CreateStack(CIRegisterList aRegisters, byte[] aData, uint aAddressOfFirstByte, AddressRange aRange) { // The registers given must be a child of this thread (in some way) System.Diagnostics.Debug.Assert(aRegisters.OwningThread == this); // Add it to the overall item too CIStack stack = CIStack.NewThreadStack(this, aRegisters, aData, aAddressOfFirstByte, aRange); AddChild(stack); return(stack); }
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); } }
private void ExtractThreadStack(CIThread aThread) { DExcExtractorListStackData stackDataList = (DExcExtractorListStackData)iData[DExcExtractorListType.EListStackData]; DataBuffer stackData = stackDataList.StackData; // Get stack range details DExcExtractorListThreadInfo threadInfo = (DExcExtractorListThreadInfo)iData[DExcExtractorListType.EListThread]; AddressRange stackRange = threadInfo.StackRange; // If we didn't get the stack range, we cannot create a stack entry if (!stackRange.IsValid || stackRange.Max == 0 || stackRange.Min == 0) { CIMessageWarning warning = new CIMessageWarning(aThread.Container, "Stack Address Range Unavailable"); warning.AddLine("The stack address range details are invalid."); aThread.AddChild(warning); } else if (stackData.Count == 0) { // No stack data CIMessageWarning warning = new CIMessageWarning(aThread.Container, "Stack Data Unavailable"); warning.AddLine("The crash details contain no stack data."); aThread.AddChild(warning); } else { // Set base address of data buffer if not already set if (stackData.AddressOffset == 0) { stackData.AddressOffset = stackRange.Min; } // In theory, D_EXC only ever captures user-side crashes (panics/exceptions) therefore // we should always be able to assume that the stack data goes with a user-side thread. CIRegisterList userRegs = aThread.Registers[TArmRegisterBank.ETypeUser]; if (userRegs != null) { CIStack stack = aThread.CreateStack(userRegs, stackData, stackData.AddressOffset, stackRange); // Register it as a specific crash instance iContainer.AddChild(stack); } } }
public CISummarisableEntity this[CIStack aEntry] { get { CISummarisableEntity ret = null; // foreach (CISummarisableEntity entry in this) { if (entry.IsAvailable(CISummarisableEntity.TElement.EElementStack)) { if (entry.Stack.Id == aEntry.Id) { ret = entry; break; } } } // return(ret); } }
public override void AddChild(CIElement aChild) { // We support 4 types of children at the moment. // Registers, stacks and exit info, messages. if (aChild.GetType() == typeof(CIExitInfo)) { if (base.ChildrenByType <CIExitInfo>().Count != 0) { throw new ArgumentException("Exit Info already associated with the thread"); } } else if (aChild.GetType() == typeof(CIThreadRegisterListCollection)) { if (base.ChildrenByType <CIThreadRegisterListCollection>().Count != 0) { throw new ArgumentException("Registers already associated with the thread"); } } else if (aChild.GetType() == typeof(CIStack)) { CIStack stack = (CIStack)aChild; // We must ensure we don't already have a stack of the specified mode // associated with the thread. bool exists = iStacks.ContainsKey(stack.Type); if (exists) { throw new ArgumentException(ArmRegisterBankUtils.BankAsStringLong(stack.Type) + " mode stack already registered with thread"); } else { iStacks.Add(stack.Type, stack); } } // base.AddChild(aChild); }
public override void Check(CIContainer aContainer) { CISummarisableEntityList list = aContainer.Summaries; foreach (CISummarisableEntity entry in list) { // Check that each stack contains some registers and at least the SP. bool stackAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementStack); bool regsAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementRegisters); // if (stackAvailable) { CIStack stack = entry.Stack; // if (regsAvailable) { CIRegisterList regs = stack.Registers; // Check that SP, LR and PC are available bool pointerAvailable = regs.Contains(TArmRegisterType.EArmReg_SP); if (!pointerAvailable) { base.CreateWarning(aContainer, stack, LibResources.CIPDRegAvailability_MissingSP_Title, string.Format(LibResources.CIPDRegAvailability_MissingSP_Description, base.CreateIdentifierText(entry)) ); } // bool lrAvailable = regs.Contains(TArmRegisterType.EArmReg_LR); if (!lrAvailable) { base.CreateWarning(aContainer, stack, LibResources.CIPDRegAvailability_MissingLR_Title, string.Format(LibResources.CIPDRegAvailability_MissingLR_Description, base.CreateIdentifierText(entry)) ); } // bool pcAvailable = regs.Contains(TArmRegisterType.EArmReg_PC); if (!pcAvailable) { base.CreateWarning(aContainer, stack, LibResources.CIPDRegAvailability_MissingPC_Title, string.Format(LibResources.CIPDRegAvailability_MissingPC_Description, base.CreateIdentifierText(entry)) ); } // If R0 is available, check if it is 0 and check whether an exception occurred - if so, it was possibly // caused by de-referencing a NULL this pointer. bool threadAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementThread); if (threadAvailable) { if (regs.Contains(TArmRegisterType.EArmReg_00)) { CIRegister r0 = regs[TArmRegisterType.EArmReg_00]; // bool r0WasNull = (r0.Value == 0); bool wasException = entry.IsAbnormalTermination && (entry.Thread.ExitInfo.Type == CrashItemLib.Crash.ExitInfo.CIExitInfo.TExitType.EExitTypeException); bool wasKernExec3 = entry.IsAbnormalTermination && (entry.Thread.ExitInfo.Type == CrashItemLib.Crash.ExitInfo.CIExitInfo.TExitType.EExitTypePanic && entry.Thread.ExitInfo.Category.ToUpper() == "KERN-EXEC" && entry.Thread.ExitInfo.Reason == 3); // if (r0WasNull && (wasException || wasKernExec3)) { base.CreateWarning(aContainer, r0, LibResources.CIPDRegAvailability_NullThisPointer_Title, string.Format(LibResources.CIPDRegAvailability_NullThisPointer_Description, base.CreateIdentifierText(entry)) ); } } } } else { base.CreateWarning(aContainer, stack, LibResources.CIPDRegAvailability_NoRegsForStack_Title, string.Format(LibResources.CIPDRegAvailability_NoRegsForStack_Description, base.CreateIdentifierText(entry)) ); } } } }
internal bool Contains(CIStack aStack) { return(iStacks.ContainsKey(aStack.Type)); }
public CXmlStack(CIStack aStack) : base(SegConstants.Stacks_Stack) { iStack = aStack; }