tdlib / td

Cross-platform library for building Telegram clients
https://core.telegram.org/tdlib
Boost Software License 1.0
7.07k stars 1.44k forks source link

Does not work for .NET Core and .NET Framework on MS Visual Studio 2019 #1038

Closed mrbus closed 3 years ago

mrbus commented 4 years ago

I successfully built Telegram.Td.dll with -DTD_ENABLE_DOTNET=ON and added a reference to it in my project. But I get different runtime errors depending on target framework and project type.

Console App .NET Core 3.1:

using System;
using Td = Telegram.Td;
using TdApi = Telegram.Td.Api;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // disable TDLib log
            Td.Client.Execute(new TdApi.SetLogVerbosityLevel(0));
            if (Td.Client.Execute(new TdApi.SetLogStream(new TdApi.LogStreamFile("tdlib.log", 1 << 27))) is TdApi.Error)
            {
                throw new System.IO.IOException("Write access to the current directory is required");
            }
            Console.WriteLine("Hello World!");
        }
    }
}

Gives System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'

Console App .NET Framework 4, with the same code: gives no errors, but nothing happens (no "Hello World!" message). And constantly consumes one processor core. If I put a breakpoint on the first line of Main, it is never reached.

Windows Forms .NET Framework 4.7.2 (also tried .NET Framework 4): I created a form, put a button on it and wrote a click handler:

        private void button1_Click(object sender, EventArgs e)
        {
            // disable TDLib log
            Td.Client.Execute(new TdApi.SetLogVerbosityLevel(0));
            if (Td.Client.Execute(new TdApi.SetLogStream(new TdApi.LogStreamFile("tdlib.log", 1 << 27))) is TdApi.Error)
            {
                throw new System.IO.IOException("Write access to the current directory is required");
            }
            MessageBox.Show("Hello");
        }

It gives "Managed Debugging Assistant 'LoaderLock' has detected a problem" when I press the button at runtime. If I change Exception Settings (Exception settings - Managed Debugging Assistants - uncheck "LoaderLock") then I get another error: "Managed Debugging Assistant 'FatalExecutionEngineError' has detected a problem". Debug Options - check "Use Managed Compatibility Mode" - didn't help.

Perhaps it is related to this? https://docs.microsoft.com/en-us/cpp/dotnet/initialization-of-mixed-assemblies?redirectedfrom=MSDN&view=vs-2019

levlam commented 4 years ago

Have you tried to use and extend our C# example https://github.com/tdlib/td/tree/master/example/csharp?

mrbus commented 4 years ago

Yes just now I tried it. Project (x64) builds and runs, but the same thing happens as with Console App .NET Framework 4: no output, one processor core consumed, and breakpoint at 'Main' never reached. I will try to build Telegram.Td.dll x86.

levlam commented 4 years ago

TDLib has no custom DllMain, doesn't change global locale and shouldn't call managed code from unmanaged.

Could you add

#pragma managed(push, off)
...
#pragma managed(pop)

around https://github.com/tdlib/td/blob/f2cb3afaef62f2dba2a0dc3dc63e374beabcb2df/td/telegram/ClientDotNet.cpp#L7 https://github.com/tdlib/td/blob/f2cb3afaef62f2dba2a0dc3dc63e374beabcb2df/td/telegram/LogDotNet.cpp#L7 https://github.com/tdlib/td/blob/f2cb3afaef62f2dba2a0dc3dc63e374beabcb2df/td/tl/tl_dotnet_object.h#L11-L12 https://github.com/tdlib/td/blob/f2cb3afaef62f2dba2a0dc3dc63e374beabcb2df/tdutils/td/utils/port/CxCli.h#L9-L11 https://github.com/tdlib/td/blob/f2cb3afaef62f2dba2a0dc3dc63e374beabcb2df/tdutils/td/utils/port/CxCli.h#L15 https://github.com/tdlib/td/blob/f2cb3afaef62f2dba2a0dc3dc63e374beabcb2df/tdutils/td/utils/port/CxCli.h#L19-L21

and check whether the deadlock has gone after TDLib is rebuilt with these changes?

mrbus commented 4 years ago

Unfortunately rebuilding TDLib x64 Release, TDLib x64 Debug with these changes had no effect.

levlam commented 4 years ago

Could you try to find the exact cause of the deadlock following instructions from https://docs.microsoft.com/en-us/cpp/dotnet/initialization-of-mixed-assemblies?view=vs-2019#how-to-debug-loader-lock-issues?

mrbus commented 4 years ago

I could not follow all the instructions. It seems that instructions are outdated and do not work for Visual Studio 2019 (i.e. ".load sos.dll" does not work, there is no "Configuration Properties" window, etc.) I created simple C++ project which tries to load Telegram.Td.dll:

#include <iostream>
#include <Windows.h>

int main()
{
    HANDLE hlib = LoadLibrary("Telegram.Td.dll");
    DWORD err = GetLastError();
    std::cout << "hlib = " << hlib << ", err = " << err;
}

It prints hlib = 0, err = 193 (0x000000C1) (bad exe format). Loading tdjson.dll the same way was successful. libcrypto-1_1-x64.dll, libssl-1_1-x64.dll, zlibd1.dll - all of them were put in the project folder. Under the assumption that the problem is the absence of some dependencies I used Dependency Walker and Process Monitor and I found that it tries to load these files: api-ms-win-core-fibers-l1-1-1.DLL api-ms-win-core-localization-l1-2-1.DLL api-ms-win-core-datetime-l1-1-1.DLL api-ms-win-core-localization-obsolete-l1-2-0.DLL api-ms-win-appmodel-runtime-l1-1-2.DLL that are missing on my system. BUT: tdjson.dll also tries to load them and is loaded successfully. Process Monitor logs attached. PMLogs.zip

mrbus commented 4 years ago

I found out that example works for Windows Server 2012 R2, Windows 10. Doesn't work for Windows 7.

levlam commented 4 years ago

api-ms-win-* aren't in fact missing. Instead Dependency Walker is outdated and can't locate them.

levlam commented 4 years ago

I don't know where I can get Windows 7 for testing, given it reached end of support already. There is also a big chance that it would work for me.

isopen commented 4 years ago

@levlam Windows 7 + virtualbox

@mrbus mr_makss 7 years ago switched to Windows 10 and all is well.

levlam commented 3 years ago

@mrbus Could you try to check whether C# example works for you in the latest TDLib 1.7.0?

mrbus commented 3 years ago

@levlam I switched to Python and used other libraries. And eventually I changed my OS to Windows 10, so this issue is not actual for me now, and I can't test TDLib 1.7.0 on Windows 7. Sorry for not reporting this earlier.

levlam commented 3 years ago

@mrbus Thanks. Then this can be closed for now.