mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
[pykd] fixed: issue 8669 ( typedVar() creates an object for a non-existent structure type )
git-svn-id: https://pykd.svn.codeplex.com/svn@64206 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
90265c7a5f
commit
228e4b1374
223
pykd/dbgtype.cpp
223
pykd/dbgtype.cpp
@ -16,7 +16,9 @@ using namespace std;
|
|||||||
boost::python::object
|
boost::python::object
|
||||||
loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG64 address )
|
loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG64 address )
|
||||||
{
|
{
|
||||||
return TypeInfo::get( moduleName, typeName ).load( address );
|
const TypeInfo *typeInfo = TypeInfo::get( moduleName, typeName );
|
||||||
|
|
||||||
|
return typeInfo != NULL ? typeInfo->load( address ) : boost::python::object();
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -35,7 +37,9 @@ sizeofType( const std::string &moduleName, const std::string &typeName )
|
|||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||||
|
|
||||||
typeSize = (ULONG)TypeInfo::get( moduleName, typeName ).size();
|
const TypeInfo *typeInfo = TypeInfo::get( moduleName, typeName );
|
||||||
|
|
||||||
|
return typeInfo != NULL ? (ULONG)typeInfo->size() : 0L;
|
||||||
}
|
}
|
||||||
catch( std::exception &e )
|
catch( std::exception &e )
|
||||||
{
|
{
|
||||||
@ -73,7 +77,7 @@ containingRecord( ULONG64 address, const std::string &moduleName, const std::str
|
|||||||
ULONG fieldOffset;
|
ULONG fieldOffset;
|
||||||
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName.c_str(), &fieldTypeId, &fieldOffset );
|
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName.c_str(), &fieldTypeId, &fieldOffset );
|
||||||
|
|
||||||
return TypeInfo::get( moduleName, typeName ).load( address - fieldOffset );
|
return loadTypedVar( moduleName, typeName, address - fieldOffset );
|
||||||
}
|
}
|
||||||
catch( std::exception &e )
|
catch( std::exception &e )
|
||||||
{
|
{
|
||||||
@ -94,7 +98,9 @@ getTypeClass( const std::string &moduleName, const std::string &typeName )
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return TypeInfo::get( moduleName, typeName ).build();
|
const TypeInfo *typeInfo = TypeInfo::get( moduleName, typeName );
|
||||||
|
|
||||||
|
return typeInfo != NULL ? typeInfo->build() : boost::python::object();
|
||||||
}
|
}
|
||||||
catch( std::exception &e )
|
catch( std::exception &e )
|
||||||
{
|
{
|
||||||
@ -104,6 +110,7 @@ getTypeClass( const std::string &moduleName, const std::string &typeName )
|
|||||||
{
|
{
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::python::object();
|
return boost::python::object();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,11 +123,14 @@ loadTypedVarList( ULONG64 address, const std::string &moduleName, const std::str
|
|||||||
|
|
||||||
ULONG64 entryAddress = 0;
|
ULONG64 entryAddress = 0;
|
||||||
|
|
||||||
const TypeInfo& typeInfo = TypeInfo::get( moduleName, typeName );
|
const TypeInfo *typeInfo = TypeInfo::get( moduleName, typeName );
|
||||||
|
|
||||||
|
if ( !typeInfo )
|
||||||
|
return boost::python::object();
|
||||||
|
|
||||||
boost::python::list objList;
|
boost::python::list objList;
|
||||||
|
|
||||||
for ( TypeInfo::TypeFieldList::const_iterator field = typeInfo.getFields().begin(); field != typeInfo.getFields().end(); field++ )
|
for ( TypeInfo::TypeFieldList::const_iterator field = typeInfo->getFields().begin(); field != typeInfo->getFields().end(); field++ )
|
||||||
{
|
{
|
||||||
if ( field->name == listEntryName )
|
if ( field->name == listEntryName )
|
||||||
{
|
{
|
||||||
@ -149,10 +159,13 @@ loadTypedVarArray( ULONG64 address, const std::string &moduleName, const std::st
|
|||||||
{
|
{
|
||||||
boost::python::list objList;
|
boost::python::list objList;
|
||||||
|
|
||||||
const TypeInfo& typeInfo = TypeInfo::get( moduleName, typeName );
|
const TypeInfo *typeInfo = TypeInfo::get( moduleName, typeName );
|
||||||
|
|
||||||
|
if ( !typeInfo )
|
||||||
|
return boost::python::object();
|
||||||
|
|
||||||
for( long i = 0; i < number; ++i )
|
for( long i = 0; i < number; ++i )
|
||||||
objList.append( loadTypedVar( moduleName, typeName, address + i * typeInfo.size() ) );
|
objList.append( loadTypedVar( moduleName, typeName, address + i * typeInfo->size() ) );
|
||||||
|
|
||||||
return objList;
|
return objList;
|
||||||
}
|
}
|
||||||
@ -239,59 +252,34 @@ size_t basicTypeSizes[] = {
|
|||||||
|
|
||||||
TypeInfo::TypeInfoMap TypeInfo::g_typeInfoCache;
|
TypeInfo::TypeInfoMap TypeInfo::g_typeInfoCache;
|
||||||
|
|
||||||
const TypeInfo&
|
const TypeInfo*
|
||||||
TypeInfo::get( const std::string &moduleName, const std::string &typeName )
|
TypeInfo::get( const std::string &moduleName, const std::string &typeName )
|
||||||
{
|
|
||||||
TypeInfoMap::iterator findIt = g_typeInfoCache.find( TypeName( moduleName, typeName ) );
|
|
||||||
|
|
||||||
if ( findIt != g_typeInfoCache.end() )
|
|
||||||
return findIt->second;
|
|
||||||
|
|
||||||
TypeInfo typeInfo( moduleName, typeName );
|
|
||||||
|
|
||||||
return g_typeInfoCache.insert( std::make_pair( TypeName( moduleName, typeName ), typeInfo) ).first->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void
|
|
||||||
TypeInfo::setupBaseType()
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < sizeof( basicTypeSizes ) / sizeof( size_t ); ++i )
|
|
||||||
{
|
|
||||||
if ( m_typeName == basicTypeNames[i] ||
|
|
||||||
m_typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
|
|
||||||
{
|
|
||||||
m_size = (ULONG)basicTypeSizes[i];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName )
|
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
m_typeName = typeName;
|
|
||||||
m_size = 0;
|
|
||||||
m_baseType = false;
|
|
||||||
m_pointer = false;
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
TypeInfoMap::iterator findIt = g_typeInfoCache.find( TypeName( moduleName, typeName ) );
|
||||||
|
|
||||||
|
if ( findIt != g_typeInfoCache.end() )
|
||||||
|
return &findIt->second;
|
||||||
|
|
||||||
|
TypeInfo typeInfo( typeName );
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
if ( typeName.find("*") < typeName.size() )
|
if ( typeName.find("*") < typeName.size() )
|
||||||
{
|
{
|
||||||
m_pointer = true;
|
typeInfo.m_pointer = true;
|
||||||
m_size = ptrSize();
|
typeInfo.m_size = ptrSize();
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_baseType = isBaseType( typeName );
|
typeInfo.m_baseType = isBaseType( typeName );
|
||||||
if ( m_baseType )
|
if ( typeInfo.m_baseType )
|
||||||
{
|
{
|
||||||
setupBaseType();
|
typeInfo.setupBaseType();
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG64 moduleBase = 0;
|
ULONG64 moduleBase = 0;
|
||||||
@ -300,11 +288,11 @@ TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName
|
|||||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||||
|
|
||||||
ULONG typeId = 0;
|
ULONG typeId = 0;
|
||||||
hres = dbgExt->symbols->GetTypeId( moduleBase, m_typeName.c_str(), &typeId );
|
hres = dbgExt->symbols->GetTypeId( moduleBase, typeInfo.m_typeName.c_str(), &typeId );
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
||||||
|
|
||||||
hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &m_size );
|
hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &typeInfo.m_size );
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
||||||
|
|
||||||
@ -332,29 +320,148 @@ TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName
|
|||||||
hres = dbgExt->symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL );
|
hres = dbgExt->symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL );
|
||||||
|
|
||||||
std::string fieldTypeNameStr( fieldTypeName );
|
std::string fieldTypeNameStr( fieldTypeName );
|
||||||
|
|
||||||
if ( fieldTypeNameStr == "__unnamed"
|
if ( fieldTypeNameStr == "__unnamed"
|
||||||
|| fieldTypeNameStr.find("<unnamed-tag>") < fieldTypeNameStr.size() )
|
|| fieldTypeNameStr.find("<unnamed-tag>") < fieldTypeNameStr.size() )
|
||||||
{
|
{
|
||||||
m_fields.push_back( TypeField( fieldName, TypeInfo( moduleName, fieldTypeId ), fieldSize, fieldOffset ) );
|
TypeInfo unnamedType;
|
||||||
|
if ( !getById( moduleName, fieldTypeId, unnamedType ) )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
typeInfo.m_fields.push_back( TypeField( fieldName, unnamedType, fieldSize, fieldOffset ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_fields.push_back( TypeField( fieldName, get(moduleName, fieldTypeName), fieldSize, fieldOffset ) );
|
const TypeInfo *fieldTypeInfo = get( moduleName, fieldTypeName );
|
||||||
|
if ( !fieldTypeInfo )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
typeInfo.m_fields.push_back( TypeField( fieldName, *fieldTypeInfo, fieldSize, fieldOffset ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} while( FALSE );
|
||||||
|
|
||||||
|
return &g_typeInfoCache.insert( std::make_pair( TypeName( moduleName, typeName ), typeInfo) ).first->second;
|
||||||
}
|
}
|
||||||
catch( std::exception &e )
|
catch( std::exception& )
|
||||||
{
|
{
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
//dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||||
|
// ýòî íîðìàëüíî: íà âõîä áûë ïåðåäàí íå âåðíûé òèï
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool
|
||||||
|
TypeInfo::getById( const std::string &moduleName, ULONG typeId, TypeInfo& typeInfo )
|
||||||
|
{
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
ULONG64 moduleBase = 0;
|
||||||
|
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||||
|
|
||||||
|
hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &typeInfo.m_size );
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
||||||
|
|
||||||
|
for ( ULONG i = 0; ; ++i )
|
||||||
|
{
|
||||||
|
char fieldName[100];
|
||||||
|
hres = dbgExt->symbols2->GetFieldName( moduleBase, typeId, i, fieldName, sizeof(fieldName), NULL );
|
||||||
|
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
ULONG fieldTypeId;
|
||||||
|
ULONG fieldOffset;
|
||||||
|
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName, &fieldTypeId, &fieldOffset );
|
||||||
|
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugSymbol3::GetFieldTypeAndOffset failed" );
|
||||||
|
|
||||||
|
ULONG fieldSize;
|
||||||
|
hres = dbgExt->symbols->GetTypeSize( moduleBase, fieldTypeId, &fieldSize );
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
||||||
|
|
||||||
|
char fieldTypeName[100];
|
||||||
|
hres = dbgExt->symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL );
|
||||||
|
|
||||||
|
std::string fieldTypeNameStr( fieldTypeName );
|
||||||
|
|
||||||
|
if ( fieldTypeNameStr == "__unnamed"
|
||||||
|
|| fieldTypeNameStr.find("<unnamed-tag>") < fieldTypeNameStr.size() )
|
||||||
|
{
|
||||||
|
TypeInfo unnamedType;
|
||||||
|
if ( !getById( moduleName, fieldTypeId, unnamedType ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
typeInfo.m_fields.push_back( TypeField( fieldName, unnamedType, fieldSize, fieldOffset ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const TypeInfo *fieldTypeInfo = get( moduleName, fieldTypeName );
|
||||||
|
if ( !fieldTypeInfo )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
typeInfo.m_fields.push_back( TypeField( fieldName, *fieldTypeInfo, fieldSize, fieldOffset ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch( std::exception& )
|
||||||
|
{
|
||||||
|
//dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||||
|
// ýòî íîðìàëüíî: íà âõîä áûë ïåðåäàí íå âåðíûé òèï
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void
|
||||||
|
TypeInfo::setupBaseType()
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < sizeof( basicTypeSizes ) / sizeof( size_t ); ++i )
|
||||||
|
{
|
||||||
|
if ( m_typeName == basicTypeNames[i] ||
|
||||||
|
m_typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
|
||||||
|
{
|
||||||
|
m_size = (ULONG)basicTypeSizes[i];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
TypeInfo::TypeInfo( const std::string &moduleName, ULONG typeId )
|
TypeInfo::TypeInfo( const std::string &moduleName, ULONG typeId )
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
@ -419,6 +526,8 @@ TypeInfo::TypeInfo( const std::string &moduleName, ULONG typeId )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
@ -554,8 +663,10 @@ valueLoader( ULONG64 address, ULONG size )
|
|||||||
{
|
{
|
||||||
valType v = 0;
|
valType v = 0;
|
||||||
if ( loadMemory( address, &v, sizeof(v) ) )
|
if ( loadMemory( address, &v, sizeof(v) ) )
|
||||||
|
{
|
||||||
return boost::python::long_( (unsigned __int64)v );
|
return boost::python::long_( (unsigned __int64)v );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
boost::python::dict arr;
|
boost::python::dict arr;
|
||||||
|
@ -85,9 +85,17 @@ public:
|
|||||||
m_pointer( false )
|
m_pointer( false )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TypeInfo( const std::string &moduleName, const std::string &typeName );
|
TypeInfo( const std::string &typeName ) :
|
||||||
|
m_size( 0 ),
|
||||||
|
m_baseType( false ),
|
||||||
|
m_pointer( false ),
|
||||||
|
m_typeName( typeName )
|
||||||
|
{}
|
||||||
|
|
||||||
TypeInfo( const std::string &moduleName, ULONG typeId );
|
|
||||||
|
/* TypeInfo( const std::string &moduleName, const std::string &typeName );
|
||||||
|
|
||||||
|
TypeInfo( const std::string &moduleName, ULONG typeId ); */
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
load( ULONG64 addr, ULONG offset = 0 ) const;
|
load( ULONG64 addr, ULONG offset = 0 ) const;
|
||||||
@ -95,7 +103,6 @@ public:
|
|||||||
boost::python::object
|
boost::python::object
|
||||||
build( ULONG offset = 0 ) const;
|
build( ULONG offset = 0 ) const;
|
||||||
|
|
||||||
|
|
||||||
ULONG64
|
ULONG64
|
||||||
size() const
|
size() const
|
||||||
{
|
{
|
||||||
@ -108,9 +115,6 @@ public:
|
|||||||
return m_typeName;
|
return m_typeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo&
|
|
||||||
get( const std::string &moduleName, const std::string &typeName );
|
|
||||||
|
|
||||||
const TypeFieldList&
|
const TypeFieldList&
|
||||||
getFields() const {
|
getFields() const {
|
||||||
return m_fields;
|
return m_fields;
|
||||||
@ -126,6 +130,9 @@ public:
|
|||||||
return m_pointer;
|
return m_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const TypeInfo*
|
||||||
|
get( const std::string &moduleName, const std::string &typeName );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static TypeInfoMap g_typeInfoCache;
|
static TypeInfoMap g_typeInfoCache;
|
||||||
@ -141,6 +148,9 @@ private:
|
|||||||
void
|
void
|
||||||
setupBaseType();
|
setupBaseType();
|
||||||
|
|
||||||
|
static bool
|
||||||
|
getById( const std::string &moduleName, ULONG typeId, TypeInfo& typeInfo );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_baseType;
|
bool m_baseType;
|
||||||
|
Loading…
Reference in New Issue
Block a user