IDebugComPlusSymbolProvider::GetAddressesInModuleFromPosition
Maps a document position in the specified module to an array of debug addresses.
[C++]
HRESULT GetAddressesInModuleFromPosition(
ULONG32 ulAppDomainID,
GUID guidModule,
IDebugDocumentPosition2* pDocPos,
BOOL fStatmentOnly,
IEnumDebugAddresses** ppEnumBegAddresses,
IEnumDebugAddresses** ppEnumEndAddresses
);
[C#]
int GetAddressesInModuleFromPosition(
uint ulAppDomainID,
Guid guidModule,
IDebugDocumentPosition2 pDocPos,
bool fStatmentOnly,
out IEnumDebugAddresses ppEnumBegAddresses,
out IEnumDebugAddresses ppEnumEndAddresses
);
Parameters
ulAppDomainID
[in] Application domain identifier.guidModule
[in] Unique identifier of the module.pDocPos
[in] The document position.fStatmentOnly
[in] If TRUE, limits the debug addresses to a single statement.ppEnumBegAddresses
[out] Returns an enumerator for the starting debug addresses that are associated with this statement or line.ppEnumEndAddresses
[out] Returns an enumerator for the ending debug addresses that are associated with this statement or line.
Return Value
If successful, returns S_OK; otherwise, returns an error code.
Example
The following example shows how to implement this method for a CDebugSymbolProvider object that exposes the IDebugComPlusSymbolProvider interface.
HRESULT CDebugSymbolProvider::GetAddressesInModuleFromPosition(
ULONG32 ulAppDomainID,
GUID guidModule,
IDebugDocumentPosition2* pDocPos,
BOOL fStatementOnly,
IEnumDebugAddresses** ppEnumBegAddresses,
IEnumDebugAddresses** ppEnumEndAddresses
)
{
GUID guidNULL = {0};
if (guidNULL == guidModule)
{
return GetAddressesInAppDomainFromPosition( ulAppDomainID,
pDocPos,
fStatementOnly,
ppEnumBegAddresses,
ppEnumEndAddresses );
}
else
{
return GetAddressesInModuleFromPositionHelper( ulAppDomainID,
guidModule,
pDocPos,
fStatementOnly,
ppEnumBegAddresses,
ppEnumEndAddresses );
}
}
HRESULT CDebugSymbolProvider::GetAddressesInModuleFromPositionHelper(
ULONG32 ulAppDomainID,
GUID guidModule,
IDebugDocumentPosition2* pDocPos,
BOOL fStatementOnly,
IEnumDebugAddresses** ppEnumBegAddresses,
IEnumDebugAddresses** ppEnumEndAddresses
)
{
HRESULT hr = S_OK;
CComBSTR bstrFileName;
TEXT_POSITION posBeg;
TEXT_POSITION posEnd;
DWORD dwLine;
USHORT segRet = 0;
ULONG offRet = 0;
CAddrList listAddr;
CAddrList listAddrEnd;
CAddrList* plistAddrEnd = NULL;
bool fFileFound = false;
Module_ID idModule(ulAppDomainID, guidModule);
DWORD dwListCount;
bool fFoundAddresses = false;
CComPtr<CModule> pmodule;
DWORD dwBegCol = 0;
DWORD dwEndCol = 0;
ASSERT(IsValidObjectPtr(this, CDebugSymbolProvider));
ASSERT(IsValidInterfacePtr(pDocPos, IDebugDocumentPosition2));
ASSERT(IsValidWritePtr(ppEnumBegAddresses, IEnumDebugAddresses*));
METHOD_ENTRY(CDebugSymbolProvider::GetAddressesInModuleFromPositionHelper);
// Bail on Invalid Args
IfFalseGo( pDocPos && ppEnumBegAddresses, E_INVALIDARG );
*ppEnumBegAddresses = NULL;
if (ppEnumEndAddresses)
{
*ppEnumEndAddresses = NULL;
plistAddrEnd = &listAddrEnd;
}
// Get the Position
IfFailGo( pDocPos->GetFileName(&bstrFileName) );
IfFailGo( pDocPos->GetRange(&posBeg, &posEnd) );
// Iterate over the module list accumulating addresses
// that match the position
dwLine = posBeg.dwLine;
IfFailGo( GetModule( idModule, &pmodule ) );
dwListCount = listAddr.GetCount();
if ( fStatementOnly )
{
dwBegCol = posBeg.dwColumn;
dwEndCol = posBeg.dwLine == posEnd.dwLine ? posEnd.dwColumn : DWORD( -1);
}
else
{
dwBegCol = 0;
dwEndCol = DWORD( -1);
}
while (!fFoundAddresses && dwLine <= posEnd.dwLine )
{
hr = pmodule->GetAddressesFromLine( bstrFileName,
dwLine,
posEnd.dwLine,
dwBegCol,
dwEndCol,
&listAddr,
plistAddrEnd );
dwLine++;
dwBegCol = 0;
dwEndCol = dwLine == posEnd.dwLine ? posEnd.dwColumn : DWORD( -1);
if (hr == E_SH_INVALID_POSITION)
{
fFileFound = true;
break;
}
if (FAILED(hr))
{
// Move on to the next module
break;
}
fFileFound = true;
fFoundAddresses = listAddr.GetCount() != dwListCount;
}
// Distinguish no file from bad position in the file
IfFalseGo( fFileFound, E_SH_FILE_NOT_FOUND);
// If the list is empty the position is bad
IfFalseGo( listAddr.GetCount(), E_SH_INVALID_POSITION );
// Create enumerators
IfFailGo( CreateEnumerator( ppEnumBegAddresses, &listAddr ) );
if (ppEnumEndAddresses)
{
IfFailGo( CreateEnumerator( ppEnumEndAddresses, &listAddrEnd ) );
}
Error:
METHOD_EXIT(CDebugSymbolProvider::GetAddressesInModuleFromPositionHelper, hr);
return hr;
}