I'm using CLR profiling API and trying to get arguments info (COR_PRF_FUNCTION_ARGUMENT_INFO) from COR_PRF_ELT_INFO using GetFunctionEnter3Info function.

Below is my code. It seems GetFunctionEnter3Info function is not setting the value for pArgumentInfo. It always has null value. However, the function returns S_OK, which is a success.

I may be missing something. How should I get COR_PRF_FUNCTION_ARGUMENT_INFO from COR_PRF_ELT_INFO ?

    PROFILER_STUB EnterStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
{
        COR_PRF_FRAME_INFO *pFrameInfo = 0;
        ULONG *pcbArgumentInfo = 0;
        COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo = NULL;

        corProfilerInfo->GetFunctionEnter3Info(functionId.functionID, eltInfo, pFrameInfo, pcbArgumentInfo, pArgumentInfo);
        if(pArgumentInfo) {
            //
        }
    }
1

There are 1 best solutions below

0
Svirin On

It is a little bit tricky,

By msdn doc:

pcbArgumentInfo [in, out] A pointer to the total size, in bytes, of the COR_PRF_FUNCTION_ARGUMENT_INFO structure (plus any additional COR_PRF_FUNCTION_ARGUMENT_RANGE structures for the argument ranges pointed to by pArgumentInfo). If the specified size is not enough, ERROR_INSUFFICIENT_BUFFER is returned and the expected size is stored in pcbArgumentInfo. To call GetFunctionEnter3Info just to retrieve the expected value for *pcbArgumentInfo, set *pcbArgumentInfo=0 and pArgumentInfo=NULL

In other words, you have a single COR_PRF_FUNCTION_ARGUMENT_INFO structure, which references multiple COR_PRF_FUNCTION_ARGUMENT_RANGE. First of all, get a number of bytes of pcbArgumentInfo, after that allocate bytes and pass the pointer to GetFunctionEnter3Info as COR_PRF_FUNCTION_ARGUMENT_INFO.

Here is an example

PROFILER_STUB EnterStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
{
    ULONG pcbArgumentInfo = 0;
    COR_PRF_FRAME_INFO frameInfo;
    corProfilerInfo3->GetFunctionEnter3Info(functionIDOrClientID.functionID, eltInfo, &frameInfo, &pcbArgumentInfo, NULL);

    char* pArgumentInfo = new char[pcbArgumentInfo];
    corProfilerInfo3->GetFunctionEnter3Info(functionIDOrClientID.functionID, eltInfo, &frameInfo, &pcbArgumentInfo, (COR_PRF_FUNCTION_ARGUMENT_INFO*)pArgumentInfo);

    COR_PRF_FUNCTION_ARGUMENT_INFO* ptr = (COR_PRF_FUNCTION_ARGUMENT_INFO*)pArgumentInfo;
}

To access the second argument info block of COR_PRF_FUNCTION_ARGUMENT_RANGE use

prt->ranges[1]

The number of blocks is written in ptr->numRanges