【问题标题】:rb_raise in embeded c++ cause Segmentation fault嵌入式 C++ 中的 rb_erase 导致分段错误
【发布时间】:2017-05-26 16:38:47
【问题描述】:

我尝试将 ruby​​ 解释器嵌入到我的程序中。 程序运行良好,但如果 ruby​​ 出现异常(在 C 或 ruby​​ 本身中),程序会因 SEGFAULT 崩溃。 示例:

#include <iostream>
#include "Ruby/ruby.h"
#define RUBY_METH(method) reinterpret_cast< VALUE ( * ) ( ... ) >(method)
using namespace std;

int main(int argc, char** argv)
{
    cout << "Hello world!" << endl;
    ruby_sysinit(&argc, &argv);
    RUBY_INIT_STACK;
    ruby_init();
    ruby_init_loadpath();
    rb_require("./init");//segfault by "raise"
    rb_raise(rb_eArgError, "Lol");//If comment "raise" in init.rb, segfault

    return 0;
}

init.rb

p "lol"
raise 

控制台输出

Hello world!
"lol"
<main>: [BUG] Segmentation fault
ruby 1.9.3p551 (2014-11-13) [i386-mingw32]

-- Control frame information -----------------------------------------------
c:0001 p:0000 s:0002 b:0002 l:000c74 d:000c74 TOP


-- C level backtrace information -------------------------------------------
C:\WINDOWS\SYSTEM32\ntdll.dll(ZwWaitForSingleObject+0xc) [0x76fbe5fc]
C:\WINDOWS\System32\KERNELBASE.dll(WaitForSingleObject+0x12) [0x75bdad52]
 [0x004b2789]
 [0x00402106]
 [0x00402f6f]
 [0x004f9e90]
 [0x004011ea]
C:\WINDOWS\SYSTEM32\ntdll.dll(LdrSetAppCompatDllRedirectionCallback+0x1ae9d) [0x76fee0bd]

在 Windows 上使用 GNU GCC 编译

【问题讨论】:

  • 你需要比这更彻底地追踪。
  • 嗯,JUMP_TAG 的一些错误

标签: c++ ruby segmentation-fault embed


【解决方案1】:

迟到的答案,但对于任何可能遇到此问题的人来说,未捕获的 Ruby 异常将使您的应用程序出现段错误。在您的应用程序中嵌入 Ruby 时,您需要使用 rb_protect 来捕获错误。

https://silverhammermba.github.io/emberb/c/#exceptions

如果您正在编译一个要由 Ruby 加载的库,那么这很容易。 API 中引发的任何异常都可以像往常一样在您的 Ruby 代码中被挽救。如果要在 API 中救援异常,可以使用 rb_rescue2(),类似于 Ruby 的救援。

...

如果您将 Ruby 解释器嵌入到 C 中,则在调用可能引发异常的 API 函数时需要格外小心:未捕获的异常会使 VM 出现段错误并终止您的程序。您可以使用 rb_eException 调用 rb_rescue2(),但还有另一种方法可以挽救所有异常: rb_protect

【讨论】:

    猜你喜欢
    • 2013-01-28
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多