示例#1
0
static void DumpTypes(IDiaSession *session)
{
    IDiaSymbol *        globalScope = NULL;
    IDiaEnumSymbols *   enumSymbols = NULL;
    IDiaSymbol *        symbol = NULL;

    HRESULT hr = session->get_globalScope(&globalScope);
    if (FAILED(hr))
        return;

    AddReportSepLine();
    g_report.Append("Types:\n");

    DWORD flags = nsfCaseInsensitive|nsfUndecoratedName; // nsNone ?
    hr = globalScope->findChildren(SymTagUDT, 0, flags, &enumSymbols);
    if (FAILED(hr))
        goto Exit;

    ULONG celt = 0;
    for (;;)
    {
        hr = enumSymbols->Next(1, &symbol, &celt);
        if (FAILED(hr) || (celt != 1))
            break;
        DumpType(symbol, 0);
        symbol->Release();
    }

Exit:
    UnkReleaseSafe(enumSymbols);
    UnkReleaseSafe(globalScope);
}
示例#2
0
//-----------------------------------------------------------------------------
// Name: ParseModules
// Object: parse all compilands
// Parameters :
//     in  : 
//     out : 
//     return : TRUE on success
//-----------------------------------------------------------------------------
BOOL CDebugInfos::ParseModules()
{
    HRESULT hr;
    IDiaEnumSymbols* pEnumSymbols;
    IDiaEnumSymbols* pEnumChildren;
    IDiaSymbol* pCompiland;
    IDiaSymbol* pSymbol;
    ULONG celt = 0;
    CModuleInfos* pModuleInfo;
    BSTR Name;

    // Retrieve the compilands first
    if(FAILED(this->pDiaGlobalSymbol->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols)))
        return FALSE;

    // for each compiland
    while(pEnumSymbols->Next(1, &pCompiland, &celt) == S_OK && celt == 1) 
    {
        // Retrieve the name of the module
        Name=NULL;
        pCompiland->get_name(&Name);

#if (REMOVE_LINKER_COMPILAND==1)
        // avoid to display "* Linker *" infos
        if (Name)
        {
            if (wcsicmp(Name,LINKER_COMPILAND_NAME)==0)
            {
                SysFreeString(Name);
                pCompiland->Release();
                continue;
            }
        }
#endif

        // create module info
        pModuleInfo=new CModuleInfos();
        // add it to modules list
        this->pLinkListModules->AddItem(pModuleInfo);
        // assume module name is set
        if (Name)
        {
#if (defined(UNICODE)||defined(_UNICODE))
            pModuleInfo->Name=_tcsdup(Name);
#else
            CAnsiUnicodeConvert::UnicodeToAnsi(Name,&pModuleInfo->Name);
#endif
            SysFreeString(Name);
        }
        else
            pModuleInfo->Name=_tcsdup(_T(""));

        // Find all the symbols defined in this compiland and get their info
        if(SUCCEEDED(pCompiland->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren)))
        {
            ULONG celt_ = 0;
            while (pEnumChildren->Next(1, &pSymbol, &celt_) == S_OK && celt_ == 1) 
            {
                hr=pModuleInfo->Parse(pSymbol);
                if (FAILED(hr))
                    this->ReportError(_T("Error parsing module information"),hr);
                pSymbol->Release();
            }
            pEnumChildren->Release();
        }
        pCompiland->Release();
    }
    pEnumSymbols->Release();
    return TRUE;
}
示例#3
0
//------------------------------------------------------------------------
// pParentSymbol 에서 자식중에 symbolName 인 심볼을 리턴한다.
// 찾은 심볼의 Offset값을 리턴한다.
// pParentSymbol 은 Data, UDT, TypeDef 타입이어야 한다.
//------------------------------------------------------------------------
IDiaSymbol* dia::FindChildSymbol( const std::string &symbolName, 
								 IDiaSymbol *pParentSymbol, OUT LONG *pOffset ) // pOffset =NULL
{
	RETV( !pParentSymbol, NULL );

	const string name = GetSymbolName(pParentSymbol); //debug용
	const wstring searchSymbolName = memmonitor::str2wstr(symbolName).c_str();

	// 데이타 심볼이면, 타입 심볼로 교체한다.
	enum SymTagEnum symTag;
	HRESULT hr = pParentSymbol->get_symTag((DWORD*)&symTag);

	bool isNewTypeSymbol = false;
	IDiaSymbol* pTypeSymbol = NULL;
	switch (symTag)
	{
	case SymTagData:
		isNewTypeSymbol = true;
		hr = pParentSymbol->get_type(&pTypeSymbol);
		break;
	case SymTagTypedef:
		{
			hr = pParentSymbol->get_type(&pTypeSymbol);
			IDiaSymbol *reval = FindChildSymbol(symbolName, pTypeSymbol, pOffset);
			if (pTypeSymbol)
				pTypeSymbol->Release();
			return reval;
		}
		break;
	default:
		{
			pTypeSymbol = pParentSymbol;
		}
		break;
	}

	// Enumeration
	CComPtr<IDiaEnumSymbols> pEnumSymbols;
	if (FAILED(pTypeSymbol->findChildren(SymTagNull, searchSymbolName.c_str(), 
		nsRegularExpression, &pEnumSymbols)))
	{
		if (isNewTypeSymbol)
			pTypeSymbol->Release();
		return NULL;
	}

	IDiaSymbol *pFindSymbol;
	ULONG celt = 0;
	pEnumSymbols->Next(1, &pFindSymbol, &celt);
	// 찾았다면 리턴 
	if (1 == celt)
	{
		if (isNewTypeSymbol)
			pTypeSymbol->Release();
		if (pOffset)
			hr = pFindSymbol->get_offset(pOffset);
		return pFindSymbol;
	}

	// 못찾았다면, 자식 중에서 찾아본다. enum  으로 선언된 값은 이렇게 찾아야함
	CComPtr<IDiaEnumSymbols> pAnotherEnumSymbols;
	if (FAILED(pTypeSymbol->findChildren(SymTagNull, NULL, nsNone, &pAnotherEnumSymbols)))
	{
		if (isNewTypeSymbol)
			pTypeSymbol->Release();
		return NULL;
	}

	pFindSymbol = NULL;
	IDiaSymbol* pChildSymbol;
	celt = 0;
	while (SUCCEEDED(pAnotherEnumSymbols->Next(1, &pChildSymbol, &celt)) && (celt == 1)) 
	{
		enum SymTagEnum symTag;
		pChildSymbol->get_symTag((DWORD*)&symTag);

		if (SymTagBaseClass == symTag)
		{
			LONG childOffset = 0;
			pFindSymbol = FindChildSymbol( symbolName, pChildSymbol, &childOffset );
			if (pFindSymbol)
			{
				LONG baseClassOffset = 0;
				hr = pChildSymbol->get_offset(&baseClassOffset);
				if (pOffset)
					*pOffset = baseClassOffset + childOffset;
				break;
			}
		}

		if (SymTagEnum != symTag) 
		{ 
			pChildSymbol->Release(); 
			continue; 
		}

		CComPtr<IDiaEnumSymbols> pSubEnumSymbols;
		if (FAILED(pChildSymbol->findChildren(SymTagNull, searchSymbolName.c_str(), 
			nsRegularExpression, &pSubEnumSymbols)))
		{
			pChildSymbol->Release(); 
			continue; 
		}

		celt = 0;
		pSubEnumSymbols->Next( 1, &pFindSymbol, &celt );
		if (1 == celt)
		{
			pChildSymbol->Release();
			const string name = GetSymbolName(pFindSymbol); //debug용
			if (pOffset)
				*pOffset = 0; // 상수값은 offset이 없다.
			break; // 찾았으니 종료
		}
	}

	if (isNewTypeSymbol)
		pTypeSymbol->Release();
	return pFindSymbol;
}