【问题标题】:Managed code in a hosted .NET Core runtime corrupts the caller stack托管 .NET Core 运行时中的托管代码会损坏调用程序堆栈
【发布时间】:2019-10-06 20:51:54
【问题描述】:

我正在玩.NET Core runtime hosting example

当我在 Windows 上“按原样”(64 位)构建它时,它可以工作。

当我将其构建为 32 位应用程序(在 Windows 上)并将 .NET 运行时更改为 x86 (-r win-x86) 时,它崩溃了。

这就是正在发生的事情。 managedDelegate 返回后,调用者 (main()) 的堆栈损坏,应用崩溃。

doWork_ptr managedDelegate;

createManagedDelegate(
        hostHandle,
        domainId,
        "ManagedLibrary, Version=1.0.0.0",
        "ManagedLibrary.ManagedWorker",
        "DoWork",
        (void**)&managedDelegate);

char* ret = managedDelegate("Test job", 5, sizeof(data) / sizeof(double), data, ReportProgressCallback);

当我将托管方法 (DoWork) 更改为 void-返回一个不带任何参数的方法时,它可以工作。

我似乎遗漏了一些关于调用约定的内容,但无法确定具体是什么。 Windows 上的默认值为 stdcall,但 x86 和 x64 之间也存在一些差异。 x64 使用特殊的x64 fastcall 约定,我怀疑在 32 位应用程序中托管 .NET CLR 时它会以某种方式搞砸整个事情。

我需要进行哪些更改才能使其运行?我是否需要使用特定的调用约定来构建本机(主机)应用程序?我需要用特殊属性装饰托管方法吗?或者也许以某种方式配置托管的 .NET Core 运行时?

【问题讨论】:

  • 是的,他们在该示例上偷工减料,显然打算将其仅用于 x64 运行时。这对于 .NETCore 来说很正常,为什么他们决定支持 x86 有点神秘。可能需要太多工作才能删除它。函数指针的声明很关键,对于 x86,你可以处理incompatible calling conventions。 x64 中的 cdecl 和 stdcall 没有区别。需要更多宏汤,Windows 声明将是 typedef int (__stdcall *report_callback_ptr)(int progress); 等。
  • @HansPassant 那里还有 32 位机器,例如宏碁 Aspire Switch 10
  • 我会通过的,他们在这里射击信使,我真的不知道他们为什么要这样编码样本。只需分享您在自己的帖子中发现的内容并将其标记为答案即可。

标签: c# .net .net-core stack-corruption .net-runtime


【解决方案1】:

正如@HansPassant 在 cmets 中提到的:

函数指针的声明很关键,对于 x86,您需要处理不兼容的调用约定。 x64 中cdeclstdcall 之间没有区别。需要更多宏汤,Windows 声明将是typedef int (__stdcall *report_callback_ptr)(int progress); 等。

这就是诀窍。

回调和托管方法函数指针需要额外装饰__stdcall属性:

typedef int (__stdcall *report_callback_ptr)(int progress);
typedef char* (__stdcall *doWork_ptr)(const char* jobName, int iterations, int dataSize, double* data, report_callback_ptr callbackFunction);

回调实现也需要修饰:

int __stdcall ReportProgressCallback(int progress) { /* implementation here */ }

事实证明,托管封送拆收器在 x86 上将托管方法视为 __stdcall,这并不奇怪。

应用这些更改会使示例在构建为托管 x86 .NET Core 运行时的 x86 应用时工作。

【讨论】:

    猜你喜欢
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 2010-09-20
    相关资源
    最近更新 更多