1

I'm using .NET profiling api to instrument my .NETCore application running on Linux. I need to find all the assemblies loaded in my application.

I've enabled the flag COR_PRF_MONITOR_ASSEMBLY_LOADS to receive notifications when assemblies are loaded into the Common Language Runtime.

Below is my code to get the Assembly name. It works as expected in windows machine. But when I run the same in Linux environment it is not giving the correct assembly name. On linux I'm getting the assembly name something like this "Sse.igotc.rcn.Lgigule����"

From my search I found that this can be character encoding issue. I even set encoding std::setlocale(LC_ALL, ""); in my code. But still no luck.

bool CAssemblyManager::Initialize(AssemblyID assemblyId)
{
    ULONG nameLength = 0;
    _corProfilerInfo2->GetAssemblyInfo(assemblyId, 0, &nameLength, 0, 0, 0);
    wchar_t* nameBuffer = new wchar_t[nameLength];
    _corProfilerInfo2->GetAssemblyInfo(assemblyId, nameLength, 0, nameBuffer, 0, 0);
        delete[] nameBuffer;
    return true;
}

I also tried to convert the wchar_t* string to a std::string encoded in UTF-8 using std::wstring_convert. But it is also not working

    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    converter.to_bytes(nameBuffer);
    std::cout << converter.to_bytes(nameBuffer) << std::endl;

What could be the issue. If it is encoding issue Am I missing something? Or is it an issue with .NET Profiling API method ("GetAssemblyInfo()"). As I said earlier it happens only in Linux.

1 Answer 1

0

You might be facing this issue because of the character encoding. you could try this below code:

#include <iostream>
#include <codecvt>
#include <locale>
#include <cstring>

bool CAssemblyManager::Initialize(AssemblyID assemblyId)
{
    ULONG nameLength = 0;
    HRESULT hr = _corProfilerInfo2->GetAssemblyInfo(assemblyId, 0, &nameLength, nullptr, nullptr, nullptr);
    if (FAILED(hr))
    {
        std::cerr << "Failed to get assembly info size: " << hr << std::endl;
        return false;
    }

    wchar_t* nameBuffer = new wchar_t[nameLength];
    hr = _corProfilerInfo2->GetAssemblyInfo(assemblyId, nameLength, nullptr, nameBuffer, nullptr, nullptr);
    if (FAILED(hr))
    {
        std::cerr << "Failed to get assembly info: " << hr << std::endl;
        delete[] nameBuffer;
        return false;
    }

    std::wcout << L"Assembly name (wide): " << nameBuffer << std::endl;

    try
    {
        std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
        std::string utf8Name = converter.to_bytes(nameBuffer);
        std::cout << "Assembly name (UTF-8): " << utf8Name << std::endl;
    }
    catch (const std::range_error& e)
    {
        std::cerr << "Conversion error: " << e.what() << std::endl;
    }

    delete[] nameBuffer;
    return true;
}

make sure you have set the locale as below:

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @Jalpa. l I tried it. But still same issue. hr = _corProfilerInfo2->GetAssemblyInfo(assemblyId, nameLength, nullptr, nameBuffer, nullptr, nullptr); This line cause the error error: cannot initialize a parameter of type 'WCHAR *' (aka 'char16_t *') with an lvalue of type 'wchar_t *' So I change it to hr = _corProfilerInfo2->GetAssemblyInfo(assemblyId, nameLength, nullptr, reinterpret_cast<WCHAR*>(nameBuffer), nullptr, nullptr);. But conversion is not happening. Getting the below error Conversion error: wstring_convert::to_bytes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.