编程语言
首页 > 编程语言> > c#-LLVM绑定中的不平衡堆栈警告

c#-LLVM绑定中的不平衡堆栈警告

作者:互联网

经过数周的努力,我设法编写了使用LLVM进行JIT编译的F#程序.但是,每当我在附有调试器的Visual Studio 2010中运行程序时(即通过按F5键),都会收到以下警告:

现在,在使用Windows 7上网本时,对于每个PInvoke调用都会收到此警告,但在使用Windows Vista桌面时,仅对某些调用会得到警告.

遇到此问题的其他人似乎已通过向请求ANSI字符串或CDecl调用约定的PInvoke调用添加属性来解决了该问题.我发现更改调用约定可以修复Windows Vista桌面上的警告,但是没有可用的调用约定(或ANSI格式字符串)可以修复Windows 7上网本上的警告.任何想法如何解决这一问题?

请注意,两台机器都是32位x86.

编辑

人们发布评论要求维修代表.重现此问题的最简单方法是按照我记录的here的说明安装LLVM和llvm-fs并运行给出的任何示例程序.他们在我的上网本上对LLVM的所有呼叫中都出现了此问题.

或者,以下代码(源自llvm-fs)应再现该问题,而无需llvm-fs:

open System.Runtime.InteropServices

[<DllImport("LLVM-3.0.dll",
            EntryPoint="LLVMModuleCreateWithName",
            CharSet=CharSet.Ansi,
            CallingConvention=CallingConvention.Cdecl)>]
extern void *moduleCreateWithNameNative(string ModuleID)

let mdl = moduleCreateWithNameNative "foo"

请注意,原始C头文件中的相应定义是:

typedef struct LLVMOpaqueModule *LLVMModuleRef;
...
LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID);

解决方法:

您是否以.NET 4.0或更早版本为目标?

我问的原因是CLR具有安全性/稳定性功能,可以对Pinvoke签名进行超严格检查.自.NET 2.0以来一直存在,但默认情况下处于禁用状态,直到.NET 4.0.

行为上的转换导致许多开发人员报告与您相同的问题.它们的绑定在.NET 2.0 / 3.5上工作得很好,但是为.NET 4.0编译时开始抛出错误.实际上,问题在于,早期版本的.NET允许轻微的PInvoke签名正常工作;现在默认情况下已进行严格检查,这些错误开始出现.

要注意的另一件事是,即使您更改计算机上的配置以禁用.NET 4.0中的此行为,Visual Studio仍将在调试项目时始终使用它.更糟糕的是,严格检查仅在默认情况下在.NET 4.0的x86版本中启用,而不在x64版本中启用,因此,在64位计算机上正常工作的程序集可能在32位计算机上崩溃.

MSDN上提供了有关pInvokeStackImbalance MDAthis blog post的更多信息,还提供了有关在调试过程中为什么出现问题的更多详细信息.

编辑:我刚刚注意到您编辑了您的问题,以包括一个代码示例.这种确认证实了我对PInvoke签名略有错误的怀疑.如果将签名从extern void * moduleCreateWithNameNative(string ModuleID)更改为extern LLVMModuleRef * moduleCreateWithNameNative(string ModuleID)会发生什么?

似乎这里还有一个编译器错误在起作用-F#不允许您定义一个名为* moduleCreateWithNameNative的方法.我猜它是允许的(出于某种原因),因此您的函数的返回类型被编译为void,并且当本机方法尝试返回值(指向LLVMModuleRef结构的指针)时,CLR跳闸了并崩溃.

标签:f,llvm,c,pinvoke,llvm-fs
来源: https://codeday.me/bug/20191101/1984938.html