Pawel Lukasik
.net dev
* X - 1 do 10
auto hr = pICorProfilerInfoUnk->QueryInterface(
IID_ICorProfilerInfo5,
(void**)&pInfo);
auto hr = pInfo->SetEventMask2(
COR_PRF_ALL |
COR_PRF_MONITOR_ALL |
COR_PRF_ENABLE_STACK_SNAPSHOT |
COR_PRF_MONITOR_THREADS, COR_PRF_HIGH_MONITOR_NONE);
RESULT __stdcall OctoProfiler::AssemblyLoadStarted(AssemblyID assemblyId)
{
auto assemblyName = nameResolver->ResolveAssemblyName(assemblyId);
Logger::DoLog(std::format(L"OctoProfiler::AssemblyLoadStarted: {0}",
assemblyName.value_or(L"<<no info>>")));
return S_OK;
}
HRESULT __stdcall OctoProfiler::AssemblyLoadFinished(AssemblyID assemblyId, HRESULT hrStatus)
{
auto assemblyName = nameResolver->ResolveAssemblyName(assemblyId);
Logger::DoLog(std::format(L"OctoProfiler::AssemblyLoadFinished: {0}",
assemblyName.value_or(L"<<no info>>")));
return S_OK;
}
HRESULT __stdcall OctoProfiler::AssemblyUnloadStarted(AssemblyID assemblyId)
{
return E_NOTIMPL;
}
hr = pInfo->DoStackSnapshot(NULL, &StackSnapshotInfo, COR_PRF_SNAPSHOT_DEFAULT,
reinterpret_cast<void *>(nameResolver.get()), NULL, 0);
HRESULT __stdcall StackSnapshotInfo(
FunctionID funcId, UINT_PTR ip, COR_PRF_FRAME_INFO frameInfo,
ULONG32 contextSize, BYTE context[], void* clientData)
{
if (!funcId)
{
Logger::DoLog(std::format("OctoProfiler::Native frame {0:x}", ip));
}
else
{
NameResolver* nameResolver = reinterpret_cast<NameResolver*>(clientData);
auto functionName = nameResolver->ResolveFunctionName(funcId);
Logger::DoLog(std::format(L"OctoProfiler::Managed frame {0} {1:x}",
functionName.value_or(L"<<no info>>"), ip));
}
return S_OK;
}
hr = pInfo->SetEventMask2(COR_PRF_MONITOR_ENTERLEAVE,
COR_PRF_HIGH_MONITOR_NONE);
this->pInfo->SetFunctionIDMapper2(&MapFunctionId,
reinterpret_cast<void*>(nameResolver.get()));
this->pInfo->SetEnterLeaveFunctionHooks2(
reinterpret_cast<FunctionEnter2*>(FuncEnterCallback),
reinterpret_cast<FunctionLeave2*>(FuncLeaveCallback), nullptr);
void FuncEnterCallback(
FunctionID funId,
UINT_PTR clientData,
COR_PRF_FRAME_INFO frameInfo,
COR_PRF_FUNCTION_ARGUMENT_INFO * argInfo);
void FuncLeaveCallback(
FunctionID funId,
UINT_PTR clientData,
COR_PRF_FRAME_INFO frameInfo,
COR_PRF_FUNCTION_ARGUMENT_INFO* argInfo);
UINT_PTR __stdcall MapFunctionId(
FunctionID funcId,
void *clientData,
BOOL *pbHookFunction)
{
auto nameResolver = reinterpret_cast<NameResolver*>(clientData);
auto functionName = nameResolver->ResolveFunctionName(funcId);
*pbHookFunction = false;
if (functionName.has_value())
{
auto c_ptr = new std::wstring(
functionName.value_or(L"<<unknown>>"));
*pbHookFunction = true;
return reinterpret_cast<UINT_PTR>(c_ptr->c_str());
}
return NULL;
}
FuncEnterCallback proc frame
; rcx - funcId, rdx - clientData,
; r8 - frameInfo, r9 - argInfo
push rax
.allocstack 8
sub rsp, 20h
.allocstack 20h
.endprolog
call FuncEnterStub
add rsp, 20h
; restore
pop rax
ret
FuncEnterCallback endp
SET DOTNET_EnableDiagnostics=1
SET COR_ENABLE_PROFILING=1
SET CORECLR_ENABLE_PROFILING=1
SET COR_PROFILER={8A8CC829-CCF2-49FE-BBAE-0F022228071A}
SET CORECLR_PROFILER={8A8CC829-CCF2-49FE-BBAE-0F022228071A}
SET COR_PROFILER_PATH=.\x64\Release\OctoProfiler.dll
SET CORECLR_PROFILER_PATH_64=.\x64\Release\OctoProfiler.dll
By Pawel Lukasik