簡體   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