繁体   English   中英

来自LLVM绑定的不平衡堆栈警告

[英]Unbalanced stack warnings from LLVM bindings

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

在此输入图像描述

现在,在使用我的Windows 7上网本时,我收到了每个PInvoke调用的警告,但是在使用我的Windows Vista桌面时,我只获得了一些调用。

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

请注意,这两台机器完全是32位x86。

编辑

人们正在发表评论,要求重新编写。 重现此问题的最简单方法是按照我在此处记录的说明安装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仍将始终在调试项目时使用它。 更糟糕的是,严格检查仅在x86版本的.NET 4.0中默认启用,而不是x64版本,因此在64位计算机上运行良好的程序集可能会在32位计算机上崩溃。

MSDN有关于pInvokeStackImbalance MDA的更多信息, 此博客文章还提供了有关在调试过程中问题突然显现的更多详细信息。

编辑:我刚刚注意到您编辑了您的问题以包含代码示例。 这种情况证实了我对PInvoke签名略有错误的怀疑。 如果您将签名从extern void *moduleCreateWithNameNative(string ModuleID)更改为extern LLVMModuleRef* moduleCreateWithNameNative(string ModuleID)什么?

看起来这里有一个编译器错误--F#不应该允许你定义一个名为*moduleCreateWithNameNative的方法。 我猜它是允许的(无论出于何种原因),因此函数的返回类型被编译为void - 当本机方法尝试返回一个值(指向LLVMModuleRef结构的指针)时,CLR会被绊倒和崩溃。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM