public override bool ResolveAddressToSymboInfo(ESymbolResolutionMode SymbolResolutionMode, ulong Address, out string OutFileName, out string OutFunction, out int OutLineNumber)
        {
            OutFileName   = null;
            OutFunction   = null;
            OutLineNumber = 0;
            bool bOk = false;

            foreach (var Symbol in Database.Symbols)
            {
                if ((Symbol.Start <= (Address - ModuleOffset)) && ((Symbol.Start + Symbol.Length) >= (Address - ModuleOffset)))
                {
                    OutFunction = Database.StringTable[Symbol.NameIdx];

                    foreach (var SymbolInfo in Symbol.SymbolInfo)
                    {
                        if ((SymbolInfo.Start <= (Address - ModuleOffset)) && ((SymbolInfo.Start + SymbolInfo.Length) >= (Address - ModuleOffset)))
                        {
                            OutFileName   = Database.StringTable[SymbolInfo.PathIdx];
                            OutLineNumber = (int)SymbolInfo.Line;
                            break;
                        }
                    }

                    bOk = true;

                    break;
                }
            }

            return(bOk);
        }
        public override bool ResolveAddressToSymboInfo(ESymbolResolutionMode SymbolResolutionMode, ulong Address, out string OutFileName, out string OutFunction, out int OutLineNumber)
        {
            OutFileName   = null;
            OutFunction   = null;
            OutLineNumber = 0;

            // subtract off a known amount for where we were loaded
            Address -= CachedSymbolOffset;

            // verify the address
            if (Address < 0 || Address > Addresses[Addresses.Count - 1])
            {
                return(false);
            }

            // fast binary search of the address to symbol
            int FoundIndex = Addresses.BinarySearch(Address);

            // negative means that the result is the binary complement of the one _bigger_ than the value, we want the one lower
            if (FoundIndex < 0)
            {
                FoundIndex = ~FoundIndex;

                // if the index is Count, then we didn't find it
                if (FoundIndex == Addresses.Count)
                {
                    return(false);
                }

                // move to the one before it
                FoundIndex -= 1;
            }

            // return the matching symbol
            OutFunction = Symbols[FoundIndex];
            return(true);
        }
		public virtual void ResolveCallstackSymbolInfoAsync(ESymbolResolutionMode SymbolResolutionMode, FCallStack CallStack, ResolveCallstackSymbolInfoCallback Callback, bool bCancelCurrentWork)
		{
			if (bCancelCurrentWork)
			{
				foreach (var Worker in ResolveCallstackSymbolInfoAsyncTasks)
				{
					if (Worker.IsBusy && !Worker.CancellationPending)
					{
						Worker.CancelAsync();
					}
				}
			}

			for (int WorkerIndex = ResolveCallstackSymbolInfoAsyncTasks.Count - 1; WorkerIndex >= 0; --WorkerIndex)
			{
				var Worker = ResolveCallstackSymbolInfoAsyncTasks[WorkerIndex];
				if (!Worker.IsBusy)
				{
					ResolveCallstackSymbolInfoAsyncTasks.RemoveAt(WorkerIndex);
				}
			}

			var AsyncWorker = new BackgroundWorker();

			AsyncWorker.DoWork += new DoWorkEventHandler(delegate(object Obj, DoWorkEventArgs Args)
			{
				var Worker = Obj as BackgroundWorker;

				foreach (int AddressIndex in CallStack.AddressIndices)
				{
					if (Worker.CancellationPending)
					{
						break;
					}

					FCallStackAddress Address = FStreamInfo.GlobalInstance.CallStackAddressArray[AddressIndex];
					ResolveAddressSymbolInfo(SymbolResolutionMode, Address);
				}

				if (!Worker.CancellationPending)
				{
					Callback(CallStack);
				}
			});

			AsyncWorker.RunWorkerAsync();
			ResolveCallstackSymbolInfoAsyncTasks.Add(AsyncWorker);
		}
		public virtual bool ResolveCallstackSymbolInfo(ESymbolResolutionMode SymbolResolutionMode, FCallStack CallStack)
		{
			bool bSuccess = true;

			foreach (int AddressIndex in CallStack.AddressIndices)
			{
				FCallStackAddress Address = FStreamInfo.GlobalInstance.CallStackAddressArray[AddressIndex];
				bSuccess &= ResolveAddressSymbolInfo(SymbolResolutionMode, Address);
			}

			return bSuccess;
		}
		public virtual bool ResolveAddressSymbolInfo(ESymbolResolutionMode SymbolResolutionMode, FCallStackAddress Address)
		{
			if (Address.LineNumber == 0)
			{
				string Filename;
				string Function;
				int LineNumber;
				if (ResolveAddressToSymboInfo(SymbolResolutionMode, Address.ProgramCounter, out Filename, out Function, out LineNumber))
				{
					if (Filename != null)
					{
						// Look up or add filename index.
						Address.FilenameIndex = FStreamInfo.GlobalInstance.GetNameIndex(Filename, true);
					}

					if (Function != null)
					{
						// Look up or add function index.
						Address.FunctionIndex = FStreamInfo.GlobalInstance.GetNameIndex(Function, true);
					}

					if (LineNumber != 0)
					{
						Address.LineNumber = LineNumber;
					}
				}
				else
				{
					return false;
				}
			}

			return true;
		}
		public virtual bool ResolveAddressToSymboInfo(ESymbolResolutionMode SymbolResolutionMode, ulong Address, out string OutFileName, out string OutFunction, out int OutLineNumber)
		{
			OutFileName = null;
			OutFunction = null;
			OutLineNumber = 0;
			return false;
		}