Cannot find bounds of current function


MinGW編譯平台的應用程序使用libcef.dll,當調用cef的capi接口時程序崩潰。調試單步到cef capi函數時,調試器報錯“Cannot find bounds of current function”。

解決問題的思路在https://stackoverflow.com/questions/8741493/why-i-do-get-cannot-find-bound-of-current-function-when-i-overwrite-the-ret-ad

 

在windows平台需要使用嵌入瀏覽器cef,同時要使用c++11,又不想安裝龐大的VS開發環境。選用了codeblocks-17.12mingw-nosetup作為開婦環境,壓縮包不到100MB,MinGW gcc為2015年的5.1.0版本。支持同等c++11特性的vc編譯器,應該是VS2015,即使是express版也有5G龐大。

http://opensource.spotify.com/cefbuilds/index.html#windows32_builds找到最低版本的libcef.3.2704.1414,體積約50M。筆者在其它軟件找到體積更小,只有40M的libcef.dll.3.2171。如果不迷戀c++wrapper的話,下載后的cefbuild直接可以使用capi。如果已經習慣了<<inside c++ object model>>的思維和c面向對象的思維,就明白其實cef的capi已經經過面向對象思想設計。

有了開發環境codeblocks+MinGw,現成的庫文件libcef.dll.3.2171,還有接口頭文件libcef.3.2704.1414.zip。只要將win32的庫文件轉換成MinGw的鏈接庫就可以使用。自然就是使用MinGw的工具導出def,然后導出.a庫文件。

經過一番適配調整配置后,程序編譯鏈接成功,但是運行失敗了, 調試時gcc在運行cef capi處報錯"Cannot find bounds of current function"。

這個錯誤並非沒有加載到庫文件,或者是沒有加載到函數,而是函數邊界問題。在stackoverflow有post討論回答“It overwrites the current stack frame of your function with irrelevant data, and destroys the return address in the process, which is normally stored there among other things”。就是函數調用的棧幀被破壞。這事情在win平台開發比較常見, stdcall與cdecl,callee和caller誰負責平衡堆棧的問題,不一致時使得棧幀被破壞。WINAPI以及CALLBACK就是stdcall。而cef項目卻有這么一個CEF_CALLBACK對win操作平台下的回調約定,自然就是stdcall。早期cef項目(這里指本文采用的3.27xx於2016年)不考慮對MinGW支持,預編譯只有兩大平台的分支COMPILER_MSVC與COMPLIER_GCC,詭異的就是MinGW是在WINOS上的GCC,所有十分尷尬。最新版的cef將CEF_CALLBACK的定義單獨放置在一個預編譯分支OS_WIN。

CEF_CALLBACK的定義在internal/cef_export.h。下面兩個版本的文件對照:

3.2704.1414

#if defined(COMPILER_MSVC)

#ifdef BUILDING_CEF_SHARED
#define CEF_EXPORT __declspec(dllexport)
#elif USING_CEF_SHARED
#define CEF_EXPORT __declspec(dllimport)
#else
#define CEF_EXPORT
#endif
#define CEF_CALLBACK __stdcall

#elif defined(COMPILER_GCC)

#define CEF_EXPORT __attribute__ ((visibility("default")))
#define CEF_CALLBACK

#endif  // COMPILER_GCC

#endif  // CEF_INCLUDE_INTERNAL_CEF_EXPORT_H_

78.3.9

#if defined(COMPILER_MSVC)

#ifdef BUILDING_CEF_SHARED
#define CEF_EXPORT __declspec(dllexport)
#elif USING_CEF_SHARED
#define CEF_EXPORT __declspec(dllimport)
#else
#define CEF_EXPORT
#endif

#elif defined(COMPILER_GCC)

#define CEF_EXPORT __attribute__((visibility("default")))

#endif  // COMPILER_GCC

#if defined(OS_WIN)
#define CEF_CALLBACK __stdcall
#else
#define CEF_CALLBACK
#endif

問題迎刃而解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM