1
0
Fork 0

DBG: significant memory usage improvements for database (~5x less memory used)

This commit is contained in:
mrexodia 2017-02-24 19:38:48 +01:00
parent 71130601ee
commit bf3ccd7e0b
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
22 changed files with 138 additions and 85 deletions

View File

@ -29,7 +29,7 @@ SCRIPT_EXPORT bool Script::Argument::GetInfo(duint addr, ArgumentInfo* info)
return false;
if(info)
{
strcpy_s(info->mod, argument.mod);
strcpy_s(info->mod, argument.mod().c_str());
info->rvaStart = argument.start;
info->rvaEnd = argument.end;
info->manual = argument.manual;
@ -67,7 +67,7 @@ SCRIPT_EXPORT bool Script::Argument::GetList(ListOf(ArgumentInfo) list)
for(const auto & argument : argumentList)
{
ArgumentInfo scriptArgument;
strcpy_s(scriptArgument.mod, argument.mod);
strcpy_s(scriptArgument.mod, argument.mod().c_str());
scriptArgument.rvaStart = argument.start;
scriptArgument.rvaEnd = argument.end;
scriptArgument.manual = argument.manual;

View File

@ -29,7 +29,7 @@ SCRIPT_EXPORT bool Script::Bookmark::GetInfo(duint addr, BookmarkInfo* info)
return false;
if(info)
{
strcpy_s(info->mod, comment.mod);
strcpy_s(info->mod, comment.mod().c_str());
info->rva = comment.addr;
info->manual = comment.manual;
}
@ -60,7 +60,7 @@ SCRIPT_EXPORT bool Script::Bookmark::GetList(ListOf(BookmarkInfo) list)
for(const auto & bookmark : bookmarkList)
{
BookmarkInfo scriptComment;
strcpy_s(scriptComment.mod, bookmark.mod);
strcpy_s(scriptComment.mod, bookmark.mod().c_str());
scriptComment.rva = bookmark.addr;
scriptComment.manual = bookmark.manual;
bookmarkScriptList.push_back(scriptComment);

View File

@ -29,9 +29,9 @@ SCRIPT_EXPORT bool Script::Comment::GetInfo(duint addr, CommentInfo* info)
return false;
if(info)
{
strcpy_s(info->mod, comment.mod);
strcpy_s(info->mod, comment.mod().c_str());
info->rva = comment.addr;
strcpy_s(info->text, comment.text);
strcpy_s(info->text, comment.text.c_str());
info->manual = comment.manual;
}
return true;
@ -61,9 +61,9 @@ SCRIPT_EXPORT bool Script::Comment::GetList(ListOf(CommentInfo) list)
for(const auto & comment : commentList)
{
CommentInfo scriptComment;
strcpy_s(scriptComment.mod, comment.mod);
strcpy_s(scriptComment.mod, comment.mod().c_str());
scriptComment.rva = comment.addr;
strcpy_s(scriptComment.text, comment.text);
strcpy_s(scriptComment.text, comment.text.c_str());
scriptComment.manual = comment.manual;
commentScriptList.push_back(scriptComment);
}

View File

@ -29,7 +29,7 @@ SCRIPT_EXPORT bool Script::Function::GetInfo(duint addr, FunctionInfo* info)
return false;
if(info)
{
strcpy_s(info->mod, function.mod);
strcpy_s(info->mod, function.mod().c_str());
info->rvaStart = function.start;
info->rvaEnd = function.end;
info->manual = function.manual;
@ -72,7 +72,7 @@ SCRIPT_EXPORT bool Script::Function::GetList(ListOf(FunctionInfo) list)
for(const auto & function : functionList)
{
FunctionInfo scriptFunction;
strcpy_s(scriptFunction.mod, function.mod);
strcpy_s(scriptFunction.mod, function.mod().c_str());
scriptFunction.rvaStart = function.start;
scriptFunction.rvaEnd = function.end;
scriptFunction.manual = function.manual;

View File

@ -34,9 +34,9 @@ SCRIPT_EXPORT bool Script::Label::GetInfo(duint addr, LabelInfo* info)
return false;
if(info)
{
strcpy_s(info->mod, label.mod);
strcpy_s(info->mod, label.mod().c_str());
info->rva = label.addr;
strcpy_s(info->text, label.text);
strcpy_s(info->text, label.text.c_str());
info->manual = label.manual;
}
return true;
@ -66,9 +66,9 @@ SCRIPT_EXPORT bool Script::Label::GetList(ListOf(LabelInfo) list)
for(const auto & label : labelList)
{
LabelInfo scriptLabel;
strcpy_s(scriptLabel.mod, label.mod);
strcpy_s(scriptLabel.mod, label.mod().c_str());
scriptLabel.rva = label.addr;
strcpy_s(scriptLabel.text, label.text);
strcpy_s(scriptLabel.text, label.text.c_str());
scriptLabel.manual = label.manual;
labelScriptList.push_back(scriptLabel);
}

View File

@ -7,7 +7,7 @@ struct ArgumentSerializer : JSONWrapper<ARGUMENTSINFO>
{
bool Save(const ARGUMENTSINFO & value) override
{
setString("module", value.mod);
setString("module", value.mod());
setHex("start", value.start);
setHex("end", value.end);
setHex("icount", value.instructioncount);
@ -17,8 +17,11 @@ struct ArgumentSerializer : JSONWrapper<ARGUMENTSINFO>
bool Load(ARGUMENTSINFO & value) override
{
return getString("module", value.mod) &&
getHex("start", value.start) &&
std::string mod;
if(!getString("module", mod))
return false;
value.modhash = ModHashFromName(mod.c_str());
return getHex("start", value.start) &&
getHex("end", value.end) &&
getBool("manual", value.manual) &&
getHex("icount", value.instructioncount) &&
@ -30,7 +33,7 @@ struct Arguments : SerializableModuleRangeMap<LockArguments, ARGUMENTSINFO, Argu
{
void AdjustValue(ARGUMENTSINFO & value) const override
{
auto base = ModBaseFromName(value.mod);
auto base = ModBaseFromName(value.mod().c_str());
value.start += base;
value.end += base;
}
@ -43,7 +46,7 @@ protected:
ModuleRange makeKey(const ARGUMENTSINFO & value) const override
{
return ModuleRange(ModHashFromName(value.mod), Range(value.start, value.end));
return ModuleRange(value.modhash, Range(value.start, value.end));
}
};
@ -66,8 +69,7 @@ bool ArgumentAdd(duint Start, duint End, bool Manual, duint InstructionCount)
return false;
ARGUMENTSINFO argument;
if(!ModNameFromAddr(Start, argument.mod, true))
*argument.mod = '\0';
argument.modhash = ModHashFromAddr(moduleBase);
argument.start = Start - moduleBase;
argument.end = End - moduleBase;
argument.manual = Manual;

View File

@ -5,11 +5,16 @@
struct ARGUMENTSINFO
{
char mod[MAX_MODULE_SIZE];
duint modhash;
duint start;
duint end;
bool manual;
duint instructioncount;
std::string mod() const
{
return ModNameFromHash(modhash);
}
};
bool ArgumentAdd(duint Start, duint End, bool Manual, duint InstructionCount = 0);

View File

@ -99,7 +99,7 @@ bool cbInstrCommentList(int argc, char* argv[])
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
if(GuiGetDisassembly(comments()[i].addr, disassembly))
GuiReferenceSetCellContent(total, 1, disassembly);
GuiReferenceSetCellContent(total, 2, comments()[i].text);
GuiReferenceSetCellContent(total, 2, comments()[i].text.c_str());
total++;
}
varset("$result", total, false);
@ -175,7 +175,7 @@ bool cbInstrLabelList(int argc, char* argv[])
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
if(GuiGetDisassembly(labels()[i].addr, disassembly))
GuiReferenceSetCellContent(i, 1, disassembly);
GuiReferenceSetCellContent(i, 2, labels()[i].text);
GuiReferenceSetCellContent(i, 2, labels()[i].text.c_str());
}
varset("$result", count, false);
dprintf(QT_TRANSLATE_NOOP("DBG", "%d label(s) listed in Reference View\n"), count);

View File

@ -41,7 +41,7 @@ bool CommentSet(duint Address, const char* Text, bool Manual)
COMMENTSINFO comment;
if(!comments.PrepareValue(comment, Address, Manual))
return false;
strcpy_s(comment.text, Text);
comment.text = Text;
return comments.Add(comment);
}
@ -51,9 +51,9 @@ bool CommentGet(duint Address, char* Text)
if(!comments.Get(Comments::VaKey(Address), comment))
return false;
if(comment.manual)
strcpy_s(Text, MAX_COMMENT_SIZE, comment.text);
strcpy_s(Text, MAX_COMMENT_SIZE, comment.text.c_str());
else
sprintf_s(Text, MAX_COMMENT_SIZE, "\1%s", comment.text);
sprintf_s(Text, MAX_COMMENT_SIZE, "\1%s", comment.text.c_str());
return true;
}

View File

@ -6,7 +6,7 @@
struct COMMENTSINFO : AddrInfo
{
char text[MAX_COMMENT_SIZE];
std::string text;
};
bool CommentSet(duint Address, const char* Text, bool Manual);

View File

@ -1481,7 +1481,6 @@ static void cbExitProcess(EXIT_PROCESS_DEBUG_INFO* ExitProcess)
dbgcleartracestate();
dbgClearRtuBreakpoints();
HistoryClear();
ModClear(); //clear all modules
}
static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread)

View File

@ -48,7 +48,7 @@ struct EncodeMapSerializer : AddrInfoSerializer<ENCODEMAP>
bool Save(const ENCODEMAP & value) override
{
AddrInfoSerializer::Save(value);
setString("data", StringUtils::ToCompressedHex(value.data, value.size).c_str());
setString("data", StringUtils::ToCompressedHex(value.data, value.size));
return true;
}

View File

@ -7,7 +7,7 @@ struct FunctionSerializer : JSONWrapper<FUNCTIONSINFO>
{
bool Save(const FUNCTIONSINFO & value) override
{
setString("module", value.mod);
setString("module", value.mod());
setHex("start", value.start);
setHex("end", value.end);
setHex("icount", value.instructioncount);
@ -20,8 +20,11 @@ struct FunctionSerializer : JSONWrapper<FUNCTIONSINFO>
//legacy support
value.manual = true;
getBool("manual", value.manual);
return getString("module", value.mod) &&
getHex("start", value.start) &&
std::string mod;
if(!getString("module", mod))
return false;
value.modhash = ModHashFromName(mod.c_str());
return getHex("start", value.start) &&
getHex("end", value.end) &&
getHex("icount", value.instructioncount) &&
value.end >= value.start;
@ -32,7 +35,7 @@ struct Functions : SerializableModuleRangeMap<LockFunctions, FUNCTIONSINFO, Func
{
void AdjustValue(FUNCTIONSINFO & value) const override
{
auto base = ModBaseFromName(value.mod);
auto base = ModBaseFromName(value.mod().c_str());
value.start += base;
value.end += base;
}
@ -45,7 +48,7 @@ protected:
ModuleRange makeKey(const FUNCTIONSINFO & value) const override
{
return ModuleRange(ModHashFromName(value.mod), Range(value.start, value.end));
return ModuleRange(value.modhash, Range(value.start, value.end));
}
};
@ -68,8 +71,7 @@ bool FunctionAdd(duint Start, duint End, bool Manual, duint InstructionCount)
return false;
FUNCTIONSINFO function;
if(!ModNameFromAddr(Start, function.mod, true))
*function.mod = '\0';
function.modhash = ModHashFromAddr(moduleBase);
function.start = Start - moduleBase;
function.end = End - moduleBase;
function.manual = Manual;

View File

@ -5,11 +5,16 @@
struct FUNCTIONSINFO
{
char mod[MAX_MODULE_SIZE];
duint modhash;
duint start;
duint end;
bool manual;
duint instructioncount;
std::string mod() const
{
return ModNameFromHash(modhash);
}
};
bool FunctionAdd(duint Start, duint End, bool Manual, duint InstructionCount = 0);

View File

@ -41,7 +41,7 @@ bool LabelSet(duint Address, const char* Text, bool Manual)
LABELSINFO label;
if(!labels.PrepareValue(label, Address, Manual))
return false;
strcpy_s(label.text, Text);
label.text = Text;
return labels.Add(label);
}
@ -49,10 +49,10 @@ bool LabelFromString(const char* Text, duint* Address)
{
return labels.GetWhere([&](const LABELSINFO & value)
{
if(strcmp(value.text, Text))
if(strcmp(value.text.c_str(), Text))
return false;
if(Address)
*Address = value.addr + ModBaseFromName(value.mod);
*Address = value.addr + ModBaseFromName(value.mod().c_str());
return true;
});
}
@ -63,7 +63,7 @@ bool LabelGet(duint Address, char* Text)
if(!labels.Get(Labels::VaKey(Address), label))
return false;
if(Text)
strcpy_s(Text, MAX_LABEL_SIZE, label.text);
strcpy_s(Text, MAX_LABEL_SIZE, label.text.c_str());
return true;
}

View File

@ -6,7 +6,7 @@
struct LABELSINFO : AddrInfo
{
char text[MAX_LABEL_SIZE];
std::string text;
};
bool LabelSet(duint Address, const char* Text, bool Manual);

View File

@ -36,7 +36,7 @@ bool LoopAdd(duint Start, duint End, bool Manual, duint instructionCount)
loopInfo.depth = finalDepth;
loopInfo.manual = Manual;
loopInfo.instructioncount = instructionCount;
ModNameFromAddr(Start, loopInfo.mod, true);
loopInfo.modhash = ModHashFromAddr(moduleBase);
// Link this to a parent loop if one does exist
if(finalDepth)
@ -49,7 +49,7 @@ bool LoopAdd(duint Start, duint End, bool Manual, duint instructionCount)
EXCLUSIVE_ACQUIRE(LockLoops);
// Insert into list
loops.insert(std::make_pair(DepthModuleRange(finalDepth, ModuleRange(ModHashFromAddr(moduleBase), Range(loopInfo.start, loopInfo.end))), loopInfo));
loops.insert(std::make_pair(DepthModuleRange(finalDepth, ModuleRange(loopInfo.modhash, Range(loopInfo.start, loopInfo.end))), loopInfo));
return true;
}
@ -182,7 +182,7 @@ void LoopCacheSave(JSON Root)
const LOOPSINFO & currentLoop = itr.second;
JSON currentJson = json_object();
json_object_set_new(currentJson, "module", json_string(currentLoop.mod));
json_object_set_new(currentJson, "module", json_string(currentLoop.mod().c_str()));
json_object_set_new(currentJson, "start", json_hex(currentLoop.start));
json_object_set_new(currentJson, "end", json_hex(currentLoop.end));
json_object_set_new(currentJson, "depth", json_integer(currentLoop.depth));
@ -220,13 +220,12 @@ void LoopCacheLoad(JSON Root)
json_array_foreach(Object, i, value)
{
LOOPSINFO loopInfo;
memset(&loopInfo, 0, sizeof(LOOPSINFO));
// Module name
const char* mod = json_string_value(json_object_get(value, "module"));
if(mod && strlen(mod) < MAX_MODULE_SIZE)
strcpy_s(loopInfo.mod, mod);
loopInfo.modhash = ModHashFromName(mod);
// All other variables
loopInfo.start = (duint)json_hex_value(json_object_get(value, "start"));
@ -241,7 +240,7 @@ void LoopCacheLoad(JSON Root)
continue;
// Insert into global list
loops[DepthModuleRange(loopInfo.depth, ModuleRange(ModHashFromName(loopInfo.mod), Range(loopInfo.start, loopInfo.end)))] = loopInfo;
loops[DepthModuleRange(loopInfo.depth, ModuleRange(loopInfo.modhash, Range(loopInfo.start, loopInfo.end)))] = loopInfo;
}
};
@ -277,7 +276,7 @@ bool LoopEnum(LOOPSINFO* List, size_t* Size)
*List = itr.second;
// Adjust the offset to a real virtual address
duint modbase = ModBaseFromName(List->mod);
duint modbase = ModBaseFromName(List->mod().c_str());
List->start += modbase;
List->end += modbase;
@ -290,5 +289,6 @@ bool LoopEnum(LOOPSINFO* List, size_t* Size)
void LoopClear()
{
EXCLUSIVE_ACQUIRE(LockLoops);
loops.clear();
std::map<DepthModuleRange, LOOPSINFO, DepthModuleRangeCompare> empty;
std::swap(loops, empty);
}

View File

@ -5,13 +5,18 @@
struct LOOPSINFO
{
char mod[MAX_MODULE_SIZE];
duint modhash;
duint start;
duint end;
duint parent;
int depth;
bool manual;
duint instructioncount;
std::string mod() const
{
return ModNameFromHash(modhash);
}
};
bool LoopAdd(duint Start, duint End, bool Manual, duint InstructionCount = 0);

View File

@ -7,6 +7,7 @@
#include "label.h"
std::map<Range, MODINFO, RangeCompare> modinfo;
std::unordered_map<duint, std::string> hashNameMap;
void GetModuleInfo(MODINFO & Info, ULONG_PTR FileMapVA)
{
@ -197,20 +198,26 @@ bool ModUnload(duint Base)
void ModClear()
{
// Clean up all the modules
EXCLUSIVE_ACQUIRE(LockModules);
for(const auto & mod : modinfo)
{
// Unload the mapped file from memory
const auto & info = mod.second;
if(info.fileMapVA)
StaticFileUnloadW(StringUtils::Utf8ToUtf16(info.path).c_str(), false, info.fileHandle, info.loadedSize, info.fileMap, info.fileMapVA);
// Clean up all the modules
EXCLUSIVE_ACQUIRE(LockModules);
for(const auto & mod : modinfo)
{
// Unload the mapped file from memory
const auto & info = mod.second;
if(info.fileMapVA)
StaticFileUnloadW(StringUtils::Utf8ToUtf16(info.path).c_str(), false, info.fileHandle, info.loadedSize, info.fileMap, info.fileMapVA);
}
modinfo.clear();
}
modinfo.clear();
EXCLUSIVE_RELEASE();
{
// Clean up the reverse hash map
EXCLUSIVE_ACQUIRE(LockModuleHashes);
hashNameMap.clear();
}
// Tell the symbol updater
GuiSymbolUpdateModuleList(0, nullptr);
@ -285,8 +292,19 @@ duint ModHashFromName(const char* Module)
auto len = int(strlen(Module));
if(!len)
return 0;
auto hash = murmurhash(Module, len);
return murmurhash(Module, len);
//update the hash cache
SHARED_ACQUIRE(LockModuleHashes);
auto hashInCache = hashNameMap.find(hash) != hashNameMap.end();
SHARED_RELEASE();
if(!hashInCache)
{
EXCLUSIVE_ACQUIRE(LockModuleHashes);
hashNameMap[hash] = Module;
}
return hash;
}
duint ModBaseFromName(const char* Module)
@ -325,6 +343,15 @@ duint ModSizeFromAddr(duint Address)
return module->size;
}
std::string ModNameFromHash(duint Hash)
{
SHARED_ACQUIRE(LockModuleHashes);
auto found = hashNameMap.find(Hash);
if(found == hashNameMap.end())
return std::string();
return found->second;
}
bool ModSectionsFromAddr(duint Address, std::vector<MODSECTIONINFO>* Sections)
{
SHARED_ACQUIRE(LockModules);
@ -444,4 +471,4 @@ void ModSetParty(duint Address, int Party)
return;
module->party = Party;
}
}

View File

@ -49,6 +49,7 @@ duint ModHashFromAddr(duint Address);
duint ModHashFromName(const char* Module);
duint ModBaseFromName(const char* Module);
duint ModSizeFromAddr(duint Address);
std::string ModNameFromHash(duint Hash);
bool ModSectionsFromAddr(duint Address, std::vector<MODSECTIONINFO>* Sections);
bool ModImportsFromAddr(duint Address, std::vector<MODIMPORTINFO>* Imports);
duint ModEntryFromAddr(duint Address);

View File

@ -20,24 +20,21 @@ public:
virtual bool Load(TValue & value) = 0;
protected:
void setString(const char* key, const char* value)
void setString(const char* key, const std::string & value)
{
set(key, json_string(value));
set(key, json_string(value.c_str()));
}
template<size_t TSize>
bool getString(const char* key, char(&_Dest)[TSize]) const
bool getString(const char* key, std::string & dest) const
{
auto jsonValue = get(key);
if(!jsonValue)
return false;
auto str = json_string_value(jsonValue);
if(str && strlen(str) < TSize)
{
strcpy_s(_Dest, str);
return true;
}
return false;
if(!str)
return false;
dest = str;
return true;
}
void setHex(const char* key, duint value)
@ -162,7 +159,8 @@ public:
void Clear()
{
EXCLUSIVE_ACQUIRE(TLock);
mMap.clear();
TMap empty;
std::swap(mMap, empty);
}
void CacheSave(JSON root) const
@ -329,9 +327,14 @@ struct SerializableModuleHashMap : SerializableUnorderedMap<TLock, duint, TValue
struct AddrInfo
{
char mod[MAX_MODULE_SIZE];
duint modhash;
duint addr;
bool manual;
std::string mod() const
{
return ModNameFromHash(modhash);
}
};
template<class TValue>
@ -341,7 +344,7 @@ struct AddrInfoSerializer : JSONWrapper<TValue>
bool Save(const TValue & value) override
{
setString("module", value.mod);
setString("module", value.mod());
setHex("address", value.addr);
setBool("manual", value.manual);
return true;
@ -351,8 +354,11 @@ struct AddrInfoSerializer : JSONWrapper<TValue>
{
value.manual = true; //legacy support
getBool("manual", value.manual);
return getString("module", value.mod) &&
getHex("address", value.addr);
std::string mod;
if(!getString("module", mod))
return false;
value.modhash = ModHashFromName(mod.c_str());
return getHex("address", value.addr);
}
};
@ -364,17 +370,17 @@ struct AddrInfoHashMap : SerializableModuleHashMap<TLock, TValue, TSerializer>
void AdjustValue(TValue & value) const override
{
value.addr += ModBaseFromName(value.mod);
value.addr += ModBaseFromName(value.mod().c_str());
}
bool PrepareValue(TValue & value, duint addr, bool manual)
{
if(!MemIsValidReadPtr(addr))
return false;
if(!ModNameFromAddr(addr, value.mod, true))
*value.mod = '\0';
auto base = ModBaseFromAddr(addr);
value.modhash = ModHashFromAddr(base);
value.manual = manual;
value.addr = addr - ModBaseFromAddr(addr);
value.addr = addr - base;
return true;
}
@ -391,6 +397,6 @@ struct AddrInfoHashMap : SerializableModuleHashMap<TLock, TValue, TSerializer>
protected:
duint makeKey(const TValue & value) const override
{
return ModHashFromName(value.mod) + value.addr;
return value.modhash + value.addr;
}
};

View File

@ -70,6 +70,7 @@ enum SectionLock
LockSymbolCache,
LockLineCache,
LockTypeManager,
LockModuleHashes,
// Number of elements in this enumeration. Must always be the last
// index.