如何使用新异常(@throw…)使用 Objective-C 构建 Ruby 扩展?
我已经用 Objective-C 构建了一个 Ruby 扩展。现在我想使用 @throw/@catch 等而不是基于宏的异常处理和自构建错误处理。
我正在使用 GCC 附带的 GNU 运行时。
当我使用扩展运行 Ruby 应用程序时,一旦发生异常,它就会进行核心转储。 abort() 来自 GNU Objective-C 运行时 (libobjc/exception.c:375):
void
objc_exception_throw (id value)
{
struct ObjcException *header = calloc (1, sizeof (*header));
header->base.exception_class = __objc_exception_class;
header->base.exception_cleanup = __objc_exception_cleanup;
header->value = value;
#ifdef SJLJ_EXCEPTIONS
_Unwind_SjLj_RaiseException (&header->base);
#else
_Unwind_RaiseException (&header->base);
#endif
/* Some sort of unwinding error. */
abort ();
}
由于我使用 -fobjc-exceptions
进行编译,我认为 _Unwind_RaiseException
正在被调用。
有没有办法在 Ruby 扩展中使用 Objective-C 异常?
I have build a Ruby extension in Objective-C. Now I want to use @throw/@catch etc. instead of macro based exception handling and self build error handling.
I am using the GNU runtime shipped with the GCC.
When I run my Ruby app with my extension it core dumps as soon as an exception occurs. The abort() comes from the GNU Objective-C runtime (libobjc/exception.c:375):
void
objc_exception_throw (id value)
{
struct ObjcException *header = calloc (1, sizeof (*header));
header->base.exception_class = __objc_exception_class;
header->base.exception_cleanup = __objc_exception_cleanup;
header->value = value;
#ifdef SJLJ_EXCEPTIONS
_Unwind_SjLj_RaiseException (&header->base);
#else
_Unwind_RaiseException (&header->base);
#endif
/* Some sort of unwinding error. */
abort ();
}
Since I compiled with -fobjc-exceptions
I think _Unwind_RaiseException
is being called.
Is there any way to use the Objective-C exceptions in a Ruby extension?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
已解决的问题:
GNU Objective-C 运行时不处理
_Unwind_(SjLj_)RaiseException
的结果(参见上面的代码)。就我而言,它返回了5
,它代表“堆栈末尾”,意味着我忘记了 @try/@catch 块。确实应该有一些日志记录或一个钩子来自己完成。
更新:
除非使用
-fobjc-exceptions
编译 Ruby,否则 Objective-C 异常处理无法通过 Ruby 代码跟踪堆栈。因此,在将控制权交给 Ruby 之前,您必须注意捕获、包装或转换任何 Objective-C 异常。Problem solved:
The GNU Objective-C runtime does not handle the result of
_Unwind_(SjLj_)RaiseException
(see code above). In my case it returned5
which stands for “end of stack” and means that I had forgotten a @try/@catch block.There really should be some logging or a hook to do it self.
Update:
Unless one compiles Ruby with
-fobjc-exceptions
the Objective-C exception handling cannot trace the stack through Ruby code. Therefore you must be aware to catch and wrap or translate any Objective-C exception before giving control to Ruby.