JD2022-TU1/main/tools/apps/MemoryProfiler/MainWindow.xaml.cs

119 lines
4.3 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using MemoryProfiler.source;
using UAF.Remoting;
namespace MemoryProfiler
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : INotifyPropertyChanged
{
private const string RelativeMapFilePath = "engine\\UA_Bin\\win32_ITF_AppFramework_r.map";
private readonly MemoryProfilerPlugin _plugin;
private readonly CallstackFactory _factory;
private UInt64 _baseAddress;
private readonly Translator _translator;
public MainWindow()
{
InitializeComponent();
_translator = new Translator();
_factory = new CallstackFactory(_translator);
_callstacks = new List<CallstackViewModel>();
_plugin = new MemoryProfilerPlugin(Dispatcher);
_plugin.RegisterHandler(MemoryProfilerPlugin.DataRootCmdName, HandleDataRootCmd);
_plugin.RegisterHandler(MemoryProfilerPlugin.CallstackCmdName, HandleCallstackCmd);
_plugin.RegisterHandler(MemoryProfilerPlugin.BaseAddressCmdName, HandleBaseAddressCmd);
_plugin.Start();
DataContext = this;
}
private bool _isMapFileLoaded;
public bool IsMapFileLoaded {
get { return _isMapFileLoaded; }
private set {
_isMapFileLoaded = value;
OnPropertyChanged("IsMapFileLoaded");
}
}
private List<CallstackViewModel> _callstacks;
public List<CallstackViewModel> Callstacks
{
get { return _callstacks; }
}
private void HandleDataRootCmd(IBlob blob)
{
var mapFilePath = Path.Combine(blob.ExtractString(), "..", RelativeMapFilePath);
IsMapFileLoaded = _translator.LoadMapFile(mapFilePath, MapFile.MapFormat.Pc);
if (!IsMapFileLoaded)
{
MessageBox.Show(string.Format("Could not load map file: {0}.", mapFilePath),
"Map file error",
MessageBoxButton.OK,
MessageBoxImage.Error);
}
}
private void HandleCallstackCmd(IBlob blob)
{
string extractInfo;
do
{
extractInfo = blob.ExtractString();
if (extractInfo.Contains("id"))
_factory.PushId(blob.ExtractUInt());
else if (extractInfo.Contains("ad"))
_factory.PushAddress(blob.ExtractUInt() - _baseAddress);
else if (extractInfo.Contains("ca"))
_factory.PushAllocationCount(blob.ExtractUInt());
else if (extractInfo.Contains("sa"))
_factory.PushAllocatedMemory(blob.ExtractUInt());
else if (extractInfo.Contains("cr"))
_factory.PushReleaseCount(blob.ExtractUInt());
else if (extractInfo.Contains("sr"))
_factory.PushReleasedMemory(blob.ExtractUInt());
else if (extractInfo.Contains("CALLSTACK"))
_callstacks.Add(new CallstackViewModel(_factory.MakeCallstack()));
else if (extractInfo.Contains("pi"))
blob.ExtractInt(); // Not used
else if (extractInfo == "ENDOFDUMP")
{
_callstacks = _callstacks.OrderBy(cs => -cs.TotalMemory).ToList();
OnPropertyChanged("Callstacks");
break;
}
} while (extractInfo != "ENDOFBLOB");
}
private void HandleBaseAddressCmd(IBlob blob)
{
_baseAddress = blob.ExtractULong();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
_plugin.Send(new Message(MemoryProfilerPlugin.CallstackCmdName));
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}