mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-05-13 14:03:22 +08:00
[0.2.x]
~ workitem/11723: find symbol by name ("public" pdb) - enum types by mask git-svn-id: https://pykd.svn.codeplex.com/svn@83473 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
0aec1a092c
commit
3d7f299028
@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <dia2.h>
|
#include <dia2.h>
|
||||||
|
#include <atltime.h>
|
||||||
|
|
||||||
#include "symengine.h"
|
#include "symengine.h"
|
||||||
|
|
||||||
#include "dia\diaexcept.h"
|
#include "dia\diaexcept.h"
|
||||||
|
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -30,12 +30,14 @@ interface IDataProvider
|
|||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Load debug symbols using DIA
|
// Load debug symbols using DIA
|
||||||
static SymbolSessionPtr createSession(
|
SymbolSessionPtr createSession(
|
||||||
IDataProvider &DataProvider,
|
IDataProvider &DataProvider,
|
||||||
ULONGLONG loadBase,
|
ULONGLONG loadBase,
|
||||||
const std::string &symbolFileName
|
const std::string &symbolFileName
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
const CTime startTime = CTime::GetCurrentTime();
|
||||||
|
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
DiaDataSourcePtr dataSource;
|
DiaDataSourcePtr dataSource;
|
||||||
|
|
||||||
@ -62,7 +64,13 @@ static SymbolSessionPtr createSession(
|
|||||||
if ( S_OK != hres )
|
if ( S_OK != hres )
|
||||||
throw DiaException("Call IDiaSymbol::get_globalScope", hres);
|
throw DiaException("Call IDiaSymbol::get_globalScope", hres);
|
||||||
|
|
||||||
return SymbolSessionPtr( new DiaSession( _session, _globalScope, symbolFileName ) );
|
return SymbolSessionPtr(
|
||||||
|
new DiaSession(
|
||||||
|
_session,
|
||||||
|
_globalScope,
|
||||||
|
symbolFileName,
|
||||||
|
(CTime::GetCurrentTime() - startTime).GetTotalSeconds() )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
84
pykd/dia/diapubsymcache.cpp
Normal file
84
pykd/dia/diapubsymcache.cpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include "dbghelp.h"
|
||||||
|
|
||||||
|
#include "dia\diadecls.h"
|
||||||
|
#include "dia\diapubsymcache.h"
|
||||||
|
|
||||||
|
#include "win\utils.h"
|
||||||
|
|
||||||
|
namespace pykd {
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DiaPublicSymbolCache::DiaPublicSymbolCache(DiaSymbolPtr globalScope)
|
||||||
|
{
|
||||||
|
const CTime startTime = CTime::GetCurrentTime();
|
||||||
|
|
||||||
|
DiaEnumSymbolsPtr publicSymbols;
|
||||||
|
HRESULT hres =
|
||||||
|
globalScope->findChildren(
|
||||||
|
::SymTagPublicSymbol,
|
||||||
|
NULL,
|
||||||
|
nsNone,
|
||||||
|
&publicSymbols);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw DiaException("Call IDiaSymbol::findChildren", hres);
|
||||||
|
|
||||||
|
std::set< std::string > ambiguousSymbols;
|
||||||
|
|
||||||
|
DiaSymbolPtr currentSym;
|
||||||
|
ULONG celt;
|
||||||
|
while ( SUCCEEDED(publicSymbols->Next(1, ¤tSym, &celt)) && (celt == 1) )
|
||||||
|
{
|
||||||
|
struct ClearSymbol : boost::noncopyable
|
||||||
|
{
|
||||||
|
DiaSymbolPtr &m_sym;
|
||||||
|
ClearSymbol(DiaSymbolPtr &sym) : m_sym(sym) {}
|
||||||
|
~ClearSymbol() { m_sym = NULL; }
|
||||||
|
} clearSymbol(currentSym);
|
||||||
|
|
||||||
|
BSTR bstrTemp;
|
||||||
|
hres = currentSym->get_name(&bstrTemp);
|
||||||
|
if (hres != S_OK)
|
||||||
|
continue;
|
||||||
|
std::string name = autoBstr(bstrTemp).asStr();
|
||||||
|
|
||||||
|
hres = currentSym->get_undecoratedNameEx(UNDNAME_NAME_ONLY, &bstrTemp);
|
||||||
|
if (hres != S_OK)
|
||||||
|
continue;
|
||||||
|
std::string undecoratedName = autoBstr(bstrTemp).asStr();
|
||||||
|
|
||||||
|
if (undecoratedName.empty() || undecoratedName == name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ambiguousSymbols.find(undecoratedName) != ambiguousSymbols.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (m_impl.find(undecoratedName) != m_impl.end())
|
||||||
|
{
|
||||||
|
ambiguousSymbols.insert(undecoratedName);
|
||||||
|
m_impl.erase(undecoratedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_impl[undecoratedName] = currentSym;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buildTimeInSeconds =
|
||||||
|
(CTime::GetCurrentTime() - startTime).GetTotalSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DiaSymbolPtr DiaPublicSymbolCache::lookup(const std::string &name) const
|
||||||
|
{
|
||||||
|
Impl::const_iterator it = m_impl.find(name);
|
||||||
|
return (it != m_impl.end()) ? it->second : DiaSymbolPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}; // pykd namespace end
|
||||||
|
|
31
pykd/dia/diapubsymcache.h
Normal file
31
pykd/dia/diapubsymcache.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace pykd {
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class DiaPublicSymbolCache : boost::noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DiaPublicSymbolCache(DiaSymbolPtr globalScope);
|
||||||
|
|
||||||
|
// Lookup entry by name
|
||||||
|
// Sta.
|
||||||
|
DiaSymbolPtr lookup(const std::string &name) const;
|
||||||
|
|
||||||
|
LONGLONG getBuildTimeInSeconds() const {
|
||||||
|
return m_buildTimeInSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map< std::string, DiaSymbolPtr > Impl;
|
||||||
|
Impl m_impl;
|
||||||
|
|
||||||
|
LONGLONG m_buildTimeInSeconds;
|
||||||
|
};
|
||||||
|
typedef boost::shared_ptr< DiaPublicSymbolCache > DiaPublicSymbolCachePtr;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
} // end pykd namespace
|
@ -9,6 +9,17 @@ namespace pykd {
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DiaSession::DiaSession( IDiaSession* session, IDiaSymbol *globalScope, const std::string symbolFile, LONGLONG loadSeconds )
|
||||||
|
: m_globalScope( globalScope )
|
||||||
|
, m_globalSymbol( DiaSymbol::fromGlobalScope( globalScope ) )
|
||||||
|
, m_session( session )
|
||||||
|
, m_symbolFileName( symbolFile )
|
||||||
|
, m_loadSeconds(loadSeconds)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SymbolPtr DiaSession::findByRva( ULONG rva, ULONG symTag, LONG* pdisplacement )
|
SymbolPtr DiaSession::findByRva( ULONG rva, ULONG symTag, LONG* pdisplacement )
|
||||||
{
|
{
|
||||||
DiaSymbolPtr child;
|
DiaSymbolPtr child;
|
||||||
@ -74,4 +85,17 @@ void DiaSession::getSourceLine( ULONG64 offset, std::string &fileName, ULONG &li
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string DiaSession::getBuildDescription() const
|
||||||
|
{
|
||||||
|
std::stringstream sstr;
|
||||||
|
sstr << "Load : ";
|
||||||
|
sstr << std::dec << m_loadSeconds;
|
||||||
|
sstr << " sec";
|
||||||
|
|
||||||
|
const std::string globalScopeDesc = m_globalSymbol->getBuildDescription();
|
||||||
|
return !globalScopeDesc.empty() ? sstr.str() + ", " + globalScopeDesc : sstr.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}; // pykd namespace end
|
}; // pykd namespace end
|
||||||
|
@ -12,12 +12,7 @@ class DiaSession : public SymbolSession
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DiaSession( IDiaSession* session, IDiaSymbol *globalScope, const std::string symbolFile ) :
|
DiaSession( IDiaSession* session, IDiaSymbol *globalScope, const std::string symbolFile, LONGLONG loadSeconds );
|
||||||
m_globalScope( globalScope ),
|
|
||||||
m_globalSymbol( DiaSymbol::fromGlobalScope( globalScope ) ),
|
|
||||||
m_session( session ),
|
|
||||||
m_symbolFileName( symbolFile )
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual SymbolPtr getSymbolScope() {
|
virtual SymbolPtr getSymbolScope() {
|
||||||
return m_globalSymbol;
|
return m_globalSymbol;
|
||||||
@ -31,6 +26,8 @@ public:
|
|||||||
return m_symbolFileName;
|
return m_symbolFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::string getBuildDescription() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ULONG findRvaByName( const std::string &name );
|
ULONG findRvaByName( const std::string &name );
|
||||||
@ -39,7 +36,7 @@ private:
|
|||||||
SymbolPtr m_globalSymbol;
|
SymbolPtr m_globalSymbol;
|
||||||
DiaSessionPtr m_session;
|
DiaSessionPtr m_session;
|
||||||
std::string m_symbolFileName;
|
std::string m_symbolFileName;
|
||||||
|
LONGLONG m_loadSeconds;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -47,49 +47,50 @@ SymbolPtr DiaSymbol::fromGlobalScope( IDiaSymbol *_symbol )
|
|||||||
if (!machineType)
|
if (!machineType)
|
||||||
machineType = IMAGE_FILE_MACHINE_I386;
|
machineType = IMAGE_FILE_MACHINE_I386;
|
||||||
|
|
||||||
return SymbolPtr( new DiaSymbol(DiaSymbolPtr(_symbol), machineType) );
|
std::auto_ptr< DiaSymbol > globalScope( new DiaSymbol(DiaSymbolPtr(_symbol), machineType) );
|
||||||
|
globalScope->m_publicSymbols.reset( new DiaPublicSymbolCache( _symbol ) );
|
||||||
|
return SymbolPtr( globalScope.release() );
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SymbolPtrList DiaSymbol::findChildren(
|
SymbolPtrList DiaSymbol::findChildren(ULONG symTag, const std::string &name)
|
||||||
ULONG symTag,
|
|
||||||
const std::string &name,
|
|
||||||
bool caseSensitive
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
DiaEnumSymbolsPtr symbols;
|
DiaEnumSymbolsPtr symbols;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
if ( name.empty() )
|
const bool bFindAllNames = ( name.empty() || name == "*" );
|
||||||
{
|
|
||||||
hres = m_symbol->findChildren(
|
|
||||||
static_cast<enum ::SymTagEnum>(symTag),
|
|
||||||
NULL,
|
|
||||||
(caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName | nsfRegularExpression,
|
|
||||||
&symbols);
|
|
||||||
|
|
||||||
|
if ( bFindAllNames )
|
||||||
|
{
|
||||||
|
hres =
|
||||||
|
m_symbol->findChildren(
|
||||||
|
static_cast<enum ::SymTagEnum>(symTag),
|
||||||
|
NULL,
|
||||||
|
nsNone,
|
||||||
|
&symbols);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hres = m_symbol->findChildren(
|
hres =
|
||||||
static_cast<enum ::SymTagEnum>(symTag),
|
m_symbol->findChildren(
|
||||||
|
static_cast<enum ::SymTagEnum>(symTag),
|
||||||
toWStr(name),
|
toWStr(name),
|
||||||
(caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName | nsfRegularExpression,
|
nsRegularExpression,
|
||||||
&symbols);
|
&symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_OK != hres)
|
if (S_OK != hres)
|
||||||
throw DiaException("Call IDiaSymbol::findChildren", hres);
|
throw DiaException("IDiaSymbol::findChildren", hres);
|
||||||
|
|
||||||
SymbolPtrList childList;
|
SymbolPtrList childList;
|
||||||
|
|
||||||
DiaSymbolPtr child;
|
DiaSymbolPtr child;
|
||||||
ULONG celt;
|
ULONG celt = 0;
|
||||||
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
|
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
|
||||||
{
|
{
|
||||||
childList.push_back( SymbolPtr( new DiaSymbol(child, m_machineType) ) );
|
childList.push_back( SymbolPtr( new DiaSymbol(child, m_machineType) ) );
|
||||||
child = NULL;
|
child.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
return childList;
|
return childList;
|
||||||
@ -167,7 +168,6 @@ SymbolPtr DiaSymbol::getChildByIndex(ULONG symTag, ULONG _index )
|
|||||||
|
|
||||||
SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
||||||
{
|
{
|
||||||
// èùåì ïðÿìîå ñîâïàäåíèå
|
|
||||||
DiaEnumSymbolsPtr symbols;
|
DiaEnumSymbolsPtr symbols;
|
||||||
HRESULT hres =
|
HRESULT hres =
|
||||||
m_symbol->findChildren(
|
m_symbol->findChildren(
|
||||||
@ -181,8 +181,11 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
|||||||
if (S_OK != hres)
|
if (S_OK != hres)
|
||||||
throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
|
throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
|
||||||
|
|
||||||
if (count >0 )
|
if (count > 0)
|
||||||
{
|
{
|
||||||
|
if (count > 1)
|
||||||
|
throw SymbolException(name + "is ambiguous");
|
||||||
|
|
||||||
DiaSymbolPtr child;
|
DiaSymbolPtr child;
|
||||||
hres = symbols->Item(0, &child);
|
hres = symbols->Item(0, &child);
|
||||||
if (S_OK != hres)
|
if (S_OK != hres)
|
||||||
@ -191,6 +194,14 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
|||||||
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_publicSymbols)
|
||||||
|
{
|
||||||
|
DiaSymbolPtr publicSymbol = m_publicSymbols->lookup(name);
|
||||||
|
if (publicSymbol)
|
||||||
|
return SymbolPtr( new DiaSymbol(publicSymbol, m_machineType) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* c++ c++ decoration is not supported
|
||||||
// _èìÿ
|
// _èìÿ
|
||||||
std::string underscoreName;
|
std::string underscoreName;
|
||||||
underscoreName += '_';
|
underscoreName += '_';
|
||||||
@ -217,7 +228,7 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
|||||||
|
|
||||||
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// _èìÿ@ïàðàì
|
// _èìÿ@ïàðàì
|
||||||
std::string pattern = "_";
|
std::string pattern = "_";
|
||||||
pattern += name;
|
pattern += name;
|
||||||
@ -250,7 +261,7 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
|||||||
|
|
||||||
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
throw DiaException(name + " is not found");
|
throw DiaException(name + " is not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,20 +330,30 @@ ULONG DiaSymbol::getLocType()
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static const boost::regex stdcallMatch("^_(\\w+)(@\\d+)?$");
|
|
||||||
static const boost::regex fastcallMatch("^@(\\w+)(@\\d+)?$");
|
|
||||||
|
|
||||||
std::string DiaSymbol::getName()
|
std::string DiaSymbol::getName()
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
BSTR bstrName = NULL;
|
BSTR bstrName = NULL;
|
||||||
|
|
||||||
|
hres = m_symbol->get_undecoratedNameEx( UNDNAME_NAME_ONLY, &bstrName);
|
||||||
|
if (S_OK == hres)
|
||||||
|
{
|
||||||
|
std::string name = autoBstr( bstrName ).asStr();
|
||||||
|
if (!name.empty())
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* c++ decoration is not supported
|
||||||
|
|
||||||
|
static const boost::regex stdcallMatch("^_(\\w+)(@\\d+)?$");
|
||||||
|
static const boost::regex fastcallMatch("^@(\\w+)(@\\d+)?$");
|
||||||
|
|
||||||
ULONG symTag;
|
ULONG symTag;
|
||||||
hres = m_symbol->get_symTag( &symTag );
|
hres = m_symbol->get_symTag( &symTag );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DiaException("Call IDiaSymbol::get_symTag", hres);
|
throw DiaException("Call IDiaSymbol::get_symTag", hres);
|
||||||
|
|
||||||
if( symTag == SymTagData || symTag == SymTagFunction || symTag == SymTagPublicSymbol )
|
if( symTag == SymTagData || symTag == SymTagFunction || symTag == SymTagPublicSymbol )
|
||||||
{
|
{
|
||||||
hres = m_symbol->get_undecoratedNameEx( UNDNAME_NAME_ONLY, &bstrName);
|
hres = m_symbol->get_undecoratedNameEx( UNDNAME_NAME_ONLY, &bstrName);
|
||||||
@ -354,7 +375,7 @@ std::string DiaSymbol::getName()
|
|||||||
return retStr;
|
return retStr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
bstrName = callSymbol(get_name);
|
bstrName = callSymbol(get_name);
|
||||||
|
|
||||||
return autoBstr( bstrName ).asStr();
|
return autoBstr( bstrName ).asStr();
|
||||||
@ -498,6 +519,20 @@ ULONG DiaSymbol::getVirtualBaseDispSize()
|
|||||||
return (ULONG)baseTableType->getType()->getSize();
|
return (ULONG)baseTableType->getType()->getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string DiaSymbol::getBuildDescription() const
|
||||||
|
{
|
||||||
|
std::stringstream sstr;
|
||||||
|
|
||||||
|
if (m_publicSymbols)
|
||||||
|
{
|
||||||
|
sstr << "Public symbols cache build time: ";
|
||||||
|
sstr << std::dec << m_publicSymbols->getBuildTimeInSeconds();
|
||||||
|
sstr << " sec";
|
||||||
|
}
|
||||||
|
|
||||||
|
return sstr.str();
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool DiaSymbol::isBasicType()
|
bool DiaSymbol::isBasicType()
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dia\diadecls.h"
|
#include "dia\diadecls.h"
|
||||||
|
#include "dia\diapubsymcache.h"
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
@ -23,8 +24,7 @@ public:
|
|||||||
|
|
||||||
SymbolPtrList findChildren(
|
SymbolPtrList findChildren(
|
||||||
ULONG symTag,
|
ULONG symTag,
|
||||||
const std::string &name = "",
|
const std::string &name = ""
|
||||||
bool caseSensitive = FALSE
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ULONGLONG getSize();
|
ULONGLONG getSize();
|
||||||
@ -63,15 +63,12 @@ public:
|
|||||||
|
|
||||||
ULONG getDataKind();
|
ULONG getDataKind();
|
||||||
|
|
||||||
//ULONG getRegisterId();
|
|
||||||
virtual ULONG getRegRealativeId() override;
|
virtual ULONG getRegRealativeId() override;
|
||||||
|
|
||||||
ULONG getMachineType() {
|
ULONG getMachineType() {
|
||||||
return m_machineType;
|
return m_machineType;
|
||||||
}
|
}
|
||||||
|
|
||||||
//SymbolPtr getChildByName(const std::string &_name);
|
|
||||||
|
|
||||||
ULONG getChildCount( ULONG symTag );
|
ULONG getChildCount( ULONG symTag );
|
||||||
|
|
||||||
ULONG getChildCount() {
|
ULONG getChildCount() {
|
||||||
@ -86,19 +83,13 @@ public:
|
|||||||
|
|
||||||
bool isConstant();
|
bool isConstant();
|
||||||
|
|
||||||
//std::string print();
|
|
||||||
|
|
||||||
//bool eq(Symbol &rhs);
|
|
||||||
|
|
||||||
int getVirtualBasePointerOffset();
|
int getVirtualBasePointerOffset();
|
||||||
|
|
||||||
ULONG getVirtualBaseDispIndex();
|
ULONG getVirtualBaseDispIndex();
|
||||||
|
|
||||||
ULONG getVirtualBaseDispSize();
|
ULONG getVirtualBaseDispSize();
|
||||||
|
|
||||||
//ULONG getSection();
|
virtual std::string getBuildDescription() const;
|
||||||
|
|
||||||
void setLoadAddress( ULONGLONG baseAddress );
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef std::pair<ULONG, const char *> ValueNameEntry;
|
typedef std::pair<ULONG, const char *> ValueNameEntry;
|
||||||
@ -128,8 +119,8 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
DiaSymbolPtr m_symbol;
|
DiaSymbolPtr m_symbol;
|
||||||
|
|
||||||
DWORD m_machineType;
|
DWORD m_machineType;
|
||||||
|
DiaPublicSymbolCachePtr m_publicSymbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace pykd {
|
|||||||
class ExportSymbolBase : public Symbol
|
class ExportSymbolBase : public Symbol
|
||||||
{
|
{
|
||||||
|
|
||||||
virtual SymbolPtrList findChildren( ULONG symTag, const std::string &name = "", bool caseSensitive = FALSE )
|
virtual SymbolPtrList findChildren( ULONG symTag, const std::string &name = "" )
|
||||||
{
|
{
|
||||||
throw ImplementException( __FILE__, __LINE__, "TODO" );
|
throw ImplementException( __FILE__, __LINE__, "TODO" );
|
||||||
}
|
}
|
||||||
@ -162,6 +162,10 @@ class ExportSymbolBase : public Symbol
|
|||||||
{
|
{
|
||||||
throw ImplementException( __FILE__, __LINE__, "TODO" );
|
throw ImplementException( __FILE__, __LINE__, "TODO" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::string getBuildDescription() const {
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -437,6 +441,10 @@ public:
|
|||||||
return std::string("export symbols");
|
return std::string("export symbols");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::string getBuildDescription() const {
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ULONGLONG m_moduleBase;
|
ULONGLONG m_moduleBase;
|
||||||
|
@ -186,9 +186,16 @@ std::string Module::print()
|
|||||||
sstr << (m_unloaded ? ", UNLOADED!" : "") << std::endl;
|
sstr << (m_unloaded ? ", UNLOADED!" : "") << std::endl;
|
||||||
sstr << "Image: " << m_imageName << std::endl;
|
sstr << "Image: " << m_imageName << std::endl;
|
||||||
if ( m_symSession )
|
if ( m_symSession )
|
||||||
|
{
|
||||||
sstr << "Symbols: " << m_symSession->getSymbolFileName() << std::endl;
|
sstr << "Symbols: " << m_symSession->getSymbolFileName() << std::endl;
|
||||||
|
std::string buildDesc = m_symSession->getBuildDescription();
|
||||||
|
if (!buildDesc.empty())
|
||||||
|
sstr << "\t" << buildDesc << std::endl;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
sstr << "Symbols: not found" << std::endl;
|
sstr << "Symbols: not found" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sstr << "Timestamp: " << m_timeDataStamp << std::endl;
|
sstr << "Timestamp: " << m_timeDataStamp << std::endl;
|
||||||
@ -197,6 +204,32 @@ std::string Module::print()
|
|||||||
return sstr.str();
|
return sstr.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::list Module::getUdts()
|
||||||
|
{
|
||||||
|
SymbolPtrList symlst = getSymScope()->findChildren( SymTagUDT );
|
||||||
|
|
||||||
|
python::list lst;
|
||||||
|
for ( SymbolPtrList::iterator it = symlst.begin(); it != symlst.end(); ++it )
|
||||||
|
lst.append( (*it)->getName() );
|
||||||
|
|
||||||
|
return lst;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::list Module::getEnums()
|
||||||
|
{
|
||||||
|
SymbolPtrList symlst = getSymScope()->findChildren( SymTagEnum );
|
||||||
|
|
||||||
|
python::list lst;
|
||||||
|
for ( SymbolPtrList::iterator it = symlst.begin(); it != symlst.end(); ++it )
|
||||||
|
lst.append( (*it)->getName() );
|
||||||
|
|
||||||
|
return lst;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TypedVarPtr
|
TypedVarPtr
|
||||||
@ -348,7 +381,7 @@ python::list Module::enumSymbols( const std::string &mask)
|
|||||||
{
|
{
|
||||||
python::list lst;
|
python::list lst;
|
||||||
|
|
||||||
SymbolPtrList symlst = getSymScope()->findChildren( SymTagData, mask, true );
|
SymbolPtrList symlst = getSymScope()->findChildren( SymTagData, mask );
|
||||||
|
|
||||||
for ( SymbolPtrList::iterator it = symlst.begin(); it != symlst.end(); ++it )
|
for ( SymbolPtrList::iterator it = symlst.begin(); it != symlst.end(); ++it )
|
||||||
{
|
{
|
||||||
@ -362,7 +395,7 @@ python::list Module::enumSymbols( const std::string &mask)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
symlst = getSymScope()->findChildren( SymTagFunction, mask, true );
|
symlst = getSymScope()->findChildren( SymTagFunction, mask );
|
||||||
|
|
||||||
for ( SymbolPtrList::iterator it = symlst.begin(); it != symlst.end(); ++it )
|
for ( SymbolPtrList::iterator it = symlst.begin(); it != symlst.end(); ++it )
|
||||||
{
|
{
|
||||||
@ -374,26 +407,6 @@ python::list Module::enumSymbols( const std::string &mask)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
python::list Module::enumTypes( const std::string &mask )
|
|
||||||
{
|
|
||||||
python::list lst;
|
|
||||||
int tags[] = { SymTagUDT, SymTagEnum };
|
|
||||||
|
|
||||||
for ( size_t i = 0; i < sizeof(tags)/sizeof(tags[0]); ++i )
|
|
||||||
{
|
|
||||||
SymbolPtrList symlst = getSymScope()->findChildren( tags[i], mask, true );
|
|
||||||
|
|
||||||
for ( SymbolPtrList::iterator it = symlst.begin(); it != symlst.end(); ++it )
|
|
||||||
{
|
|
||||||
lst.append( (*it)->getName() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lst;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::string Module::queryVersion( const std::string &value) {
|
std::string Module::queryVersion( const std::string &value) {
|
||||||
return getModuleVersionInfo( m_base, value );
|
return getModuleVersionInfo( m_base, value );
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,10 @@ public:
|
|||||||
return TypeInfo::getTypeInfo( boost::static_pointer_cast<Symbol>( getSymScope() ), typeName);
|
return TypeInfo::getTypeInfo( boost::static_pointer_cast<Symbol>( getSymScope() ), typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
python::list getUdts();
|
||||||
|
|
||||||
|
python::list getEnums();
|
||||||
|
|
||||||
TypedVarPtr getTypedVarByAddr( ULONG64 addr );
|
TypedVarPtr getTypedVarByAddr( ULONG64 addr );
|
||||||
|
|
||||||
TypedVarPtr getTypedVarByName( const std::string &symName );
|
TypedVarPtr getTypedVarByName( const std::string &symName );
|
||||||
@ -118,8 +122,6 @@ public:
|
|||||||
|
|
||||||
python::list enumSymbols( const std::string &mask = "*" );
|
python::list enumSymbols( const std::string &mask = "*" );
|
||||||
|
|
||||||
python::list enumTypes( const std::string &mask = std::string() );
|
|
||||||
|
|
||||||
std::string print();
|
std::string print();
|
||||||
|
|
||||||
std::string queryVersion( const std::string &value);
|
std::string queryVersion( const std::string &value);
|
||||||
|
@ -641,6 +641,14 @@
|
|||||||
RelativePath=".\dia\diaload.cpp"
|
RelativePath=".\dia\diaload.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\dia\diapubsymcache.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\dia\diapubsymcache.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\dia\diasession.cpp"
|
RelativePath=".\dia\diasession.cpp"
|
||||||
>
|
>
|
||||||
|
@ -68,7 +68,6 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( findSymbol_, TypeInfo::findSymbol, 1, 2 );
|
|||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( TypeBuilder_createStruct, TypeBuilder::createStruct, 1, 2 );
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( TypeBuilder_createStruct, TypeBuilder::createStruct, 1, 2 );
|
||||||
|
|
||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumSymbols, Module::enumSymbols, 0, 1 );
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumSymbols, Module::enumSymbols, 0, 1 );
|
||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumTypes, Module::enumTypes, 0, 1 );
|
|
||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_findSymbol, Module::getSymbolNameByVa, 1, 2 );
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_findSymbol, Module::getSymbolNameByVa, 1, 2 );
|
||||||
|
|
||||||
|
|
||||||
@ -386,6 +385,10 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Return a size of the type or variable" )
|
"Return a size of the type or variable" )
|
||||||
.def("type", &Module::getTypeByName,
|
.def("type", &Module::getTypeByName,
|
||||||
"Return typeInfo class by type name" )
|
"Return typeInfo class by type name" )
|
||||||
|
.def("getUdts", &Module::getUdts,
|
||||||
|
"Return a list of all user-defined type names" )
|
||||||
|
.def("getEnums", &Module::getEnums,
|
||||||
|
"Return a list of all enumeration names" )
|
||||||
.def("typedVar", &Module::getTypedVarByAddr,
|
.def("typedVar", &Module::getTypedVarByAddr,
|
||||||
"Return a typedVar class instance" )
|
"Return a typedVar class instance" )
|
||||||
.def("typedVar",&Module::getTypedVarByName,
|
.def("typedVar",&Module::getTypedVarByName,
|
||||||
@ -401,8 +404,6 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
|
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
|
||||||
.def("enumSymbols", &Module::enumSymbols, Module_enumSymbols( python::args("mask"),
|
.def("enumSymbols", &Module::enumSymbols, Module_enumSymbols( python::args("mask"),
|
||||||
"Return list of tuple ( symbolname, offset )" ) )
|
"Return list of tuple ( symbolname, offset )" ) )
|
||||||
.def("enumTypes", &Module::enumTypes, Module_enumTypes( python::args("mask"),
|
|
||||||
"Return list of type's names" ))
|
|
||||||
.def("checksum", &Module::getCheckSum,
|
.def("checksum", &Module::getCheckSum,
|
||||||
"Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" )
|
"Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" )
|
||||||
.def("timestamp", &Module::getTimeDataStamp,
|
.def("timestamp", &Module::getTimeDataStamp,
|
||||||
|
@ -123,8 +123,9 @@ enum RegRealativeId
|
|||||||
class Symbol {
|
class Symbol {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// > Applies a case-sensitive name match using asterisks (*) and
|
||||||
virtual SymbolPtrList findChildren( ULONG symTag, const std::string &name = "", bool caseSensitive = FALSE ) = 0;
|
// > question marks (?) as wildcards
|
||||||
|
virtual SymbolPtrList findChildren( ULONG symTag, const std::string &name = "") = 0;
|
||||||
virtual ULONG getBaseType() = 0;
|
virtual ULONG getBaseType() = 0;
|
||||||
virtual ULONG getBitPosition() = 0;
|
virtual ULONG getBitPosition() = 0;
|
||||||
virtual SymbolPtr getChildByIndex(ULONG _index ) = 0;
|
virtual SymbolPtr getChildByIndex(ULONG _index ) = 0;
|
||||||
@ -153,6 +154,8 @@ public:
|
|||||||
virtual bool isIndirectVirtualBaseClass() = 0;
|
virtual bool isIndirectVirtualBaseClass() = 0;
|
||||||
virtual bool isVirtualBaseClass() = 0;
|
virtual bool isVirtualBaseClass() = 0;
|
||||||
virtual ULONG getRegRealativeId() = 0; // <- RegRealativeId
|
virtual ULONG getRegRealativeId() = 0; // <- RegRealativeId
|
||||||
|
|
||||||
|
virtual std::string getBuildDescription() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -168,6 +171,8 @@ public:
|
|||||||
virtual void getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement ) = 0;
|
virtual void getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement ) = 0;
|
||||||
|
|
||||||
virtual std::string getSymbolFileName() = 0;
|
virtual std::string getSymbolFileName() = 0;
|
||||||
|
|
||||||
|
virtual std::string getBuildDescription() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -894,7 +894,7 @@ python::dict EnumTypeInfo::asMap()
|
|||||||
{
|
{
|
||||||
python::dict dct;
|
python::dict dct;
|
||||||
|
|
||||||
SymbolPtrList symbolsList = m_dia->findChildren(SymTagData, "", TRUE );
|
SymbolPtrList symbolsList = m_dia->findChildren(SymTagData);
|
||||||
|
|
||||||
for ( SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ )
|
for ( SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ )
|
||||||
{
|
{
|
||||||
@ -916,7 +916,7 @@ std::string EnumTypeInfo::print()
|
|||||||
|
|
||||||
sstr << "enum: " << getName() << std::endl;
|
sstr << "enum: " << getName() << std::endl;
|
||||||
|
|
||||||
SymbolPtrList symbolsList = m_dia->findChildren(SymTagData, "", true );
|
SymbolPtrList symbolsList = m_dia->findChildren(SymTagData);
|
||||||
|
|
||||||
for ( SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ )
|
for ( SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ )
|
||||||
{
|
{
|
||||||
|
@ -78,11 +78,11 @@ class ModuleTest( unittest.TestCase ):
|
|||||||
fileName = pykd.getSourceFile(target.module.FuncWithName0 )
|
fileName = pykd.getSourceFile(target.module.FuncWithName0 )
|
||||||
self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
|
self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
|
||||||
fileName, lineNo, displacement = pykd.getSourceLine( target.module.FuncWithName0 + 2)
|
fileName, lineNo, displacement = pykd.getSourceLine( target.module.FuncWithName0 + 2)
|
||||||
self.assertEqual( 404, lineNo )
|
self.assertEqual( 413, lineNo )
|
||||||
self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
|
self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
|
||||||
self.assertEqual( 2, displacement )
|
self.assertEqual( 2, displacement )
|
||||||
fileName, lineNo, displacement = pykd.getSourceLine()
|
fileName, lineNo, displacement = pykd.getSourceLine()
|
||||||
self.assertEqual( 677, lineNo )
|
self.assertEqual( 689, lineNo )
|
||||||
|
|
||||||
def testEnumSymbols( self ):
|
def testEnumSymbols( self ):
|
||||||
lst = target.module.enumSymbols()
|
lst = target.module.enumSymbols()
|
||||||
@ -98,20 +98,13 @@ class ModuleTest( unittest.TestCase ):
|
|||||||
lst = target.module.enumSymbols( "classChild" )
|
lst = target.module.enumSymbols( "classChild" )
|
||||||
self.assertEqual( 0, len(lst) )
|
self.assertEqual( 0, len(lst) )
|
||||||
|
|
||||||
def testEnumTypes( self ):
|
def testGetTypes( self ):
|
||||||
lst1 = target.module.enumTypes()
|
lst1 = target.module.getUdts()
|
||||||
self.assertNotEqual( 0, len(lst1) )
|
self.assertNotEqual( 0, len(lst1) )
|
||||||
|
|
||||||
self.assertTrue( "classChild" in lst1 )
|
self.assertTrue( "classChild" in lst1 )
|
||||||
self.assertTrue( "classBase" in lst1 )
|
self.assertTrue( "classBase" in lst1 )
|
||||||
self.assertTrue( "structTest" in lst1 )
|
self.assertTrue( "structTest" in lst1 )
|
||||||
|
|
||||||
lst2 = target.module.enumTypes("*class*")
|
lst2 = target.module.getEnums()
|
||||||
self.assertTrue( len(lst2) >= 2 )
|
self.assertNotEqual( 0, len(lst2) )
|
||||||
self.assertTrue( len(lst1) > len(lst2) )
|
self.assertTrue( "enumType" in lst2 )
|
||||||
|
|
||||||
self.assertTrue( "classChild" in lst2 )
|
|
||||||
self.assertTrue( "classBase" in lst2 )
|
|
||||||
|
|
||||||
lst3 = target.module.enumTypes("hello*Str")
|
|
||||||
self.assertEqual( 0, len(lst3) )
|
|
||||||
|
@ -25,4 +25,5 @@ class MsPdbTest(unittest.TestCase):
|
|||||||
def testFindMethodOffset(self):
|
def testFindMethodOffset(self):
|
||||||
"""Lookup method offset by name"""
|
"""Lookup method offset by name"""
|
||||||
with PeFileAsDumpLoader( os.environ["WINDIR"] + r"\System32\ole32.dll" ) as loadedDump:
|
with PeFileAsDumpLoader( os.environ["WINDIR"] + r"\System32\ole32.dll" ) as loadedDump:
|
||||||
|
print "\n" + str( pykd.module("ole32") )
|
||||||
self.assertNotEqual( 0, pykd.getOffset("ole32!CPackagerMoniker::AddRef") )
|
self.assertNotEqual( 0, pykd.getOffset("ole32!CPackagerMoniker::AddRef") )
|
||||||
|
@ -11,16 +11,16 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
def testCtor( self ):
|
def testCtor( self ):
|
||||||
tv = target.module.typedVar( "structTest", target.module.g_structTest )
|
tv = target.module.typedVar( "structTest", target.module.g_structTest )
|
||||||
tv = target.module.typedVar( "g_structTest" )
|
tv = target.module.typedVar( "g_structTest" )
|
||||||
|
|
||||||
tv = pykd.typedVar( "structTest", target.module.g_structTest )
|
tv = pykd.typedVar( "structTest", target.module.g_structTest )
|
||||||
tv = pykd.typedVar( target.moduleName + "!structTest", target.module.g_structTest )
|
tv = pykd.typedVar( target.moduleName + "!structTest", target.module.g_structTest )
|
||||||
|
|
||||||
structTest = target.module.type( "structTest" )
|
structTest = target.module.type( "structTest" )
|
||||||
tv = pykd.typedVar( structTest, target.module.g_structTest )
|
tv = pykd.typedVar( structTest, target.module.g_structTest )
|
||||||
|
|
||||||
tv = pykd.typedVar( "g_structTest" )
|
tv = pykd.typedVar( "g_structTest" )
|
||||||
tv = pykd.typedVar( target.moduleName + "!g_structTest" )
|
tv = pykd.typedVar( target.moduleName + "!g_structTest" )
|
||||||
|
|
||||||
def testBaseTypes(self):
|
def testBaseTypes(self):
|
||||||
self.assertEqual( 1, target.module.typedVar( "g_ucharValue" ) )
|
self.assertEqual( 1, target.module.typedVar( "g_ucharValue" ) )
|
||||||
self.assertEqual( 2, target.module.typedVar( "g_ushortValue" ) )
|
self.assertEqual( 2, target.module.typedVar( "g_ushortValue" ) )
|
||||||
@ -46,7 +46,7 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
customStructTest.append("m_field1", pykd.typeInfo("UInt8B"))
|
customStructTest.append("m_field1", pykd.typeInfo("UInt8B"))
|
||||||
tvCustomStruct = pykd.typedVar( customStructTest.ptrTo(), target.module.offset("g_structTestPtr") )
|
tvCustomStruct = pykd.typedVar( customStructTest.ptrTo(), target.module.offset("g_structTestPtr") )
|
||||||
self.assertEqual( 500, tvCustomStruct.deref().m_field1 )
|
self.assertEqual( 500, tvCustomStruct.deref().m_field1 )
|
||||||
|
|
||||||
def testArrayOf(self):
|
def testArrayOf(self):
|
||||||
arrayType = pykd.typeInfo("UInt8B").arrayOf(5)
|
arrayType = pykd.typeInfo("UInt8B").arrayOf(5)
|
||||||
arrayVar = pykd.typedVar( arrayType, target.module.offset("ulonglongArray") )
|
arrayVar = pykd.typedVar( arrayType, target.module.offset("ulonglongArray") )
|
||||||
@ -74,7 +74,7 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
self.assertEqual( 16 + pykd.ptrSize(), tv1.sizeof() )
|
self.assertEqual( 16 + pykd.ptrSize(), tv1.sizeof() )
|
||||||
tv2 = target.module.typedVar( "structTest[2]", target.module.g_testArray )
|
tv2 = target.module.typedVar( "structTest[2]", target.module.g_testArray )
|
||||||
self.assertEqual( tv1.sizeof()*2, tv2.sizeof() )
|
self.assertEqual( tv1.sizeof()*2, tv2.sizeof() )
|
||||||
|
|
||||||
self.assertEqual( pykd.sizeof("g_structTest"), tv1.sizeof() )
|
self.assertEqual( pykd.sizeof("g_structTest"), tv1.sizeof() )
|
||||||
self.assertEqual( pykd.sizeof("g_testArray"), tv2.sizeof() )
|
self.assertEqual( pykd.sizeof("g_testArray"), tv2.sizeof() )
|
||||||
self.assertEqual( pykd.sizeof("g_ucharValue"), 1 )
|
self.assertEqual( pykd.sizeof("g_ucharValue"), 1 )
|
||||||
@ -116,12 +116,12 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
self.assertTrue(False)
|
self.assertTrue(False)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
|
|
||||||
def testArrayFieldSlice(self):
|
def testArrayFieldSlice(self):
|
||||||
tv = target.module.typedVar( "g_struct3" )
|
tv = target.module.typedVar( "g_struct3" )
|
||||||
self.assertEqual( 2, tv.m_arrayField[-1] )
|
self.assertEqual( 2, tv.m_arrayField[-1] )
|
||||||
self.assertEqual( [ 0, 2 ], tv.m_arrayField[0:2] )
|
self.assertEqual( [ 0, 2 ], tv.m_arrayField[0:2] )
|
||||||
|
|
||||||
def testGlobalVar(self):
|
def testGlobalVar(self):
|
||||||
self.assertEqual( 4, target.module.typedVar( "g_ulongValue" ) )
|
self.assertEqual( 4, target.module.typedVar( "g_ulongValue" ) )
|
||||||
self.assertEqual( 0x80000000, target.module.typedVar( "ulongArray" )[3] )
|
self.assertEqual( 0x80000000, target.module.typedVar( "ulongArray" )[3] )
|
||||||
@ -135,7 +135,7 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
off2 = target.module.offset( "g_structTest" )
|
off2 = target.module.offset( "g_structTest" )
|
||||||
tv = target.module.containingRecord( off2 + off1, "structTest", "m_field2" )
|
tv = target.module.containingRecord( off2 + off1, "structTest", "m_field2" )
|
||||||
self.assertEqual( True, tv.m_field2 )
|
self.assertEqual( True, tv.m_field2 )
|
||||||
|
|
||||||
def testBitField(self):
|
def testBitField(self):
|
||||||
tv = target.module.typedVar("g_structWithBits")
|
tv = target.module.typedVar("g_structWithBits")
|
||||||
self.assertEqual( 4, tv.m_bit0_4 )
|
self.assertEqual( 4, tv.m_bit0_4 )
|
||||||
@ -150,7 +150,7 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" )
|
tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" )
|
||||||
self.assertEqual( 3, len( tvl ) )
|
self.assertEqual( 3, len( tvl ) )
|
||||||
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
||||||
|
|
||||||
tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry.Flink" )
|
tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry.Flink" )
|
||||||
self.assertEqual( 3, len( tvl ) )
|
self.assertEqual( 3, len( tvl ) )
|
||||||
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
||||||
@ -186,17 +186,17 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
tvl1 = target.module.typedVarArray( target.module.g_testArray, "structTest", 2 )
|
tvl1 = target.module.typedVarArray( target.module.g_testArray, "structTest", 2 )
|
||||||
tvl2 = pykd.typedVarArray( target.module.g_testArray, target.moduleName + "!structTest", 2 )
|
tvl2 = pykd.typedVarArray( target.module.g_testArray, target.moduleName + "!structTest", 2 )
|
||||||
self.assertEqual( tvl1, tvl2 )
|
self.assertEqual( tvl1, tvl2 )
|
||||||
|
|
||||||
def testEqual(self):
|
def testEqual(self):
|
||||||
tv1 = target.module.typedVar("g_structTest")
|
tv1 = target.module.typedVar("g_structTest")
|
||||||
tv2 = target.module.typedVar("intMatrix")
|
tv2 = target.module.typedVar("intMatrix")
|
||||||
self.assertEqual( tv1.m_field3, tv2[0][1] )
|
self.assertEqual( tv1.m_field3, tv2[0][1] )
|
||||||
|
|
||||||
def testEnum(self):
|
def testEnum(self):
|
||||||
tv = target.module.typedVar("g_classChild")
|
tv = target.module.typedVar("g_classChild")
|
||||||
self.assertEqual( 3, tv.m_enumField )
|
self.assertEqual( 3, tv.m_enumField )
|
||||||
self.assertEqual( target.module.type("enumType").THREE, tv.m_enumField )
|
self.assertEqual( target.module.type("enumType").THREE, tv.m_enumField )
|
||||||
|
|
||||||
def testIndex(self):
|
def testIndex(self):
|
||||||
ind = target.module.typedVar( "g_ucharValue" )
|
ind = target.module.typedVar( "g_ucharValue" )
|
||||||
self.assertEqual( 5, [0,5,10][ind] )
|
self.assertEqual( 5, [0,5,10][ind] )
|
||||||
@ -245,8 +245,7 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
|
|
||||||
self.assertRaises( pykd.TypeException, tv1.deref )
|
self.assertRaises( pykd.TypeException, tv1.deref )
|
||||||
self.assertRaises( pykd.TypeException, tv2.deref )
|
self.assertRaises( pykd.TypeException, tv2.deref )
|
||||||
|
|
||||||
|
|
||||||
def testTypeVarArg(self):
|
def testTypeVarArg(self):
|
||||||
tv1 = target.module.typedVar( "structTest", target.module.g_structTest )
|
tv1 = target.module.typedVar( "structTest", target.module.g_structTest )
|
||||||
tv2 = target.module.typedVar( "structTest", tv1 )
|
tv2 = target.module.typedVar( "structTest", tv1 )
|
||||||
@ -278,7 +277,7 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
types = ("structTest", "ULong[100]", "ULong*" )
|
types = ("structTest", "ULong[100]", "ULong*" )
|
||||||
for ti in types:
|
for ti in types:
|
||||||
self.assertTrue( str(pykd.typedVar( target.module.type(ti), 0 ) ) )
|
self.assertTrue( str(pykd.typedVar( target.module.type(ti), 0 ) ) )
|
||||||
|
|
||||||
def testStaticField(self):
|
def testStaticField(self):
|
||||||
tv = pykd.typedVar( "g_classChild" )
|
tv = pykd.typedVar( "g_classChild" )
|
||||||
self.assertEqual( 200, tv.m_staticField )
|
self.assertEqual( 200, tv.m_staticField )
|
||||||
@ -287,17 +286,15 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
def testAmbiguousFieldAccess(self):
|
def testAmbiguousFieldAccess(self):
|
||||||
derivedFiledVal = pykd.loadCStr( pykd.typedVar( "g_fieldSameNameStruct" ).m_field )
|
derivedFiledVal = pykd.loadCStr( pykd.typedVar( "g_fieldSameNameStruct" ).m_field )
|
||||||
self.assertEqual( derivedFiledVal, "toaster" )
|
self.assertEqual( derivedFiledVal, "toaster" )
|
||||||
print target.module.type("fieldSameNameStruct")
|
|
||||||
|
|
||||||
def testDiamondVirtualInherit(self):
|
def testDiamondVirtualInherit(self):
|
||||||
tv = pykd.typedVar( "g_virtChild" )
|
tv = pykd.typedVar( "g_virtChild" )
|
||||||
self.assertEqual( -100, tv.m_baseField )
|
self.assertEqual( -100, tv.m_baseField )
|
||||||
|
|
||||||
def testDinkumwareMap(self):
|
def testDinkumwareMap(self):
|
||||||
g_map = target.module.typedVar( "g_map" )
|
g_map = target.module.typedVar( "g_map" )
|
||||||
self.assertEqual( 1, g_map._Mysize )
|
self.assertEqual( 1, g_map._Mysize )
|
||||||
|
|
||||||
|
|
||||||
def testUdtSubscribe(self):
|
def testUdtSubscribe(self):
|
||||||
tv = pykd.typedVar( "g_virtChild" )
|
tv = pykd.typedVar( "g_virtChild" )
|
||||||
self.assertEqual( 5, len(tv) )
|
self.assertEqual( 5, len(tv) )
|
||||||
@ -306,9 +303,8 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
self.assertEqual( fieldVal, tv.m_baseField )
|
self.assertEqual( fieldVal, tv.m_baseField )
|
||||||
for field in tv:
|
for field in tv:
|
||||||
str( field )
|
str( field )
|
||||||
|
|
||||||
def testDeadlockList(self):
|
def testDeadlockList(self):
|
||||||
|
|
||||||
lst = []
|
lst = []
|
||||||
entry = pykd.typedVar("entry1").Flink
|
entry = pykd.typedVar("entry1").Flink
|
||||||
for i in range( 0, 100000 ):
|
for i in range( 0, 100000 ):
|
||||||
|
@ -171,6 +171,15 @@ public:
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct YetAnotherChild_class : classBase
|
||||||
|
{
|
||||||
|
int m_i;
|
||||||
|
YetAnotherChild_class() : m_i(0) {}
|
||||||
|
virtual void virtFunc() {}
|
||||||
|
virtual void virtFunc2() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int classChild::m_staticField = 200;
|
int classChild::m_staticField = 200;
|
||||||
|
|
||||||
classChild g_classChild;
|
classChild g_classChild;
|
||||||
@ -405,6 +414,9 @@ void FuncWithName0()
|
|||||||
classChild _classChild;
|
classChild _classChild;
|
||||||
_classChild.baseMethod();
|
_classChild.baseMethod();
|
||||||
|
|
||||||
|
static volatile YetAnotherChild_class yetAnotherChild;
|
||||||
|
std::cout << yetAnotherChild.m_i;
|
||||||
|
|
||||||
reinterpret_cast<classChild *>(&_classChild)->virtFunc2();
|
reinterpret_cast<classChild *>(&_classChild)->virtFunc2();
|
||||||
std::cout << _classChild.m_childField2;
|
std::cout << _classChild.m_childField2;
|
||||||
std::cout << g_constNumValue;
|
std::cout << g_constNumValue;
|
||||||
|
Loading…
Reference in New Issue
Block a user