Implemented automatic memory leak detection and reporting for CRT.
This commit is contained in:
parent
67a5288984
commit
380582dfeb
14
Crawler.sln
14
Crawler.sln
@ -5,6 +5,8 @@ VisualStudioVersion = 17.5.33516.290
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Crawler", "Crawler\Crawler.vcxproj", "{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MemoryLeakFileParser", "MemoryLeakFileParser\MemoryLeakFileParser.vcxproj", "{3054FF55-6C4E-4A38-89DA-E707AE2F3178}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@ -27,6 +29,18 @@ Global
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release|x64.Build.0 = Release|x64
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release|x86.ActiveCfg = Release|Win32
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release|x86.Build.0 = Release|Win32
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Debug|x64.Build.0 = Debug|x64
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Debug|x86.Build.0 = Debug|Win32
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Release Desktop|x64.ActiveCfg = Release|x64
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Release Desktop|x64.Build.0 = Release|x64
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Release Desktop|x86.ActiveCfg = Release|Win32
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Release Desktop|x86.Build.0 = Release|Win32
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Release|x64.ActiveCfg = Release|x64
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Release|x64.Build.0 = Release|x64
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Release|x86.ActiveCfg = Release|Win32
|
||||
{3054FF55-6C4E-4A38-89DA-E707AE2F3178}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
class IAttributable{
|
||||
protected:
|
||||
inline virtual ~IAttributable(){};
|
||||
std::map<Attribute,std::variant<VARIANTS>>attributes;
|
||||
inline float&GetFloat(Attribute a){
|
||||
if(attributes.count(a)==0){
|
||||
|
||||
@ -1551,7 +1551,32 @@ int main()
|
||||
demo.Start();
|
||||
}
|
||||
|
||||
_CrtDumpMemoryLeaks();
|
||||
#ifdef _DEBUG
|
||||
HANDLE hLogFile;
|
||||
hLogFile = CreateFile(L"assets/memoryleak.txt", GENERIC_WRITE,
|
||||
FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
_CrtSetReportMode(_CRT_WARN,_CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_WARN,hLogFile);
|
||||
_CrtDumpMemoryLeaks();
|
||||
CloseHandle(hLogFile);
|
||||
|
||||
std::ifstream file("assets/memoryleak.txt");
|
||||
bool leaked=false;
|
||||
while(file.good()){
|
||||
std::string line;
|
||||
std::getline(file,line);
|
||||
if(line.find("Crawler\\")!=std::string::npos){
|
||||
if(!leaked){
|
||||
leaked=true;
|
||||
std::cout<<std::endl<<std::endl<<std::endl<<"Memory leak detected!"<<std::endl;
|
||||
}
|
||||
std::cout<<line<<std::endl;
|
||||
std::getline(file,line);
|
||||
std::cout<<line<<std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1631,9 +1656,17 @@ bool Crawler::OnUserDestroy(){
|
||||
delete MAP_DATA[data.first].optimizedTile;
|
||||
}
|
||||
}
|
||||
for(auto&key:MAP_TILESETS){
|
||||
delete key.second.tileset;
|
||||
}
|
||||
for(auto&data:GameState::states){
|
||||
delete data.second;
|
||||
}
|
||||
delete[]pathfinder.nodes;
|
||||
Menu::CleanupAllMenus();
|
||||
for(auto&key:MonsterData::imgs){
|
||||
delete key.second;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ protected:
|
||||
}
|
||||
}
|
||||
}
|
||||
void inline RemoveEmptySlots(){
|
||||
inline void RemoveEmptySlots(){
|
||||
//Algorithm will iterate through all slots, finding blank slots. Each time a blank slot is found, all items will shift over by one, and then the last item will be removed. Repeat until all slots iterated through.
|
||||
for(int i=0;i<components.size();i++){
|
||||
MenuComponent*button=components[i];
|
||||
@ -58,7 +58,7 @@ protected:
|
||||
}
|
||||
bounds=CalculateBounds(); //Recalculate the bounds as it's possible the width/height of the component has changed.
|
||||
}
|
||||
virtual void OnInventorySlotsUpdate(ITCategory cat)override{
|
||||
virtual inline void OnInventorySlotsUpdate(ITCategory cat)override{
|
||||
std::vector<std::string>&inv=Inventory::get(cat);
|
||||
//We only want to refresh the inventory slots if the component count no longer matches what's actually in our inventory.
|
||||
if(components.size()<inv.size()){//We need more space to display our items.
|
||||
@ -82,4 +82,7 @@ protected:
|
||||
RemoveEmptySlots();
|
||||
}
|
||||
}
|
||||
virtual inline void Cleanup()override{
|
||||
|
||||
}
|
||||
};
|
||||
@ -18,8 +18,8 @@ std::vector<MenuComponent*>Menu::unhandledComponents;
|
||||
///__/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//| |////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//| |/////WARNING! If you are adding something here you likely are adding another container with MenuComponent pointers in it right now.
|
||||
//| |/////Because we are handling raw pointers, you must also add this container to the list of iterating search removal contains that occur in the
|
||||
//| |/////DESTRUCTOR of MenuComponents!!!!! THIS IS NOT A DRILL!
|
||||
//| |/////Because we are handling raw pointers, you must also add this container to the list of iterating search removal containers that occur in the
|
||||
//| |/////DESTRUCTOR of MenuComponents!!!!! (Go to MenuComponent::~MenuComponent()) THIS IS NOT A DRILL!
|
||||
//|__|////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///__/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -648,5 +648,18 @@ bool Menu::IsMenuOpen(){
|
||||
}
|
||||
|
||||
void Menu::CleanupAllMenus(){
|
||||
|
||||
}
|
||||
for(auto key:Menu::menus){
|
||||
Menu*menu=key.second;
|
||||
for(auto componentKey:menu->components){
|
||||
MenuComponent*component=componentKey.second;
|
||||
component->Cleanup();
|
||||
delete component;
|
||||
}
|
||||
menu->components.Reset();
|
||||
menu->Cleanup();
|
||||
delete menu;
|
||||
}
|
||||
Menu::menus.clear();
|
||||
}
|
||||
|
||||
void Menu::Cleanup(){}
|
||||
@ -67,6 +67,7 @@ public:
|
||||
vf2d center();
|
||||
//Returns the last menu type created and last registered component, in case a component is detected as memory leaking, provides this information to each component for safety.
|
||||
static std::pair<MenuType,std::string>GetMemoryLeakReportInfo();
|
||||
virtual void Cleanup();
|
||||
private:
|
||||
Menu(vf2d pos,vf2d size);
|
||||
static MenuType lastMenuTypeCreated;
|
||||
|
||||
@ -25,6 +25,7 @@ MenuComponent::~MenuComponent(){
|
||||
std::erase_if(components,[&](MenuComponent*component){return component==this;});
|
||||
}
|
||||
std::erase_if(pMenu->displayComponents,[&](MenuComponent*component){return component==this;});
|
||||
//pMenu->components.erase(this->name); //We're not going to do this here because we are in the middle of a loop for another menu component when cleaning up.
|
||||
}
|
||||
|
||||
void MenuComponent::AfterCreate(){}
|
||||
@ -122,4 +123,6 @@ std::string MenuComponent::GetLabel(){
|
||||
|
||||
void MenuComponent::Enable(bool enabled){
|
||||
disabled=!enabled;
|
||||
};
|
||||
};
|
||||
|
||||
void MenuComponent::Cleanup(){}
|
||||
@ -70,6 +70,7 @@ public:
|
||||
virtual void OnInventorySlotsUpdate(ITCategory cat);
|
||||
std::string GetLabel();
|
||||
void Enable(bool enabled);
|
||||
virtual void Cleanup();
|
||||
};
|
||||
|
||||
constexpr auto operator|(ButtonAttr attribute,ButtonAttr attribute2) noexcept
|
||||
|
||||
@ -26,13 +26,6 @@ public:
|
||||
:MenuComponent(parent,rect,"",onClick,ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD){
|
||||
r.Create(rect.size.x,rect.size.y);
|
||||
}
|
||||
|
||||
virtual inline ~ScrollableWindowComponent(){
|
||||
MenuComponent::~MenuComponent();
|
||||
for(MenuComponent*component:components){
|
||||
delete component;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
virtual inline void AfterCreate()override{
|
||||
upButton=NEW MenuComponent(parentMenu,{vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y+="ThemeGlobal.MenuButtonScrollSpeed"_I;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD);
|
||||
@ -192,4 +185,5 @@ public:
|
||||
V(A::SCROLL_OFFSET).y+=rect.size.y/2;
|
||||
return true;
|
||||
};
|
||||
virtual void Cleanup()override{}
|
||||
};
|
||||
@ -2,7 +2,7 @@
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 1
|
||||
#define VERSION_BUILD 2592
|
||||
#define VERSION_BUILD 2618
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
||||
30985
Crawler/assets/memoryleak.txt
Normal file
30985
Crawler/assets/memoryleak.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -52,6 +52,9 @@ public:
|
||||
size_t erase(const T&key){
|
||||
return map.erase(key);
|
||||
}
|
||||
auto erase(std::map<T,O>::iterator it){
|
||||
return map.erase(it);
|
||||
}
|
||||
};
|
||||
|
||||
//A class that has an initialization lock so that when the lock is activated, any further gets that are missing items in it will report themselves for easier debugging detection.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user