【问题标题】:Lua module created with SWIG and MinGW, cause the interpreter to crash on exit使用 SWIG 和 MinGW 创建的 Lua 模块,导致解释器在退出时崩溃
【发布时间】:2014-01-13 10:24:36
【问题描述】:

我有以下文件:

hello.h

#ifndef HELLO_H
#define HELLO_H

class Hello {
    private:
        int _number;

    public:
        Hello(int number);
        void printHello(void) const;
};

#endif

hello.cpp

#include "hello.h"
#include <iostream>

Hello::Hello(int number)
    : _number(number) {
}

void Hello::printHello(void) const {
    std::cout << "Hello, " << this->_number << std::endl;
}

hello.swg

%module hello
%{
    #include "hello.h"
%}
%include "hello.h"

CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
FIND_PACKAGE(Lua51)
INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIR})
ADD_LIBRARY(
    "hello"
    SHARED
    "hello_wrap.cxx"
    "hello.cpp"
)
TARGET_LINK_LIBRARIES(hello "${LUA_LIBRARIES}")
SET_TARGET_PROPERTIES(hello PROPERTIES PREFIX "")

我使用 SWIG 生成 hello_wrap.cxx,然后通过 CMake 创建 MinGW Makefile 并构建它们。这会产生 hello.dll。

打开lua解释器,我输入:

hello=require('hello')
inst=hello.Hello(23)
inst:printHello()

正如预期的那样,我希望它打印出“你好,23”,因此模块加载似乎正常工作。

但是,当我这样做时:

os.exit()

我收到以下错误:

"This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information."

随后 lua.exe 崩溃。当我简单地这样做时也会发生这种情况:

hello=require('hello')
os.exit()

有人对我如何解决这个问题有任何想法吗?

提前致谢。

编辑:以下是depends.exe通过lua.exe运行带有问题行的test.lua时产生的输出

***************************| Module Dependency Tree |***************************
*                                                                              *
* Legend: F  Forwarded Module   ?  Missing Module        6  64-bit Module      *
*         D  Delay Load Module  !  Invalid Module                              *
*         *  Dynamic Module     E  Import/Export Mismatch or Load Failure      *
*                               ^  Duplicate Module                            *
*                                                                              *
********************************************************************************

[   ] LUA.EXE
     [   ] KERNEL32.DLL
          [   ] API-MS-WIN-CORE-RTLSUPPORT-L1-1-0.DLL
          [   ] NTDLL.DLL
          [   ] KERNELBASE.DLL
               [ ^ ] NTDLL.DLL
          [   ] API-MS-WIN-CORE-PROCESSTHREADS-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-HEAP-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-MEMORY-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-HANDLE-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-SYNCH-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-FILE-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-IO-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-THREADPOOL-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-LIBRARYLOADER-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-NAMEDPIPE-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-MISC-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-SYSINFO-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-LOCALIZATION-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-PROCESSENVIRONMENT-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-STRING-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-DEBUG-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-ERRORHANDLING-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-FIBERS-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-UTIL-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-PROFILE-L1-1-0.DLL
          [   ] API-MS-WIN-SECURITY-BASE-L1-1-0.DLL
          [F^ ] NTDLL.DLL
     [   ] MSVCRT.DLL
          [ ^ ] KERNELBASE.DLL
          [ ^ ] NTDLL.DLL
          [   ] API-MS-WIN-CORE-CONSOLE-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-DATETIME-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-DEBUG-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-ERRORHANDLING-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-FIBERS-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-FILE-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-HANDLE-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-HEAP-L1-1-0.DLL
          [   ] API-MS-WIN-CORE-INTERLOCKED-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-LOCALIZATION-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-LIBRARYLOADER-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-MEMORY-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-MISC-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-NAMEDPIPE-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-PROCESSENVIRONMENT-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-PROCESSTHREADS-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-PROFILE-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-STRING-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-SYNCH-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-SYSINFO-L1-1-0.DLL
          [ ^ ] API-MS-WIN-CORE-UTIL-L1-1-0.DLL
     [ ^ ] MSVCRT.DLL
     [   ] LUA52.DLL
          [ ^ ] KERNEL32.DLL
               [F^ ] NTDLL.DLL
          [ ^ ] MSVCRT.DLL
          [*  ] HELLO.DLL
               [ ^ ] KERNEL32.DLL
                    [F^ ] NTDLL.DLL
               [ ^ ] MSVCRT.DLL
               [   ] LIBGCC_S_DW2-1.DLL
                    [ ^ ] KERNEL32.DLL
                         [F^ ] NTDLL.DLL
                    [ ^ ] MSVCRT.DLL
                    [*^ ] LIBGCC_S_DW2-1.DLL
               [   ] LIBSTDC++-6.DLL
                    [ ^ ] KERNEL32.DLL
                         [F^ ] NTDLL.DLL
                    [ ^ ] MSVCRT.DLL
                    [ ^ ] MSVCRT.DLL
                    [ ^ ] LIBGCC_S_DW2-1.DLL
                    [*^ ] LIBGCC_S_DW2-1.DLL
               [*^ ] LIBGCC_S_DW2-1.DLL
[*  ] SNXHK.DLL
     [ ^ ] KERNEL32.DLL
          [F^ ] NTDLL.DLL
     [*^ ] KERNEL32.DLL

编辑:添加了来自 'cmake -G "MinGW Makefiles"' 的输出和构建

cmake -G "MinGW Makefiles"

-- The C compiler identification is GNU 4.8.1
-- The CXX compiler identification is GNU 4.8.1
-- Check for working C compiler: C:/MinGW/bin/gcc.exe
-- Check for working C compiler: C:/MinGW/bin/gcc.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: C:/MinGW/bin/g++.exe
-- Check for working CXX compiler: C:/MinGW/bin/g++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found Lua51: C:/Users/forgottenmaster/Dropbox/lua/lua-5.2.3/src/liblua.a
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/forgottenmaster/Dropbox/lua/modules/c++

mingw32-make

Scanning dependencies of target hello
[ 50%] Building CXX object CMakeFiles/hello.dir/hello_wrap.cxx.obj
[100%] Building CXX object CMakeFiles/hello.dir/hello.cpp.obj
Linking CXX shared library hello.dll
[100%] Built target hello

【问题讨论】:

  • 你能在调试器中运行这个以便你可以捕获吗?
  • 如果您删除os.exit() 并用Ctrl-Z 替换它会怎样?如果您使用该组合键退出解释器,它仍然会崩溃吗?
  • 我找不到像样的 lua 调试器,我尝试 LuaEdit 进行调试,但它只是崩溃了,没有任何意义。使用 lua API 从 C++ 运行脚本,通过 gdb 在脚本退出时出现以下错误 “程序收到信号 SIGSEGV, Segmentation fault. 0x775ddfe4 in ntdll!RtlFreeHeap () from C:\Windows\system32\ntdll .dll”。另外,Ctrl+C组合退出lua解释器没有错误
  • 如果您在没有os.exit() 的情况下运行测试脚本,会出现段错误吗?我相信os.exit 只是在下面调用 abort 或终止,因此可能不会完成任何需要进行的清理。
  • lua.exe 链接到哪个 C 运行时?默认情况下,MinGW 将链接到MSVCRT.DLL,而不是任何较新的 Visual C 版本。 Lua for Windows 是(IIRC)链接到MSVCR80.DLL。混合 C 运行时将导致最终的痛苦,这通常是由于多个内存分配器与从一个版本的 malloc() 收到的指针传递给另一个版本的 free() 造成的混淆。查看正在发生的事情的最佳方法是使用DEPENDS.EXE 找出真正在使用的 DLL。

标签: c++ lua cmake mingw swig


【解决方案1】:

以下是一些可以尝试的方法:

  1. 你的 cmake 有 FIND_PACKAGE(Lua51) 这可能会导致 hello.dll 链接到 Lua 5.1,而你正在运行 Lua 5.2。

  2. 通过 Visual Studio 运行 lua test.lua。你可以通过几种方式做到这一点,其中之一是运行 lua test.lua 并让脚本暂停,等待输入;在等待输入时,您运行视觉工作室并附加到 lua 进程;然后在 lua 控制台中按回车键,脚本继续;您可能会知道故障发生在哪里(发布文件/行#)。

  3. 我怀疑问题出在系统 DLL 上,更有可能是使用不兼容的设置构建 hello.DLL,例如单线程而不是多线程。检查您链接到的 Lua 是否是 mingw 的,使用相同的编译器设置构建。 make 中最重要的信息是构建和链接的最终命令。检查制作 Lua 时的编译和构建命令是什么(可能为 make 设置了详细标志 - 您发布的内容仅显示 g++ 正在运行的状态消息,而不是提供给它的命令行参数,显示包含路径等),并找到如何使用 cmake 获取它们。

  4. 原则上,您应该能够复制 Lua makefile 并将列出 lua51.lib 等的几行替换为 hello.lib 和 co。

【讨论】:

  • 您好,感谢您的回复,我使用了 FIND_PACKAGE(Lua51),因为我拥有的 CMake 版本中没有 FindLua52.cmake 脚本。但是,从 cmake 给出的输出中可以看出,它似乎找到了 5.2 版本的库
  • 按照上述步骤(将 io.read() 调用添加到脚本,在 lua.exe 中运行脚本,将可视化 C++ 附加到进程)给出以下错误 未处理的异常在 0x77E2DFE4 (ntdll. dll)在lua.exe中:0xC0000005:访问冲突读取位置0x6241C41F。,我猜这是gdb抱怨的RtlFreeHeap函数。我正在尝试support.microsoft.com/kb/929833 的步骤,看看它是否作为损坏的 dll 出现
  • 是的,我使用 mingw32-make 编译了 lua,这与我用于构建 hello.dll 的命令相同。虽然在构建 lua.exe 中有所不同,但我使用源附带的 makefile,而在我的 makefile 是由 cmake 生成的,所以我不确定它们是否有不同的编译器设置。我可以同时发布,看看是否有人能看到任何东西,我自己不确定 makefile 语法
  • 发布makefile 代码太多,最重要的是最后的编译和链接命令带有命令行参数。我编辑了帖子,将多个 cmets 列为更有用的答案。如果仍然没有运气,我认为我们将不得不关闭这个问题,它更适合讨论论坛,并且 AFAICT 你还没有 SO 上的聊天权限(需要至少 20 个代表点)。
猜你喜欢
  • 1970-01-01
  • 2017-03-17
  • 2022-11-18
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
相关资源
最近更新 更多