diff --git a/pykd/livevar.cpp b/pykd/livevar.cpp index c3d0718..3996b80 100644 --- a/pykd/livevar.cpp +++ b/pykd/livevar.cpp @@ -21,12 +21,15 @@ struct addLocals { ULONG m_rva; Ctx::ContextPtr m_ctx; IDebugClient4 *m_client; + ULONG m_formalNameCounter; void append(pyDia::SymbolPtr symParent); private: void appendVar(pyDia::SymbolPtr symData); + void generateUniqueName(std::string &varName); + TypedVarPtr getTypeVarByOffset( pyDia::SymbolPtr symData, ULONG64 varOffset @@ -81,6 +84,10 @@ void addLocals::appendVar(pyDia::SymbolPtr symData) std::string varName = symData->getName(); + // check name for unique. f.e. may be may be somewhat parameters + // with name "__formal" + generateUniqueName(varName); + switch (symData->getLocType()) { case LocIsStatic: @@ -107,6 +114,22 @@ void addLocals::appendVar(pyDia::SymbolPtr symData) //////////////////////////////////////////////////////////////////////////////// +void addLocals::generateUniqueName(std::string &varName) +{ + if ( !m_locals.has_key(varName) ) + return; + + std::string origVarName = varName; + while ( m_locals.has_key(varName) ) + { + std::stringstream sstream; + sstream << origVarName << ++m_formalNameCounter; + varName = sstream.str(); + } +} + +//////////////////////////////////////////////////////////////////////////////// + TypedVarPtr addLocals::getTypeVarByOffset( pyDia::SymbolPtr symData, ULONG64 varOffset @@ -176,7 +199,7 @@ python::dict DebugClient::getLocals(Ctx::ContextPtr ctx OPTIONAL) return python::dict(); // out of function debug range python::dict locals; - impl::addLocals Locals = { locals, mod, rva, ctx, m_client }; + impl::addLocals Locals = { locals, mod, rva, ctx, m_client, 0 }; Locals.append(symFunc); diff --git a/test/scripts/diatest.py b/test/scripts/diatest.py index 251885c..1287a50 100644 --- a/test/scripts/diatest.py +++ b/test/scripts/diatest.py @@ -232,7 +232,7 @@ class DiaTest( unittest.TestCase ): try: gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertEqual( pykd.DataIsGlobal, gScope["g_structTest"].dataKind() ) - self.assertEqual( pykd.DataIsParam, gScope["EnumWindowsProc"]["hWindow"].dataKind() ) + self.assertEqual( pykd.DataIsParam, gScope["EnumWindowsProc1"]["hWindow"].dataKind() ) except pykd.DiaException as diaExcept: print diaExcept self.assertTrue(False) diff --git a/test/scripts/localstest.py b/test/scripts/localstest.py index bf3adab..4d9e3df 100644 --- a/test/scripts/localstest.py +++ b/test/scripts/localstest.py @@ -6,13 +6,13 @@ import pykd class LocalVarsTest(unittest.TestCase): def testLocalVariable(self): - """Start new process and break in targetapp!EnumWindowsProc""" + """Start new process and test local variables""" testClient = pykd.createDbgClient() testClient.startProcess( target.appPath + " -testEnumWindows" ) testClient.go() # initial breakpoint -> wmain - testClient.go() # wmain -> targetapp!EnumWindowsProc + testClient.go() # wmain -> targetapp!EnumWindowsProc1 # pykd.dprint( "\n" + testClient.dbgCommand("u") ) locals = testClient.getLocals() @@ -30,3 +30,10 @@ class LocalVarsTest(unittest.TestCase): self.assertEqual( pykd.DataIsStaticLocal, locals["staticVar"].dataKind() ) self.assertEqual( locals["dwProccessId"] + 1, locals["staticVar"] ) + + testClient.go() # targetapp!EnumWindowsProc1 -> targetapp!EnumWindowsProc2 + locals = testClient.getLocals() + self.assertEqual( len(locals), 2 ) + locValues = locals.values() + self.assertTrue( locValues[0] == 7 or locValues[1] == 7 ) + diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp index e98afe4..1c90f24 100644 --- a/test/targetapp/targetapp.cpp +++ b/test/targetapp/targetapp.cpp @@ -259,7 +259,7 @@ void FuncWithName1(int a) //////////////////////////////////////////////////////////////////////////////// #pragma optimize("g", off) -BOOL CALLBACK EnumWindowsProc( +BOOL CALLBACK EnumWindowsProc1( HWND hWindow, const LPARAM lParam ) @@ -278,6 +278,15 @@ BOOL CALLBACK EnumWindowsProc( } return hWindow ? FALSE : TRUE; } + +//////////////////////////////////////////////////////////////////////////////// + +BOOL CALLBACK EnumWindowsProc2(HWND, LPARAM) +{ + __debugbreak(); + return FALSE; +} + #pragma optimize("g", on) //////////////////////////////////////////////////////////////////////////////// @@ -317,7 +326,8 @@ int _tmain(int argc, _TCHAR* argv[]) if ( !_tcsicmp(argv[1], _T("-testEnumWindows")) ) { - ::EnumWindows(&EnumWindowsProc, 6); + ::EnumWindows(&EnumWindowsProc1, 6); + ::EnumWindows(&EnumWindowsProc2, 7); return ERROR_SUCCESS; } }