Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
306d6b0
first attempt
mayankbansal018 Feb 21, 2019
1007a5a
Make profiler
mayankbansal018 Feb 21, 2019
633e0ba
update guid
mayankbansal018 Feb 21, 2019
590f32c
add managed functions/instructions
mayankbansal018 Feb 22, 2019
a0d2809
errors
mayankbansal018 Feb 22, 2019
6300fb1
minor
mayankbansal018 Feb 22, 2019
de693fe
auto(not supported)
mayankbansal018 Feb 22, 2019
de265c9
use iterator
mayankbansal018 Feb 22, 2019
40a8528
fix auto debug info generation
mayankbansal018 Feb 22, 2019
4f5cec3
remove -g flag
mayankbansal018 Feb 22, 2019
20c44e1
square 1
mayankbansal018 Feb 22, 2019
375e10b
clang 3.7
mayankbansal018 Feb 22, 2019
7704ed3
revert
mayankbansal018 Feb 22, 2019
be09f70
fix auto
mayankbansal018 Feb 22, 2019
cdf2f2c
please compile
mayankbansal018 Feb 24, 2019
c78c6fd
separate disassembler
mayankbansal018 Mar 2, 2019
f9e04ff
fix
mayankbansal018 Mar 2, 2019
1642579
narrow
mayankbansal018 Mar 2, 2019
7b5ec14
fix
mayankbansal018 Mar 2, 2019
15f40a9
move map to header
mayankbansal018 Mar 2, 2019
4ae1393
error
mayankbansal018 Mar 2, 2019
8c02537
compile disassembler
mayankbansal018 Mar 2, 2019
ab6dadd
unordered_map
mayankbansal018 Mar 2, 2019
f379575
remove map
mayankbansal018 Mar 2, 2019
4d3347c
remove map
mayankbansal018 Mar 2, 2019
f1c60e2
include directory
mayankbansal018 Mar 2, 2019
48bfb07
build dis-assem
mayankbansal018 Mar 2, 2019
d528156
load lib
mayankbansal018 Mar 12, 2019
930c771
bstr to wstring
mayankbansal018 Mar 12, 2019
abd5429
zz
mayankbansal018 Mar 12, 2019
d6e7b6a
load lib
mayankbansal018 Mar 12, 2019
e17923f
zzz
mayankbansal018 Mar 12, 2019
ca107eb
tstring
mayankbansal018 Mar 13, 2019
0a351a4
fix
mayankbansal018 Mar 13, 2019
bac5f87
load method
mayankbansal018 Mar 13, 2019
216e49a
nit
mayankbansal018 Mar 13, 2019
31a5704
correct function def
mayankbansal018 Mar 13, 2019
30674c6
get method
mayankbansal018 Mar 13, 2019
79c0f76
stdcall
mayankbansal018 Mar 13, 2019
c46048c
method name
mayankbansal018 Mar 13, 2019
f419737
zz
mayankbansal018 Mar 13, 2019
c9c73d8
load pdb
mayankbansal018 Mar 13, 2019
fde4e3a
zzz
mayankbansal018 Mar 13, 2019
5c02e37
zzzz
mayankbansal018 Mar 13, 2019
4e02353
check if pdb exists
mayankbansal018 Mar 13, 2019
0ad9baf
read
mayankbansal018 Mar 13, 2019
2d24c36
zzzz
mayankbansal018 Mar 13, 2019
5fad3af
check file exists
mayankbansal018 Mar 13, 2019
a20bc65
zzzz
mayankbansal018 Mar 13, 2019
c0ba3a1
compute blocks
mayankbansal018 Mar 13, 2019
306c45b
nit
mayankbansal018 Mar 13, 2019
a95147b
print wchar
mayankbansal018 Mar 13, 2019
5d822c9
zzz
mayankbansal018 Mar 13, 2019
fb60281
fixes
mayankbansal018 Mar 20, 2019
1aae300
namespace
mayankbansal018 Mar 20, 2019
c6fdb20
fix
mayankbansal018 Mar 20, 2019
36b4812
fix2
mayankbansal018 Mar 20, 2019
8d4ff0e
fix
mayankbansal018 Mar 20, 2019
53c2727
ref
mayankbansal018 Mar 20, 2019
fd3ff57
fix
mayankbansal018 Mar 20, 2019
07a67cf
zzz
mayankbansal018 Mar 20, 2019
c810914
instrument
mayankbansal018 Mar 23, 2019
f2020a6
fix
mayankbansal018 Mar 23, 2019
d80fdfe
fix
mayankbansal018 Mar 23, 2019
c8224cc
fix
mayankbansal018 Mar 23, 2019
aba5b05
headers
mayankbansal018 Mar 23, 2019
15dbd38
zzz
mayankbansal018 Mar 23, 2019
a4fb7dd
zzz
mayankbansal018 Mar 23, 2019
c7c0d90
zzz
mayankbansal018 Mar 23, 2019
f30a492
on method instr
mayankbansal018 Mar 23, 2019
d4300d7
minor
mayankbansal018 Mar 23, 2019
1062030
instrumnet
mayankbansal018 Mar 23, 2019
bf344e0
fixx
mayankbansal018 Mar 23, 2019
8f851cf
minor
mayankbansal018 Mar 23, 2019
887946c
fix
mayankbansal018 Mar 23, 2019
8a071c2
zzz
mayankbansal018 Mar 23, 2019
1696e37
fix
mayankbansal018 Mar 29, 2019
2205029
instr
mayankbansal018 Mar 31, 2019
28272af
fix
mayankbansal018 Mar 31, 2019
0618259
fix
mayankbansal018 Mar 31, 2019
5824e72
global data
mayankbansal018 Mar 31, 2019
6c2b2f9
imp
mayankbansal018 Mar 31, 2019
d790bef
fix
mayankbansal018 Apr 1, 2019
482a09c
instr module level
mayankbansal018 Apr 1, 2019
c04f868
errors
mayankbansal018 Apr 1, 2019
7e2827f
fixes
mayankbansal018 Apr 1, 2019
979b624
idiot
mayankbansal018 Apr 1, 2019
3070c81
remove
mayankbansal018 Apr 1, 2019
cfd1995
instr
mayankbansal018 Apr 2, 2019
fae3edf
fix
mayankbansal018 Apr 2, 2019
e1a856e
copy this
mayankbansal018 Apr 5, 2019
6b59abb
Merge branch 'develop' into dev/maban/vanguard
Apr 17, 2020
a1dcb89
CHanges
Apr 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
667 changes: 667 additions & 0 deletions SeafoodInstrumentation/InstrumentationMethod.cpp

Large diffs are not rendered by default.

17 changes: 6 additions & 11 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,10 @@ macro (build_init build_language build_type)
# add_definitions(-D_DEBUG) TODO: Enable this
endif ()

if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
message("Detected Linux x86_64")
add_definitions(-DLINUX64)
add_definitions(-D_M_AMD64)
add_definitions(-DTARGET_AMD64)
else (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
message(FATAL_ERROR "error: Detected non x86_64 target processor. Not supported!")
endif(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
message("Detected Linux x86_64")
add_definitions(-DLINUX64)
add_definitions(-D_M_AMD64)
add_definitions(-DTARGET_AMD64)

# Ignored warnings
# TODO: Reenable these
Expand Down Expand Up @@ -242,9 +238,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux)
endif(CMAKE_SYSTEM_NAME STREQUAL Linux)

# Set flag to indicate if this will be a 64bit Linux build
if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
set(IS_64BIT_BUILD 1)
endif (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
set(IS_64BIT_BUILD 1)

# Ensure that on MacOS, dylibs are referenced as '@rpath/example.dylib' instead of just 'example.dylib'. Otherwise they
# will not be found unless the working directory == vsdbg directory.
Expand Down Expand Up @@ -342,4 +336,5 @@ add_subdirectory(unix/src/atl)
add_subdirectory(InstrumentationEngine.Api)
add_subdirectory(InstrumentationEngine.Lib)
add_subdirectory(InstrumentationEngine)
add_subdirectory(LinuxProfiler)

81 changes: 81 additions & 0 deletions src/LinuxProfiler/CComPtr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#pragma once

template<class TInterface>
class CComPtr
{
private:
TInterface* pointer;
public:
CComPtr(const CComPtr&) = delete; // Copy constructor
CComPtr& operator= (const CComPtr&) = delete; // Copy assignment
CComPtr(CComPtr&&) = delete; // Move constructor
CComPtr& operator= (CComPtr&&) = delete; // Move assignment

void* operator new(std::size_t) = delete;
void* operator new[](std::size_t) = delete;

void operator delete(void *ptr) = delete;
void operator delete[](void *ptr) = delete;

CComPtr()
{
this->pointer = nullptr;
}

~CComPtr()
{
if (this->pointer)
{
this->pointer->Release();
this->pointer = nullptr;
}
}

operator TInterface*()
{
return this->pointer;
}

operator TInterface*() const
{
return this->pointer;
}

TInterface& operator *()
{
return *this->pointer;
}

TInterface& operator *() const
{
return *this->pointer;
}

TInterface** operator&()
{
return &this->pointer;
}

TInterface** operator&() const
{
return &this->pointer;
}

TInterface* operator->()
{
return this->pointer;
}

TInterface* operator->() const
{
return this->pointer;
}

void Release()
{
this->~CComPtr();
}
};
274 changes: 274 additions & 0 deletions src/LinuxProfiler/CExtensionsHost.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
#include "stdafx.h"
#include <unistd.h>
#include "CExtensionsHost.h"

using namespace vanguard::instrumentation::managed;

static vector<string> globalMethodCol;

HRESULT ExtensionsHostCrossPlat::CExtensionHost::Initialize(
_In_ IProfilerManager* pProfilerManager
)
{
usleep(5*1000);
CComPtr<ICorProfilerInfo> pCorProfilerInfo;
pProfilerManager->GetCorProfilerInfo((IUnknown**)&pCorProfilerInfo);
pCorProfilerInfo->SetEventMask(COR_PRF_MONITOR_EXCEPTIONS | COR_PRF_ENABLE_STACK_SNAPSHOT);
return S_OK;
}

HRESULT ExtensionsHostCrossPlat::CExtensionHost::InstrumentMethod(_In_ IMethodInfo* pMethodInfo, _In_ BOOL isRejit)
{
/*CComBSTR bstrMethodName;
pMethodInfo->GetFullName(&bstrMethodName);

tstringstream methodName;
methodName << (LPWSTR)bstrMethodName;

tstring methodNameWStr = methodName.str();
string methodNameStr(methodNameWStr.begin(), methodNameWStr.end());

bool instrument = false;

for (size_t i = 0; i < globalMethodCol.size(); i++)
{
if (methodNameStr.compare(globalMethodCol[i]) == 0)
{
instrument = true;
break;
}
}

if (!instrument)
{
return S_OK;
}

BYTE pSignature[256] = {};
DWORD cbSignature = 0;
pMethodInfo->GetCorSignature(_countof(pSignature), pSignature, &cbSignature);

if (cbSignature < 2)
return S_FALSE;
USHORT argsCount = pSignature[1];*/

CComPtr<IModuleInfo> pModuleInfo;
pMethodInfo->GetModuleInfo(&pModuleInfo);

ModuleID modId;
pModuleInfo->GetModuleID(&modId);

module_info *instrumented_module = NULL;

unordered_map<ModuleID, module_info*>::iterator it = _instrumented_modules.find(modId);
if (it != _instrumented_modules.end())
{
mdToken token;
pMethodInfo->GetMethodToken(&token);
instrumented_module = it->second;
}

mdMethodDef token;
pMethodInfo->GetMethodToken(&token);

method_info info;
bool result = instrumented_module->get_method_info(token, info);

if (!result)
{
return S_OK;
}

auto block_indices = info.get_block_indexes();
auto start_index = info.get_start_index();
void const *coverage_buffer = instrumented_module->get_coverage_buffer();

CComPtr<IInstructionFactory> sptrInstructionFactory;
HRESULT hr = (pMethodInfo->GetInstructionFactory(&sptrInstructionFactory));
IfFailRet(hr);

CComPtr<IInstructionGraph> sptrInstructionGraph;
hr = (pMethodInfo->GetInstructions(&sptrInstructionGraph));
IfFailRet(hr);

CComPtr<IInstruction> sptrCurrent;
hr = (sptrInstructionGraph->GetFirstInstruction(&sptrCurrent));
IfFailRet(hr);

auto index = reinterpret_cast<__int64>(coverage_buffer);
index = index + info.get_start_index();

CComPtr<IInstruction> operandInstr;
hr = (sptrInstructionFactory->CreateLongOperandInstruction(Cee_Ldc_I8, index, &operandInstr));
IfFailRet(hr);
hr = (sptrInstructionGraph->InsertBeforeAndRetargetOffsets(sptrCurrent, operandInstr));
IfFailRet(hr);

CComPtr<IInstruction> pushInstr;
hr = (sptrInstructionFactory->CreateInstruction(Cee_Ldc_I4_1, &pushInstr));
IfFailRet(hr);
hr = (sptrInstructionGraph->InsertBefore(sptrCurrent, pushInstr));
IfFailRet(hr);

CComPtr<IInstruction> commitInstr;
hr = (sptrInstructionFactory->CreateInstruction(Cee_Stind_I1, &commitInstr));
IfFailRet(hr);
hr = (sptrInstructionGraph->InsertBefore(sptrCurrent, commitInstr));
IfFailRet(hr);

return hr;
}

HRESULT ExtensionsHostCrossPlat::CExtensionHost::OnShutdown()
{
return S_OK;
}

HRESULT ExtensionsHostCrossPlat::CExtensionHost::ShouldInstrumentMethod(_In_ IMethodInfo* pMethodInfo, _In_ BOOL isRejit, _Out_ BOOL* pbInstrument)
{
/*CComBSTR bstrMethodName;
pMethodInfo->GetFullName(&bstrMethodName);

tstringstream methodName;
methodName << (LPWSTR)bstrMethodName;

tstring methodNameWStr = methodName.str();
string methodNameStr(methodNameWStr.begin(), methodNameWStr.end());


for (size_t i = 0; i < globalMethodCol.size(); i++)
{
if (methodNameStr.compare(globalMethodCol[i]) == 0)
{
*pbInstrument = TRUE;
break;
}
}*/

CComPtr<IModuleInfo> pModuleInfo;
pMethodInfo->GetModuleInfo(&pModuleInfo);

ModuleID modId;
pModuleInfo->GetModuleID(&modId);

unordered_map<ModuleID, module_info*>::iterator it = _instrumented_modules.find(modId);
if (it != _instrumented_modules.end())
{
mdToken token;
pMethodInfo->GetMethodToken(&token);
module_info *info = it->second;
*pbInstrument = info->contains_instrumented_method(token);
}

return S_OK;
}

HRESULT ExtensionsHostCrossPlat::CExtensionHost::OnModuleLoaded(IModuleInfo* pModuleInfo)
{
HRESULT hr = S_OK;

CComBSTR bstrModuleName;
IfFailRet(pModuleInfo->GetModuleName(&bstrModuleName));

CComBSTR bstrModulePath;
IfFailRet(pModuleInfo->GetFullPath(&bstrModulePath));

tstringstream dllPath;
dllPath << (LPWSTR)bstrModulePath;

tstring pdbPath = dllPath.str();
pdbPath = pdbPath.substr(0, pdbPath.find_last_of(_T('.'))) + _T(".pdb");

string filePathChar(pdbPath.begin(), pdbPath.end());

tstringstream pathBuilder;
pathBuilder <<_T("/home/maban/projects/XPlatPdbReader/bin/x64/Debug/libXPlatPdbReader.so");

if (m_hmod == NULL)
{
m_hmod = ::LoadLibrary(pathBuilder.str().c_str());
}

if (m_hmod == NULL)
{
auto error = ::GetLastError();
// Failed to load the module.
return HRESULT_FROM_WIN32(error);
}

typedef int(__stdcall* ReadPDB)(const char* path);

ReadPDB pfnReadPdb = (ReadPDB)GetProcAddress(m_hmod, "ReadPDB");
if (!pfnReadPdb)
{
auto error = ::GetLastError();
FreeLibrary(m_hmod);
return HRESULT_FROM_WIN32(error);
}

int methodCount = 0;
methodCount = pfnReadPdb(filePathChar.c_str());

const mdMethodDef baseToken = 0x06 << 24;
mdMethodDef methodDef = 1;
HRESULT methodInfoResult = S_OK;
vector<IMethodInfo*> methodInfoCollection;

il_disassembler disassembler(pModuleInfo);

while (methodCount)
{
IMethodInfo* methodInfo = NULL;
CComBSTR bstrMethodName;

mdMethodDef token = baseToken | methodDef;
methodInfoResult = pModuleInfo->GetMethodInfoByToken(token, &methodInfo);
methodInfoCollection.push_back(methodInfo);
methodDef++;
methodCount--;
methodInfo->GetFullName(&bstrMethodName);

//printf("Method Name: %ls \n ", bstrMethodName);
vanguard::instrumentation::managed::function* func = new vanguard::instrumentation::managed::function();
func->set_token(token);

disassembler.initialize_function(methodInfo, func);
disassembler.disassemble_function();

struct function_releaser
{
function_releaser(il_disassembler& d) :
_disassembler(d)
{
}

~function_releaser() { _disassembler.cleanup_function(); }

private:
il_disassembler& _disassembler;
} releaser(disassembler);

func->calculate_blocks(disassembler);

if (func->get_block_count() > 0)
{
tstringstream methodName;
methodName << (LPWSTR)bstrMethodName;

tstring methodNameWStr = methodName.str();
string methodNameStr(methodNameWStr.begin(), methodNameWStr.end());
globalMethodCol.push_back(methodNameStr);
disassembler.instrument_function();
}
}

ModuleID modId;
pModuleInfo->GetModuleID(&modId);

module_info* info = disassembler.get_module_info();
info->set_block_count(disassembler.get_global_block_count());

_instrumented_modules.insert(make_pair(modId, info));

return hr;
}
Loading