Как получить COR_PRF_FUNCTION_ARGUMENT_INFO из COR_PRF_ELT_INFO с помощью функции GetFunctionEnter3Info в интерфейсе ICorProfilerInfo3

Я использую API профилирования CLR и пытаюсь получить информацию об аргументах (COR_PRF_FUNCTION_ARGUMENT_INFO) из COR_PRF_ELT_INFO с помощью функции GetFunctionEnter3Info.

Ниже мой код. Кажется, что функция GetFunctionEnter3Info не устанавливает значение для pArgumentInfo. Он всегда имеет нулевое значение. Однако функция возвращает S_OK, что является успешным.

Я могу что-то упустить. Как мне получить COR_PRF_FUNCTION_ARGUMENT_INFO из 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) {
            //
        }
    }

person Zader    schedule 21.07.2019    source источник
comment
Вы включили COR_PRF_ENABLE_FUNCTION_ARGS в вашем вызове SetEventMask?   -  person Brian Reichle    schedule 25.07.2019
comment
да. Я включил следующие флаги: COR_PRF_MONITOR_ENTERLEAVE, COR_PRF_ENABLE_FUNCTION_ARGS, COR_PRF_ENABLE_FUNCTION_RETVAL, COR_PRF_ENABLE_FRAME_INFO   -  person Zader    schedule 28.07.2019
comment
Случайно ли этот метод находится в образе ngen-ed? (например, mscorlib). Я заметил, что вы не указали COR_PRF_DISABLE_ALL_NGEN_IMAGES для отключения изображений, созданных с помощью ngen, или COR_PRF_USE_PROFILE_IMAGES, чтобы запросить изображения, созданные с помощью ngen с поддержкой профилирования.   -  person Brian Reichle    schedule 29.07.2019


Ответы (1)


Это немного сложно,

Документ msdn:

pcbArgumentInfo [in, out] Указатель на общий размер в байтах структуры COR_PRF_FUNCTION_ARGUMENT_INFO (плюс любые дополнительные структуры COR_PRF_FUNCTION_ARGUMENT_RANGE для диапазонов аргументов, на которые указывает pArgumentInfo). Если указанного размера недостаточно, возвращается ERROR_INSUFFICIENT_BUFFER, а ожидаемый размер сохраняется в pcbArgumentInfo. Чтобы вызвать GetFunctionEnter3Info только для получения ожидаемого значения для *pcbArgumentInfo, установите *pcbArgumentInfo=0 и pArgumentInfo=NULL.

Другими словами, у вас есть одна структура COR_PRF_FUNCTION_ARGUMENT_INFO, которая ссылается на несколько COR_PRF_FUNCTION_ARGUMENT_RANGE. Прежде всего, получите количество байтов pcbArgumentInfo, после этого распределите байты и передайте указатель на GetFunctionEnter3Info как COR_PRF_FUNCTION_ARGUMENT_INFO.

Вот пример

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;
}

Для доступа ко второму argument info блоку COR_PRF_FUNCTION_ARGUMENT_RANGE используйте

prt->ranges[1]

Количество блоков записывается в ptr->numRanges

person Svirin    schedule 08.09.2019