mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-19 19:13: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
|
||||
|
||||
#include <dia2.h>
|
||||
#include <atltime.h>
|
||||
|
||||
#include "symengine.h"
|
||||
|
||||
#include "dia\diaexcept.h"
|
||||
|
||||
|
||||
namespace pykd {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -30,12 +30,14 @@ interface IDataProvider
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Load debug symbols using DIA
|
||||
static SymbolSessionPtr createSession(
|
||||
SymbolSessionPtr createSession(
|
||||
IDataProvider &DataProvider,
|
||||
ULONGLONG loadBase,
|
||||
const std::string &symbolFileName
|
||||
)
|
||||
{
|
||||
const CTime startTime = CTime::GetCurrentTime();
|
||||
|
||||
HRESULT hres;
|
||||
DiaDataSourcePtr dataSource;
|
||||
|
||||
@ -62,7 +64,13 @@ static SymbolSessionPtr createSession(
|
||||
if ( S_OK != 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 )
|
||||
{
|
||||
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
|
||||
|
@ -12,12 +12,7 @@ class DiaSession : public SymbolSession
|
||||
{
|
||||
public:
|
||||
|
||||
DiaSession( IDiaSession* session, IDiaSymbol *globalScope, const std::string symbolFile ) :
|
||||
m_globalScope( globalScope ),
|
||||
m_globalSymbol( DiaSymbol::fromGlobalScope( globalScope ) ),
|
||||
m_session( session ),
|
||||
m_symbolFileName( symbolFile )
|
||||
{}
|
||||
DiaSession( IDiaSession* session, IDiaSymbol *globalScope, const std::string symbolFile, LONGLONG loadSeconds );
|
||||
|
||||
virtual SymbolPtr getSymbolScope() {
|
||||
return m_globalSymbol;
|
||||
@ -31,6 +26,8 @@ public:
|
||||
return m_symbolFileName;
|
||||
}
|
||||
|
||||
virtual std::string getBuildDescription() const;
|
||||
|
||||
private:
|
||||
|
||||
ULONG findRvaByName( const std::string &name );
|
||||
@ -39,7 +36,7 @@ private:
|
||||
SymbolPtr m_globalSymbol;
|
||||
DiaSessionPtr m_session;
|
||||
std::string m_symbolFileName;
|
||||
|
||||
LONGLONG m_loadSeconds;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -47,49 +47,50 @@ SymbolPtr DiaSymbol::fromGlobalScope( IDiaSymbol *_symbol )
|
||||
if (!machineType)
|
||||
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(
|
||||
ULONG symTag,
|
||||
const std::string &name,
|
||||
bool caseSensitive
|
||||
)
|
||||
SymbolPtrList DiaSymbol::findChildren(ULONG symTag, const std::string &name)
|
||||
{
|
||||
DiaEnumSymbolsPtr symbols;
|
||||
HRESULT hres;
|
||||
|
||||
if ( name.empty() )
|
||||
{
|
||||
hres = m_symbol->findChildren(
|
||||
static_cast<enum ::SymTagEnum>(symTag),
|
||||
NULL,
|
||||
(caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName | nsfRegularExpression,
|
||||
&symbols);
|
||||
const bool bFindAllNames = ( name.empty() || name == "*" );
|
||||
|
||||
if ( bFindAllNames )
|
||||
{
|
||||
hres =
|
||||
m_symbol->findChildren(
|
||||
static_cast<enum ::SymTagEnum>(symTag),
|
||||
NULL,
|
||||
nsNone,
|
||||
&symbols);
|
||||
}
|
||||
else
|
||||
{
|
||||
hres = m_symbol->findChildren(
|
||||
static_cast<enum ::SymTagEnum>(symTag),
|
||||
hres =
|
||||
m_symbol->findChildren(
|
||||
static_cast<enum ::SymTagEnum>(symTag),
|
||||
toWStr(name),
|
||||
(caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName | nsfRegularExpression,
|
||||
nsRegularExpression,
|
||||
&symbols);
|
||||
}
|
||||
|
||||
if (S_OK != hres)
|
||||
throw DiaException("Call IDiaSymbol::findChildren", hres);
|
||||
throw DiaException("IDiaSymbol::findChildren", hres);
|
||||
|
||||
SymbolPtrList childList;
|
||||
|
||||
DiaSymbolPtr child;
|
||||
ULONG celt;
|
||||
ULONG celt = 0;
|
||||
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
|
||||
{
|
||||
childList.push_back( SymbolPtr( new DiaSymbol(child, m_machineType) ) );
|
||||
child = NULL;
|
||||
child.Release();
|
||||
}
|
||||
|
||||
return childList;
|
||||
@ -167,7 +168,6 @@ SymbolPtr DiaSymbol::getChildByIndex(ULONG symTag, ULONG _index )
|
||||
|
||||
SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
||||
{
|
||||
// èùåì ïðÿìîå ñîâïàäåíèå
|
||||
DiaEnumSymbolsPtr symbols;
|
||||
HRESULT hres =
|
||||
m_symbol->findChildren(
|
||||
@ -181,8 +181,11 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
||||
if (S_OK != hres)
|
||||
throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
|
||||
|
||||
if (count >0 )
|
||||
if (count > 0)
|
||||
{
|
||||
if (count > 1)
|
||||
throw SymbolException(name + "is ambiguous");
|
||||
|
||||
DiaSymbolPtr child;
|
||||
hres = symbols->Item(0, &child);
|
||||
if (S_OK != hres)
|
||||
@ -191,6 +194,14 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
||||
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;
|
||||
underscoreName += '_';
|
||||
@ -217,7 +228,7 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
||||
|
||||
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
||||
}
|
||||
|
||||
|
||||
// _èìÿ@ïàðàì
|
||||
std::string pattern = "_";
|
||||
pattern += name;
|
||||
@ -250,7 +261,7 @@ SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
||||
|
||||
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
||||
}
|
||||
|
||||
*/
|
||||
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()
|
||||
{
|
||||
HRESULT hres;
|
||||
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;
|
||||
hres = m_symbol->get_symTag( &symTag );
|
||||
|
||||
if ( FAILED( hres ) )
|
||||
throw DiaException("Call IDiaSymbol::get_symTag", hres);
|
||||
|
||||
|
||||
if( symTag == SymTagData || symTag == SymTagFunction || symTag == SymTagPublicSymbol )
|
||||
{
|
||||
hres = m_symbol->get_undecoratedNameEx( UNDNAME_NAME_ONLY, &bstrName);
|
||||
@ -354,7 +375,7 @@ std::string DiaSymbol::getName()
|
||||
return retStr;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
bstrName = callSymbol(get_name);
|
||||
|
||||
return autoBstr( bstrName ).asStr();
|
||||
@ -498,6 +519,20 @@ ULONG DiaSymbol::getVirtualBaseDispSize()
|
||||
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()
|
||||
|
@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "dia\diadecls.h"
|
||||
#include "dia\diapubsymcache.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
@ -23,8 +24,7 @@ public:
|
||||
|
||||
SymbolPtrList findChildren(
|
||||
ULONG symTag,
|
||||
const std::string &name = "",
|
||||
bool caseSensitive = FALSE
|
||||
const std::string &name = ""
|
||||
);
|
||||
|
||||
ULONGLONG getSize();
|
||||
@ -63,15 +63,12 @@ public:
|
||||
|
||||
ULONG getDataKind();
|
||||
|
||||
//ULONG getRegisterId();
|
||||
virtual ULONG getRegRealativeId() override;
|
||||
|
||||
ULONG getMachineType() {
|
||||
return m_machineType;
|
||||
}
|
||||
|
||||
//SymbolPtr getChildByName(const std::string &_name);
|
||||
|
||||
ULONG getChildCount( ULONG symTag );
|
||||
|
||||
ULONG getChildCount() {
|
||||
@ -86,19 +83,13 @@ public:
|
||||
|
||||
bool isConstant();
|
||||
|
||||
//std::string print();
|
||||
|
||||
//bool eq(Symbol &rhs);
|
||||
|
||||
int getVirtualBasePointerOffset();
|
||||
|
||||
ULONG getVirtualBaseDispIndex();
|
||||
|
||||
ULONG getVirtualBaseDispSize();
|
||||
|
||||
//ULONG getSection();
|
||||
|
||||
void setLoadAddress( ULONGLONG baseAddress );
|
||||
virtual std::string getBuildDescription() const;
|
||||
|
||||
public:
|
||||
typedef std::pair<ULONG, const char *> ValueNameEntry;
|
||||
@ -128,8 +119,8 @@ protected:
|
||||
}
|
||||
|
||||
DiaSymbolPtr m_symbol;
|
||||
|
||||
DWORD m_machineType;
|
||||
DiaPublicSymbolCachePtr m_publicSymbols;
|
||||
};
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace pykd {
|
||||
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" );
|
||||
}
|
||||
@ -162,6 +162,10 @@ class ExportSymbolBase : public Symbol
|
||||
{
|
||||
throw ImplementException( __FILE__, __LINE__, "TODO" );
|
||||
}
|
||||
|
||||
virtual std::string getBuildDescription() const {
|
||||
return std::string();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -437,6 +441,10 @@ public:
|
||||
return std::string("export symbols");
|
||||
}
|
||||
|
||||
virtual std::string getBuildDescription() const {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ULONGLONG m_moduleBase;
|
||||
|
@ -186,9 +186,16 @@ std::string Module::print()
|
||||
sstr << (m_unloaded ? ", UNLOADED!" : "") << std::endl;
|
||||
sstr << "Image: " << m_imageName << std::endl;
|
||||
if ( m_symSession )
|
||||
{
|
||||
sstr << "Symbols: " << m_symSession->getSymbolFileName() << std::endl;
|
||||
std::string buildDesc = m_symSession->getBuildDescription();
|
||||
if (!buildDesc.empty())
|
||||
sstr << "\t" << buildDesc << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
sstr << "Symbols: not found" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
sstr << "Timestamp: " << m_timeDataStamp << std::endl;
|
||||
@ -197,6 +204,32 @@ std::string Module::print()
|
||||
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
|
||||
@ -348,7 +381,7 @@ python::list Module::enumSymbols( const std::string &mask)
|
||||
{
|
||||
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 )
|
||||
{
|
||||
@ -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 )
|
||||
{
|
||||
@ -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) {
|
||||
return getModuleVersionInfo( m_base, value );
|
||||
}
|
||||
|
@ -92,6 +92,10 @@ public:
|
||||
return TypeInfo::getTypeInfo( boost::static_pointer_cast<Symbol>( getSymScope() ), typeName);
|
||||
}
|
||||
|
||||
python::list getUdts();
|
||||
|
||||
python::list getEnums();
|
||||
|
||||
TypedVarPtr getTypedVarByAddr( ULONG64 addr );
|
||||
|
||||
TypedVarPtr getTypedVarByName( const std::string &symName );
|
||||
@ -118,8 +122,6 @@ public:
|
||||
|
||||
python::list enumSymbols( const std::string &mask = "*" );
|
||||
|
||||
python::list enumTypes( const std::string &mask = std::string() );
|
||||
|
||||
std::string print();
|
||||
|
||||
std::string queryVersion( const std::string &value);
|
||||
|
@ -641,6 +641,14 @@
|
||||
RelativePath=".\dia\diaload.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dia\diapubsymcache.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dia\diapubsymcache.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
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( 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 );
|
||||
|
||||
|
||||
@ -386,6 +385,10 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Return a size of the type or variable" )
|
||||
.def("type", &Module::getTypeByName,
|
||||
"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,
|
||||
"Return a typedVar class instance" )
|
||||
.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" )
|
||||
.def("enumSymbols", &Module::enumSymbols, Module_enumSymbols( python::args("mask"),
|
||||
"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,
|
||||
"Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" )
|
||||
.def("timestamp", &Module::getTimeDataStamp,
|
||||
|
@ -123,8 +123,9 @@ enum RegRealativeId
|
||||
class Symbol {
|
||||
|
||||
public:
|
||||
|
||||
virtual SymbolPtrList findChildren( ULONG symTag, const std::string &name = "", bool caseSensitive = FALSE ) = 0;
|
||||
// > Applies a case-sensitive name match using asterisks (*) and
|
||||
// > question marks (?) as wildcards
|
||||
virtual SymbolPtrList findChildren( ULONG symTag, const std::string &name = "") = 0;
|
||||
virtual ULONG getBaseType() = 0;
|
||||
virtual ULONG getBitPosition() = 0;
|
||||
virtual SymbolPtr getChildByIndex(ULONG _index ) = 0;
|
||||
@ -153,6 +154,8 @@ public:
|
||||
virtual bool isIndirectVirtualBaseClass() = 0;
|
||||
virtual bool isVirtualBaseClass() = 0;
|
||||
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 std::string getSymbolFileName() = 0;
|
||||
|
||||
virtual std::string getBuildDescription() const = 0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -894,7 +894,7 @@ python::dict EnumTypeInfo::asMap()
|
||||
{
|
||||
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++ )
|
||||
{
|
||||
@ -916,7 +916,7 @@ std::string EnumTypeInfo::print()
|
||||
|
||||
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++ )
|
||||
{
|
||||
|
@ -78,11 +78,11 @@ class ModuleTest( unittest.TestCase ):
|
||||
fileName = pykd.getSourceFile(target.module.FuncWithName0 )
|
||||
self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
|
||||
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.assertEqual( 2, displacement )
|
||||
fileName, lineNo, displacement = pykd.getSourceLine()
|
||||
self.assertEqual( 677, lineNo )
|
||||
self.assertEqual( 689, lineNo )
|
||||
|
||||
def testEnumSymbols( self ):
|
||||
lst = target.module.enumSymbols()
|
||||
@ -98,20 +98,13 @@ class ModuleTest( unittest.TestCase ):
|
||||
lst = target.module.enumSymbols( "classChild" )
|
||||
self.assertEqual( 0, len(lst) )
|
||||
|
||||
def testEnumTypes( self ):
|
||||
lst1 = target.module.enumTypes()
|
||||
def testGetTypes( self ):
|
||||
lst1 = target.module.getUdts()
|
||||
self.assertNotEqual( 0, len(lst1) )
|
||||
|
||||
self.assertTrue( "classChild" in lst1 )
|
||||
self.assertTrue( "classBase" in lst1 )
|
||||
self.assertTrue( "structTest" in lst1 )
|
||||
|
||||
lst2 = target.module.enumTypes("*class*")
|
||||
self.assertTrue( len(lst2) >= 2 )
|
||||
self.assertTrue( len(lst1) > len(lst2) )
|
||||
|
||||
self.assertTrue( "classChild" in lst2 )
|
||||
self.assertTrue( "classBase" in lst2 )
|
||||
|
||||
lst3 = target.module.enumTypes("hello*Str")
|
||||
self.assertEqual( 0, len(lst3) )
|
||||
lst2 = target.module.getEnums()
|
||||
self.assertNotEqual( 0, len(lst2) )
|
||||
self.assertTrue( "enumType" in lst2 )
|
||||
|
@ -25,4 +25,5 @@ class MsPdbTest(unittest.TestCase):
|
||||
def testFindMethodOffset(self):
|
||||
"""Lookup method offset by name"""
|
||||
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") )
|
||||
|
@ -11,16 +11,16 @@ class TypedVarTest( unittest.TestCase ):
|
||||
def testCtor( self ):
|
||||
tv = target.module.typedVar( "structTest", target.module.g_structTest )
|
||||
tv = target.module.typedVar( "g_structTest" )
|
||||
|
||||
|
||||
tv = pykd.typedVar( "structTest", target.module.g_structTest )
|
||||
tv = pykd.typedVar( target.moduleName + "!structTest", target.module.g_structTest )
|
||||
|
||||
|
||||
structTest = target.module.type( "structTest" )
|
||||
tv = pykd.typedVar( structTest, target.module.g_structTest )
|
||||
|
||||
|
||||
tv = pykd.typedVar( "g_structTest" )
|
||||
tv = pykd.typedVar( target.moduleName + "!g_structTest" )
|
||||
|
||||
|
||||
def testBaseTypes(self):
|
||||
self.assertEqual( 1, target.module.typedVar( "g_ucharValue" ) )
|
||||
self.assertEqual( 2, target.module.typedVar( "g_ushortValue" ) )
|
||||
@ -46,7 +46,7 @@ class TypedVarTest( unittest.TestCase ):
|
||||
customStructTest.append("m_field1", pykd.typeInfo("UInt8B"))
|
||||
tvCustomStruct = pykd.typedVar( customStructTest.ptrTo(), target.module.offset("g_structTestPtr") )
|
||||
self.assertEqual( 500, tvCustomStruct.deref().m_field1 )
|
||||
|
||||
|
||||
def testArrayOf(self):
|
||||
arrayType = pykd.typeInfo("UInt8B").arrayOf(5)
|
||||
arrayVar = pykd.typedVar( arrayType, target.module.offset("ulonglongArray") )
|
||||
@ -74,7 +74,7 @@ class TypedVarTest( unittest.TestCase ):
|
||||
self.assertEqual( 16 + pykd.ptrSize(), tv1.sizeof() )
|
||||
tv2 = target.module.typedVar( "structTest[2]", target.module.g_testArray )
|
||||
self.assertEqual( tv1.sizeof()*2, tv2.sizeof() )
|
||||
|
||||
|
||||
self.assertEqual( pykd.sizeof("g_structTest"), tv1.sizeof() )
|
||||
self.assertEqual( pykd.sizeof("g_testArray"), tv2.sizeof() )
|
||||
self.assertEqual( pykd.sizeof("g_ucharValue"), 1 )
|
||||
@ -116,12 +116,12 @@ class TypedVarTest( unittest.TestCase ):
|
||||
self.assertTrue(False)
|
||||
except IndexError:
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def testArrayFieldSlice(self):
|
||||
tv = target.module.typedVar( "g_struct3" )
|
||||
self.assertEqual( 2, tv.m_arrayField[-1] )
|
||||
self.assertEqual( [ 0, 2 ], tv.m_arrayField[0:2] )
|
||||
|
||||
|
||||
def testGlobalVar(self):
|
||||
self.assertEqual( 4, target.module.typedVar( "g_ulongValue" ) )
|
||||
self.assertEqual( 0x80000000, target.module.typedVar( "ulongArray" )[3] )
|
||||
@ -135,7 +135,7 @@ class TypedVarTest( unittest.TestCase ):
|
||||
off2 = target.module.offset( "g_structTest" )
|
||||
tv = target.module.containingRecord( off2 + off1, "structTest", "m_field2" )
|
||||
self.assertEqual( True, tv.m_field2 )
|
||||
|
||||
|
||||
def testBitField(self):
|
||||
tv = target.module.typedVar("g_structWithBits")
|
||||
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" )
|
||||
self.assertEqual( 3, len( 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" )
|
||||
self.assertEqual( 3, len( 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 )
|
||||
tvl2 = pykd.typedVarArray( target.module.g_testArray, target.moduleName + "!structTest", 2 )
|
||||
self.assertEqual( tvl1, tvl2 )
|
||||
|
||||
|
||||
def testEqual(self):
|
||||
tv1 = target.module.typedVar("g_structTest")
|
||||
tv2 = target.module.typedVar("intMatrix")
|
||||
self.assertEqual( tv1.m_field3, tv2[0][1] )
|
||||
|
||||
|
||||
def testEnum(self):
|
||||
tv = target.module.typedVar("g_classChild")
|
||||
self.assertEqual( 3, tv.m_enumField )
|
||||
self.assertEqual( target.module.type("enumType").THREE, tv.m_enumField )
|
||||
|
||||
|
||||
def testIndex(self):
|
||||
ind = target.module.typedVar( "g_ucharValue" )
|
||||
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, tv2.deref )
|
||||
|
||||
|
||||
|
||||
def testTypeVarArg(self):
|
||||
tv1 = target.module.typedVar( "structTest", target.module.g_structTest )
|
||||
tv2 = target.module.typedVar( "structTest", tv1 )
|
||||
@ -278,7 +277,7 @@ class TypedVarTest( unittest.TestCase ):
|
||||
types = ("structTest", "ULong[100]", "ULong*" )
|
||||
for ti in types:
|
||||
self.assertTrue( str(pykd.typedVar( target.module.type(ti), 0 ) ) )
|
||||
|
||||
|
||||
def testStaticField(self):
|
||||
tv = pykd.typedVar( "g_classChild" )
|
||||
self.assertEqual( 200, tv.m_staticField )
|
||||
@ -287,17 +286,15 @@ class TypedVarTest( unittest.TestCase ):
|
||||
def testAmbiguousFieldAccess(self):
|
||||
derivedFiledVal = pykd.loadCStr( pykd.typedVar( "g_fieldSameNameStruct" ).m_field )
|
||||
self.assertEqual( derivedFiledVal, "toaster" )
|
||||
print target.module.type("fieldSameNameStruct")
|
||||
|
||||
|
||||
def testDiamondVirtualInherit(self):
|
||||
tv = pykd.typedVar( "g_virtChild" )
|
||||
self.assertEqual( -100, tv.m_baseField )
|
||||
|
||||
|
||||
def testDinkumwareMap(self):
|
||||
g_map = target.module.typedVar( "g_map" )
|
||||
self.assertEqual( 1, g_map._Mysize )
|
||||
|
||||
|
||||
|
||||
def testUdtSubscribe(self):
|
||||
tv = pykd.typedVar( "g_virtChild" )
|
||||
self.assertEqual( 5, len(tv) )
|
||||
@ -306,9 +303,8 @@ class TypedVarTest( unittest.TestCase ):
|
||||
self.assertEqual( fieldVal, tv.m_baseField )
|
||||
for field in tv:
|
||||
str( field )
|
||||
|
||||
|
||||
def testDeadlockList(self):
|
||||
|
||||
lst = []
|
||||
entry = pykd.typedVar("entry1").Flink
|
||||
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;
|
||||
|
||||
classChild g_classChild;
|
||||
@ -405,6 +414,9 @@ void FuncWithName0()
|
||||
classChild _classChild;
|
||||
_classChild.baseMethod();
|
||||
|
||||
static volatile YetAnotherChild_class yetAnotherChild;
|
||||
std::cout << yetAnotherChild.m_i;
|
||||
|
||||
reinterpret_cast<classChild *>(&_classChild)->virtFunc2();
|
||||
std::cout << _classChild.m_childField2;
|
||||
std::cout << g_constNumValue;
|
||||
|
Loading…
Reference in New Issue
Block a user