diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h
index cc644b5..7d1dde3 100644
--- a/pykd/dbgengine.h
+++ b/pykd/dbgengine.h
@@ -59,8 +59,7 @@ struct STACK_FRAME_DESC {
     ULONG64 stackOffset;
 };
 
-ULONG getStackTraceFrameCount();
-void getStackTrace( STACK_FRAME_DESC* frames, ULONG frameCount, ULONG* frameReturned = NULL );
+void getStackTrace(std::vector<STACK_FRAME_DESC> &frames);
 
 //breakpoints
 ULONG breakPointSet( ULONG64 offset, bool hardware = false, ULONG size = 0, ULONG accessType = 0 );
diff --git a/pykd/dia/diawrapper.cpp b/pykd/dia/diawrapper.cpp
index 62b94b2..f5ee616 100644
--- a/pykd/dia/diawrapper.cpp
+++ b/pykd/dia/diawrapper.cpp
@@ -8,6 +8,36 @@ namespace pykd {
 
 ///////////////////////////////////////////////////////////////////////////////
 
+static const struct DiaRegToRegRelativeAmd64 : DiaRegToRegRelativeBase
+{
+    typedef std::map<ULONG, ULONG> Base;
+    DiaRegToRegRelativeAmd64();
+} g_DiaRegToRegRelativeAmd64;
+
+DiaRegToRegRelativeAmd64::DiaRegToRegRelativeAmd64()
+{
+    (*this)[CV_AMD64_RIP] = rriInstructionPointer;
+    (*this)[CV_AMD64_RBP] = rriStackFrame;
+    (*this)[CV_AMD64_RSP] = rriStackPointer;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static const struct DiaRegToRegRelativeI386 : DiaRegToRegRelativeBase
+{
+    typedef std::map<ULONG, ULONG> Base;
+    DiaRegToRegRelativeI386();
+} g_DiaRegToRegRelativeI386;
+
+DiaRegToRegRelativeI386::DiaRegToRegRelativeI386()
+{
+    (*this)[CV_REG_EIP] = rriInstructionPointer;
+    (*this)[CV_REG_EBP] = rriStackFrame;
+    (*this)[CV_REG_ESP] = rriStackPointer;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 const std::string DiaException::descPrefix("pyDia: ");
 
 std::string DiaException::makeFullDesc(const std::string &desc, HRESULT hres)
@@ -96,18 +126,21 @@ std::string getBasicTypeName( ULONG basicType )
 
 ////////////////////////////////////////////////////////////////////////////////
 
-DiaSymbol::DiaSymbol(__inout DiaSymbolPtr &_symbol )
+DiaSymbol::DiaSymbol(__inout DiaSymbolPtr &_symbol, DWORD machineType )
+    : m_symbol(_symbol), m_machineType(machineType)
 {
-    m_symbol = _symbol;
-    m_symbol->get_machineType(&m_machineType);
 }
 
 //////////////////////////////////////////////////////////////////////////////////
 
-DiaSymbol::DiaSymbol( IDiaSymbol *_symbol )
+SymbolPtr DiaSymbol::fromGlobalScope( IDiaSymbol *_symbol )
 {
-    m_symbol = _symbol;
-    m_symbol->get_machineType(&m_machineType);
+    DWORD machineType;
+    HRESULT hres = _symbol->get_machineType(&machineType);
+    if (S_OK != hres)
+        throw DiaException("IDiaSymbol::get_machineType", hres);
+
+    return SymbolPtr( new DiaSymbol(DiaSymbolPtr(_symbol), machineType) );
 }
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -148,7 +181,7 @@ SymbolPtrList  DiaSymbol::findChildren(
     ULONG celt;
     while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
     {
-        childList.push_back( SymbolPtr( new DiaSymbol(child) ) );
+        childList.push_back( SymbolPtr( new DiaSymbol(child, m_machineType) ) );
         child = NULL;
     }
 
@@ -220,7 +253,7 @@ SymbolPtr DiaSymbol::getChildByIndex(ULONG symTag, ULONG _index )
     if (S_OK != hres)
         throw DiaException("Call IDiaEnumSymbols::Item", hres);
 
-    return SymbolPtr( new DiaSymbol(child) );
+    return SymbolPtr( new DiaSymbol(child, m_machineType) );
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -247,7 +280,7 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name )
         if (S_OK != hres)
             throw DiaException("Call IDiaEnumSymbols::Item", hres);
 
-        return SymbolPtr( new DiaSymbol(child) );
+        return SymbolPtr( new DiaSymbol(child, m_machineType) );
     }
 
     std::string     pattern = "*";
@@ -279,7 +312,7 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name )
         if (S_OK != hres)
             throw DiaException("Call IDiaEnumSymbols::Item", hres);
 
-        SymbolPtr  symPtr = SymbolPtr( new DiaSymbol(child) );
+        SymbolPtr  symPtr = SymbolPtr( new DiaSymbol(child, m_machineType) );
 
         if ( name == symPtr->getName() )
             return symPtr;
@@ -304,6 +337,33 @@ ULONG DiaSymbol::getDataKind()
 
 ////////////////////////////////////////////////////////////////////////////////
 
+ULONG DiaSymbol::getRegRealativeId()
+{
+    switch (m_machineType)
+    {
+    case IMAGE_FILE_MACHINE_AMD64:
+        return getRegRealativeIdImpl(g_DiaRegToRegRelativeAmd64);
+    case IMAGE_FILE_MACHINE_I386:
+        return getRegRealativeIdImpl(g_DiaRegToRegRelativeI386);
+    }
+    throw DiaException("Unsupported machine type");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+ULONG DiaSymbol::getRegRealativeIdImpl(const DiaRegToRegRelativeBase &DiaRegToRegRelative)
+{
+    DiaRegToRegRelativeBase::const_iterator it = 
+        DiaRegToRegRelative.find(callSymbol(get_registerId));
+
+    if (it == DiaRegToRegRelative.end())
+        throw DiaException("Cannot convert DAI register ID to relative register ID");
+
+    return it->second;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 ULONG DiaSymbol::getIndexId()
 {
     return callSymbol(get_symIndexId);
@@ -313,7 +373,8 @@ ULONG DiaSymbol::getIndexId()
 
 SymbolPtr DiaSymbol::getIndexType()
 {
-    return SymbolPtr( new DiaSymbol(callSymbol(get_arrayIndexType) ) );
+    DiaSymbolPtr diaSymbol(callSymbol(get_arrayIndexType));
+    return SymbolPtr( new DiaSymbol(diaSymbol, m_machineType) );
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -381,7 +442,8 @@ ULONG DiaSymbol::getSymTag()
 
 SymbolPtr DiaSymbol::getType()
 {
-    return SymbolPtr( new DiaSymbol( callSymbol(get_type) ) );
+    DiaSymbolPtr diaSymbol(callSymbol(get_type));
+    return SymbolPtr( new DiaSymbol( diaSymbol, m_machineType ) );
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -480,9 +542,10 @@ ULONG DiaSymbol::getVirtualBaseDispIndex()
 
 ULONG DiaSymbol::getVirtualBaseDispSize()
 {
-   SymbolPtr   baseTableType = SymbolPtr( new DiaSymbol( callSymbol(get_virtualBaseTableType) ) );
+    DiaSymbolPtr diaSymbol(callSymbol(get_virtualBaseTableType));
+    SymbolPtr baseTableType = SymbolPtr( new DiaSymbol( diaSymbol, m_machineType ) );
 
-   return (ULONG)baseTableType->getType()->getSize();
+    return (ULONG)baseTableType->getType()->getSize();
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -534,10 +597,13 @@ SymbolPtr DiaSession::findByRva( ULONG rva, ULONG symTag, LONG* pdisplacement )
         throw DiaException("Call IDiaSession::findSymbolByRVAEx", hres);
     if (!child)
         throw DiaException("Call IDiaSession::findSymbolByRVAEx", E_UNEXPECTED);
-    if ( pdisplacement == NULL && displacement != 0 )
+    if ( !pdisplacement && displacement)
         throw DiaException("Call IDiaSession::findSymbolByRVAEx failed to find suymbol" );
 
-    return SymbolPtr( new DiaSymbol(child) );
+    if (pdisplacement)
+        *pdisplacement = displacement;
+
+    return SymbolPtr( new DiaSymbol(child, m_globalSymbol->getMachineType() ) );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/pykd/dia/diawrapper.h b/pykd/dia/diawrapper.h
index bd40afa..a42053e 100644
--- a/pykd/dia/diawrapper.h
+++ b/pykd/dia/diawrapper.h
@@ -19,6 +19,8 @@ typedef CComPtr< IDiaEnumLineNumbers > DiaEnumLineNumbersPtr;
 typedef CComPtr< IDiaLineNumber> DiaLineNumberPtr;
 typedef CComPtr< IDiaSourceFile > DiaSourceFilePtr;
 
+typedef std::map<ULONG, ULONG> DiaRegToRegRelativeBase;
+
 //////////////////////////////////////////////////////////////////////////////
 
 class DiaException : public SymbolException {
@@ -51,10 +53,9 @@ private:
 
 class DiaSymbol : public Symbol {
 public:
+    DiaSymbol( DiaSymbolPtr &_symbol, DWORD machineType );
 
-    DiaSymbol( DiaSymbolPtr &_symbol );
-
-    DiaSymbol( IDiaSymbol *_symbol );
+    static SymbolPtr fromGlobalScope( IDiaSymbol *_symbol );
 
     SymbolPtr getChildByName(const std::string &_name );
 
@@ -105,6 +106,7 @@ public:
     ULONG getDataKind();
 
     //ULONG getRegisterId();
+    virtual ULONG getRegRealativeId() override;
 
     ULONG getMachineType() {
         return m_machineType;
@@ -195,6 +197,8 @@ protected:
     //    const char *prefix = NULL
     //);
 
+    ULONG getRegRealativeIdImpl(const DiaRegToRegRelativeBase &DiaRegToRegRelative);
+
     template <typename TRet>
     TRet callSymbolT(
         HRESULT(STDMETHODCALLTYPE IDiaSymbol::*method)(TRet *),
@@ -222,8 +226,8 @@ public:
 
     DiaSession( IDiaSession* session, IDiaSymbol *globalScope ) :
         m_globalScope( globalScope ),
-        m_session( session ),
-        m_globalSymbol( new DiaSymbol( globalScope ) )
+        m_globalSymbol( DiaSymbol::fromGlobalScope( globalScope ) ),
+        m_session( session )
         {}
 
     SymbolPtr& getSymbolScope() {
diff --git a/pykd/localvar.cpp b/pykd/localvar.cpp
index 66d563f..1658eb6 100644
--- a/pykd/localvar.cpp
+++ b/pykd/localvar.cpp
@@ -18,10 +18,189 @@ python::dict getLocals()
 
 ///////////////////////////////////////////////////////////////////////////////
 
-python::dict getLocalsByFrame( StackFrame &frame )
+class BuildLocals
 {
-    python::dict  dct;
-    return dct;
+public:
+    BuildLocals( ModulePtr mod, const StackFrame &frame )
+        : m_mod(mod), m_frame(frame), m_formalGen(0) 
+    {
+        m_ipRva = static_cast<ULONG>(m_frame.m_instructionOffset - m_mod->getBase());
+    }
+
+    void process( SymbolPtr symParent );
+
+    python::dict &getResult() {
+         return m_dct;
+    }
+
+protected:
+    void addVar(SymbolPtr symVar);
+
+private:
+    ModulePtr m_mod;
+    const StackFrame &m_frame;
+    python::dict m_dct;
+    size_t m_formalGen;
+    ULONG m_ipRva;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+void BuildLocals::process(
+    SymbolPtr symParent
+)
+{
+    // add vars from current scope
+    SymbolPtrList symList = symParent->findChildren(SymTagData);
+    SymbolPtrList::iterator itVar = symList.begin();
+    for (; itVar != symList.end(); ++itVar)
+        addVar(*itVar);
+
+    // find inners scopes
+    symList = symParent->findChildren(SymTagBlock);
+    SymbolPtrList::iterator itScope = symList.begin();
+    for (; itScope != symList.end(); ++itScope)
+    {
+        SymbolPtr scope = *itScope;
+        ULONG scopeRva = scope->getRva();
+        if (scopeRva <= m_ipRva && (scopeRva + scope->getSize()) > m_ipRva)
+            process(scope);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void BuildLocals::addVar(SymbolPtr symVar)
+{
+    std::string name;
+    try
+    {
+        name = symVar->getName();
+        if (name.empty())
+            return;
+    }
+    catch (const SymbolException &except)
+    {
+        DBG_UNREFERENCED_PARAMETER(except);
+        return;
+    }
+
+    if (m_dct.has_key(name))
+    {
+        std::stringstream sstream;
+        sstream << name << "#" << std::dec << ++m_formalGen;
+        name = sstream.str();
+    }
+
+    BOOST_ASSERT(!m_dct.has_key(name));
+    if (m_dct.has_key(name))
+        return;
+
+    ULONG64 varAddr;
+    const LocationType locType = static_cast<LocationType>(symVar->getLocType());
+    switch (locType)
+    {
+    case LocIsStatic:
+        varAddr = m_mod->getBase() + symVar->getRva();
+        break;
+
+    case LocIsRegRel:
+        {
+            RegRealativeId rri;
+            try
+            {
+                rri = static_cast<RegRealativeId>(symVar->getRegRealativeId());
+            }
+            catch (const DbgException &except)
+            {
+                DBG_UNREFERENCED_PARAMETER(except);
+                return;
+            }
+            varAddr = m_frame.getValue(rri, symVar->getOffset());
+        }
+        break;
+
+    default:
+        BOOST_ASSERT(LocIsEnregistered == locType);
+        return;
+    }
+
+    TypeInfoPtr typeInfo = TypeInfo::getTypeInfo(symVar);
+    TypedVarPtr typedVar = TypedVar::getTypedVarByTypeInfo(typeInfo, varAddr);
+    typedVar->setDataKind( symVar->getDataKind() );
+    m_dct[name] = typedVar;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static bool IsInDebugRange(
+    SymbolPtr func,
+    ULONG ipRva
+)
+{
+    SymbolPtrList lstFuncDebugStart;
+    SymbolPtrList lstFuncDebugEnd;
+
+    try
+    {
+        lstFuncDebugStart = func->findChildren(SymTagFuncDebugStart);
+        if (1 != lstFuncDebugStart.size())
+        {
+            BOOST_ASSERT(lstFuncDebugStart.empty());
+            return true;
+        }
+
+        lstFuncDebugEnd = func->findChildren(SymTagFuncDebugEnd);
+        if (1 != lstFuncDebugEnd.size())
+        {
+            BOOST_ASSERT(lstFuncDebugEnd.empty());
+            return true;
+        }
+    }
+    catch (const SymbolException &except)
+    {
+        DBG_UNREFERENCED_PARAMETER(except);
+        return true;
+    }
+
+    return 
+        ((*lstFuncDebugStart.begin())->getRva() <= ipRva) &&
+        ((*lstFuncDebugEnd.begin())->getRva() >= ipRva);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+python::dict getLocalsByFrame( const StackFrame &frame )
+{
+    // query target fuction by $ip register
+    ModulePtr mod;
+    SymbolPtr func;
+    try
+    {
+        mod = Module::loadModuleByOffset(frame.m_instructionOffset);
+        LONG displacemnt;
+        func = mod->getSymbolByVa(frame.m_instructionOffset, SymTagFunction, &displacemnt );
+    }
+    catch (const DbgException &except)
+    {
+        DBG_UNREFERENCED_PARAMETER(except);
+        return python::dict();
+    }
+
+#ifdef _DEBUG
+    std::string funcName;
+    funcName = func->getName();
+#endif  // _DEBUG
+
+    if (!IsInDebugRange(func, static_cast<ULONG>(frame.m_instructionOffset - mod->getBase())))
+    {
+        // not in debug range
+        return python::dict();
+    }
+
+    BuildLocals buildLocals(mod, frame);
+    buildLocals.process(func);
+    return buildLocals.getResult();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/pykd/localvar.h b/pykd/localvar.h
index 35ebdcc..f4ae3c2 100644
--- a/pykd/localvar.h
+++ b/pykd/localvar.h
@@ -8,7 +8,7 @@ namespace pykd {
 
 python::dict getLocals();
 
-python::dict getLocalsByFrame( StackFrame &frame );
+python::dict getLocalsByFrame( const StackFrame &frame );
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/pykd/module.cpp b/pykd/module.cpp
index bb61b9b..3d01402 100644
--- a/pykd/module.cpp
+++ b/pykd/module.cpp
@@ -220,10 +220,10 @@ std::string Module::getSymbolNameByVa( ULONG64 offset )
 
     sstr << sym->getName();
 
-    if ( displacement > 0 )
+    if ( displacement > 0 && displacement )
         sstr << '+' << std::hex << displacement;
     else if ( displacement < 0 )
-        sstr << '-' << std::hex << -displacement;        
+        sstr << '-' << std::hex << -displacement;
 
     return sstr.str();
 }
diff --git a/pykd/module.h b/pykd/module.h
index e0c8cd5..12d2abf 100644
--- a/pykd/module.h
+++ b/pykd/module.h
@@ -94,7 +94,7 @@ public:
 
     ULONG64 getSymbolSize( const std::string &symName );
 
-    SymbolPtr getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacemnt );
+    SymbolPtr getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacemnt = NULL );
 
     std::string getSymbolNameByVa( ULONG64 offset );
 
diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj
index 49ca1f4..24fdecb 100644
--- a/pykd/pykd_2008.vcproj
+++ b/pykd/pykd_2008.vcproj
@@ -1,10 +1,14 @@
 <?xml version="1.0" encoding="windows-1251"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="9,00"
+	Version="9.00"
 	Name="pykd"
 	ProjectGUID="{FE961905-666F-4908-A212-961465F46F13}"
 	RootNamespace="pykd"
+	SccProjectName="$/pykd/branch/0.2.x/pykd"
+	SccAuxPath="https://tfs.codeplex.com/tfs/TFS08"
+	SccLocalPath="."
+	SccProvider="{4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}"
 	Keyword="Win32Proj"
 	TargetFrameworkVersion="0"
 	>
diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp
index 796aa7f..b2e8fad 100644
--- a/pykd/pymod.cpp
+++ b/pykd/pymod.cpp
@@ -295,7 +295,7 @@ BOOST_PYTHON_MODULE( pykd )
         .def("offset", &Module::getSymbolOffset,
             "Return offset of the symbol" )
         .def("findSymbol", &Module::getSymbolNameByVa,
-            "Return symbol name by offset" )
+            "Return symbol name by virtual address" )
         .def("rva", &Module::getSymbolRva,
             "Return rva of the symbol" )
         .def("sizeof", &Module::getSymbolSize,
@@ -382,8 +382,8 @@ BOOST_PYTHON_MODULE( pykd )
             "Return a frame's stack offset" )
         .def_readonly( "frameNumber", &StackFrame::m_frameNumber,
             "Return a frame's number" )
-        //.def( "getLocals", &StackFrame::getLocals, StackFrame_getLocals( python::args( "ctx" ),
-        //    "Get list of local variables for this stack frame" ) )
+        .def( "getLocals", &StackFrame::getLocals,
+             "Get list of local variables for this stack frame" )
         .def( "__str__", &StackFrame::print,
             "Return stacks frame as a string");
 
diff --git a/pykd/stkframe.cpp b/pykd/stkframe.cpp
index e3b43fb..7e4b19f 100644
--- a/pykd/stkframe.cpp
+++ b/pykd/stkframe.cpp
@@ -41,27 +41,38 @@ std::string StackFrame::print() const
 
 ////////////////////////////////////////////////////////////////////////////////
 
-python::dict StackFrame::getLocals()
+python::dict StackFrame::getLocals() const
 {
     return getLocalsByFrame( *this );
 }
 
+///////////////////////////////////////////////////////////////////////////////
+
+ULONG64 StackFrame::getValue(RegRealativeId rri, LONG64 offset /*= 0*/) const
+{
+    switch (rri)
+    {
+    case rriInstructionPointer: return m_instructionOffset + offset;
+    case rriStackFrame: return m_frameOffset + offset;
+    case rriStackPointer: return m_stackOffset + offset;
+    }
+
+    BOOST_ASSERT(!"Unexcepted error");
+    throw DbgException(__FUNCTION__ " Unexcepted error" );
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 python::list getCurrentStack()
 {
-    ULONG  frameCount = getStackTraceFrameCount();
+    std::vector<STACK_FRAME_DESC> frames; 
+    getStackTrace( frames );
 
-    std::vector<STACK_FRAME_DESC>  frames(frameCount); 
+    python::list frameList;
 
-    getStackTrace( &frames[0], frameCount );
-
-    python::list    frameList;
-
-    for ( ULONG i = 0; i < frameCount; ++i )
+    for ( ULONG i = 0; i < frames.size(); ++i )
     {
         python::object  frameObj( StackFrame( frames.at(i) ) ); 
-
         frameList.append( frameObj );
     }
 
@@ -72,12 +83,8 @@ python::list getCurrentStack()
 
 StackFrame getCurrentStackFrame()
 {
-    ULONG  frameCount = getStackTraceFrameCount();
-
-    std::vector<STACK_FRAME_DESC>  frames(frameCount); 
-
-    getStackTrace( &frames[0], frameCount );
-
+    std::vector<STACK_FRAME_DESC> frames; 
+    getStackTrace( frames );
     return frames[0];
 }
 
diff --git a/pykd/stkframe.h b/pykd/stkframe.h
index 3bd2c22..d9af538 100644
--- a/pykd/stkframe.h
+++ b/pykd/stkframe.h
@@ -6,6 +6,7 @@
 
 #include "dbgengine.h"
 #include "context.h"
+#include "symengine.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -18,10 +19,12 @@ class StackFrame
 public:
     StackFrame( const STACK_FRAME_DESC& desc );
 
-    python::dict getLocals();
+    python::dict getLocals() const;
 
     std::string print() const;
 
+    ULONG64 getValue(RegRealativeId rri, LONG64 offset = 0) const;
+
 public:
 
     ULONG  m_frameNumber;
diff --git a/pykd/symengine.h b/pykd/symengine.h
index 1bb85d6..385453d 100644
--- a/pykd/symengine.h
+++ b/pykd/symengine.h
@@ -111,6 +111,15 @@ enum BasicType
 
 ////////////////////////////////////////////////////////////////////////////////
 
+enum RegRealativeId
+{
+    rriInstructionPointer,
+    rriStackFrame,
+    rriStackPointer
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
 class Symbol {
 
 public:
@@ -144,7 +153,7 @@ public:
     virtual bool isConstant() = 0;
     virtual bool isIndirectVirtualBaseClass() = 0;
     virtual bool isVirtualBaseClass() = 0;
-   
+    virtual ULONG getRegRealativeId() = 0;  // <- RegRealativeId
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/pykd/win/dbgeng.cpp b/pykd/win/dbgeng.cpp
index da8bc38..6185322 100644
--- a/pykd/win/dbgeng.cpp
+++ b/pykd/win/dbgeng.cpp
@@ -673,46 +673,26 @@ ULONG64 getRegInstructionPointer()
 
 ///////////////////////////////////////////////////////////////////////////////
 
-ULONG getStackTraceFrameCount()
+void getStackTrace(std::vector<STACK_FRAME_DESC> &frames)
 {
     PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
 
-    HRESULT  hres;
-    ULONG  filledFrames;
-
-    hres = g_dbgEng->control->GetStackTrace( 0, 0, 0, NULL, 0, &filledFrames );
-    if ( FAILED( hres ) )
-        throw DbgException( "IDebugControl::GetStackTrace  failed" );
-
-    return filledFrames;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void getStackTrace( STACK_FRAME_DESC* frames, ULONG frameCount, ULONG* frameReturned )
-{
-    PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
-
-    HRESULT     hres;
-
-    ULONG   filledFrames;
-    std::vector<DEBUG_STACK_FRAME>  stack(frameCount); 
-
-    hres = g_dbgEng->control->GetStackTrace( 0, 0, 0, &stack[0], frameCount, &filledFrames);
+    HRESULT hres;
+    ULONG   filledFrames = 1024;
+    std::vector<DEBUG_STACK_FRAME> dbgFrames(filledFrames);
+    hres = g_dbgEng->control->GetStackTrace( 0, 0, 0, &dbgFrames[0], filledFrames, &filledFrames);
     if ( FAILED( hres ) )
         throw DbgException( "IDebugControl::GetStackTrace  failed" );
 
+    frames.resize(filledFrames);
     for ( ULONG i = 0; i < filledFrames; ++i )
     {
-        frames[i].number = stack[i].FrameNumber;
-        frames[i].instructionOffset = stack[i].InstructionOffset;
-        frames[i].returnOffset = stack[i].ReturnOffset;
-        frames[i].frameOffset = stack[i].FrameOffset;
-        frames[i].stackOffset = stack[i].StackOffset;
+        frames[i].number = dbgFrames[i].FrameNumber;
+        frames[i].instructionOffset = dbgFrames[i].InstructionOffset;
+        frames[i].returnOffset = dbgFrames[i].ReturnOffset;
+        frames[i].frameOffset = dbgFrames[i].FrameOffset;
+        frames[i].stackOffset = dbgFrames[i].StackOffset;
     }
-
-    if ( frameReturned )
-        *frameReturned = filledFrames;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/test/scripts/localstest.py b/test/scripts/localstest.py
index 79cc7a6..d955af2 100644
--- a/test/scripts/localstest.py
+++ b/test/scripts/localstest.py
@@ -3,47 +3,42 @@
 import unittest
 import target
 import pykd
+import testutils
+
+
+def testEnumWindowsProc1Locals(testCase, locals):
+    testCase.assertNotEqual( 0, locals["hWindow"] )
+    DataIsParam = 3
+    testCase.assertEqual( DataIsParam, locals["hWindow"].dataKind() )
+
+    testCase.assertEqual( 6, locals["lParam"] )
+    testCase.assertEqual( DataIsParam, locals["lParam"].dataKind() )
+
+    DataIsLocal = 1
+    testCase.assertNotEqual( 0, locals["dwProccessId"] )
+    testCase.assertEqual( DataIsLocal, locals["dwProccessId"].dataKind() )
+
+    DataIsStaticLocal = 2
+    testCase.assertNotEqual( 0, locals["staticVar"] )
+    testCase.assertEqual( DataIsStaticLocal, locals["staticVar"].dataKind() )
+
+    testCase.assertEqual( locals["dwProccessId"] + 1, locals["staticVar"] )
 
 class LocalVarsTest(unittest.TestCase):
     def testLocalVariable(self):
         """Start new process and test local variables"""
+        _locProcessId = pykd.startProcess( target.appPath + " -testEnumWindows" )
+        with testutils.ContextCallIt( testutils.KillProcess(_locProcessId) ) as killStartedProcess :
+            pykd.go() # initial breakpoint -> wmain
+            pykd.go() # wmain -> targetapp!EnumWindowsProc1
 
-        newClnt = pykd.createDbgClient()
-        newClnt.startProcess( target.appPath + " -testEnumWindows" )
-
-        newClnt.go() # initial breakpoint -> wmain
-        newClnt.go() # wmain -> targetapp!EnumWindowsProc1
-        # pykd.dprint( "\n" + newClnt.dbgCommand("u") )
-
-        locals = newClnt.getLocals()
-
-        self.assertNotEqual( 0, locals["hWindow"] )
-        self.assertEqual( pykd.DataIsParam, locals["hWindow"].dataKind() )
-
-        self.assertEqual( 6, locals["lParam"] )
-        self.assertEqual( pykd.DataIsParam, locals["lParam"].dataKind() )
-
-        self.assertNotEqual( 0, locals["dwProccessId"] )
-        self.assertEqual( pykd.DataIsLocal, locals["dwProccessId"].dataKind() )
-
-        self.assertNotEqual( 0, locals["staticVar"] )
-        self.assertEqual( pykd.DataIsStaticLocal, locals["staticVar"].dataKind() )
-
-        self.assertEqual( locals["dwProccessId"] + 1, locals["staticVar"] )
-
-        newClnt.go() # targetapp!EnumWindowsProc1 -> targetapp!functionCalledFromEnumWindowsProc1
-
-        # get local variables from previous stack frame
-        prevLocals = newClnt.getCurrentStack()[1].getLocals()
-
-        self.assertEqual( len(prevLocals), len(locals) )
-        for varName in locals.iterkeys():
-            self.assertEqual( prevLocals[varName], locals[varName] )
-
-        newClnt.go() # targetapp!EnumWindowsProc1 -> targetapp!EnumWindowsProc2
-        locals = newClnt.getLocals()
-        self.assertEqual( len(locals), 2 )
-        locValues = locals.values()
-        self.assertTrue( locValues[0] == 7 or locValues[1] == 7 )
+            testEnumWindowsProc1Locals(self, pykd.getLocals())
 
+            pykd.go() # targetapp!EnumWindowsProc1 -> targetapp!functionCalledFromEnumWindowsProc1
+            testEnumWindowsProc1Locals(self, pykd.getCurrentStack()[1].getLocals())
 
+            pykd.go() # targetapp!EnumWindowsProc1 -> targetapp!EnumWindowsProc2
+            locals = pykd.getLocals()
+            self.assertEqual( len(locals), 2 )
+            locValues = locals.values()
+            self.assertTrue( locValues[0] == 7 or locValues[1] == 7 )
diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py
index a99960c..e77b060 100644
--- a/test/scripts/moduletest.py
+++ b/test/scripts/moduletest.py
@@ -61,6 +61,6 @@ class ModuleTest( unittest.TestCase ):
         self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
         self.assertEqual( 2, displacement )
         fileName, lineNo, displacement = pykd.getSourceLine()
-        self.assertEqual( 636, lineNo )
+        self.assertEqual( 616, lineNo )
 
 
diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py
index 3ef7b56..f32efe2 100644
--- a/test/scripts/pykdtest.py
+++ b/test/scripts/pykdtest.py
@@ -19,6 +19,7 @@ import moduletest
 import typeinfo 
 import typedvar
 import regtest
+import localstest
 
 class StartProcessWithoutParamsTest(unittest.TestCase):
     def testStart(self):
@@ -30,13 +31,13 @@ class StartProcessWithoutParamsTest(unittest.TestCase):
 class TerminateProcessTest(unittest.TestCase):
     def testKill(self):
         pykd.killProcess( target.processId )
+        pykd.detachProcess( target.processId )
 
 def getTestSuite( singleName = "" ):
     if singleName == "":
         return unittest.TestSuite(
            [
                 unittest.TestLoader().loadTestsFromTestCase( StartProcessWithoutParamsTest ),
-                unittest.TestLoader().loadTestsFromTestCase( target.TargetTest ),
                 # *** Test without start/kill new processes
                 unittest.TestLoader().loadTestsFromTestCase( intbase.IntBaseTest ),
                 unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
@@ -44,8 +45,10 @@ def getTestSuite( singleName = "" ):
                 unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
                 unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
                 unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ),
-                # *** 
+                # ^^^
                 unittest.TestLoader().loadTestsFromTestCase( TerminateProcessTest ),
+
+                unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ),
             ] ) 
     else:
        return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
@@ -53,7 +56,7 @@ def getTestSuite( singleName = "" ):
 if __name__ == "__main__":
 
     print "\nTesting PyKd ver. " + pykd.version
-    
+
     target.appPath = sys.argv[1]
     target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0]
     #print "Test module: %s" % target.appPath
diff --git a/test/scripts/target.py b/test/scripts/target.py
index 4befd70..a464cfe 100644
--- a/test/scripts/target.py
+++ b/test/scripts/target.py
@@ -10,13 +10,6 @@ module = None
 moduleName = None
 processId = None
 
-class TargetTest( unittest.TestCase ):
-
-    def testStartStop(self):
-        _locProcessId = pykd.startProcess( appPath )
-        pykd.killProcess( _locProcessId )
-
-
 
 #module = None
 #moduleName = None
diff --git a/test/scripts/testutils.py b/test/scripts/testutils.py
index e07d47e..842520b 100644
--- a/test/scripts/testutils.py
+++ b/test/scripts/testutils.py
@@ -14,3 +14,12 @@ class ContextCallIt:
         try: self.callIt()
         except: pass
 
+class KillProcess:
+    """Kill process"""
+    def __init__(self, processId):
+        self.processId = processId
+
+    def __call__(self):
+        pykd.killProcess( self.processId )
+        pykd.detachProcess( self.processId )
+