- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
LuaJIT 手册 states :
Lua errors can be caught on the C++ side with catch(...). The corresponding Lua error message can be retrieved from the Lua stack.
这按预期工作 - 除了 std::uncaught_exception()
在这种情况下不返回 true。
以下是说明该问题的最小示例。 checker
的析构函数应该在堆栈展开期间执行,因此其中的 std::uncaught_exception()
应该返回 true,但它没有。
这怎么可能?是我误解了这个过程还是 LuaJIT 以粗略的方式执行异常引发?
struct checker {
~checker() {
if(std::uncaught_exception()) {
// condition should evaluate true, but doesn't
}
}
}
auto l = luaL_newstate();
try {
{
checker c;
luaL_checknumber(l, -1); // this line causes LuaJIT to raise an error
}
}
catch(...) {
// this will be executed, as intended
auto err = lua_tostring(state, -1); // read the LuaJIT error, works too
// ...
}
最佳答案
原始 Lua(不是 LuaJIT)使用不是 C++ 异常的 C 风格异常(长跳转)。grep
LUAI_THROW 的 Lua 来源并注意 C/C++ 异常处理之间的区别。
/*
@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
** CHANGE them if you prefer to use longjmp/setjmp even with C++
** or if want/don't to use _longjmp/_setjmp instead of regular
** longjmp/setjmp. By default, Lua handles errors with exceptions when
** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
** and with longjmp/setjmp otherwise.
*/
#if defined(__cplusplus)
/* C++ exceptions */
#define LUAI_THROW(L,c) throw(c)
#define LUAI_TRY(L,c,a) try { a } catch(...) \
{ if ((c)->status == 0) (c)->status = -1; }
#define luai_jmpbuf int /* dummy variable */
#elif defined(LUA_USE_ULONGJMP)
/* in Unix, try _longjmp/_setjmp (more efficient) */
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#else
/* default handling with long jumps */
#define LUAI_THROW(L,c) longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#endif
我不确定是否可行,但您可以尝试使用 C++ 编译 Lua,这将允许您捕获 Lua 异常。注意,编译为 C 代码的原始 Lua 不支持 C++ 栈帧展开!
至于 LuaJIT,它看起来像是自己实现了帧展开,有关详细信息,请参阅 lj_err.c。这就是为什么在此过程中可能不会设置某些 CRT 变量的原因。
/*
** LuaJIT can either use internal or external frame unwinding:
**
** - Internal frame unwinding (INT) is free-standing and doesn't require
** any OS or library support.
**
** - External frame unwinding (EXT) uses the system-provided unwind handler.
**
** Pros and Cons:
**
** - EXT requires unwind tables for *all* functions on the C stack between
** the pcall/catch and the error/throw. This is the default on x64,
** but needs to be manually enabled on x86/PPC for non-C++ code.
**
** - INT is faster when actually throwing errors (but this happens rarely).
** Setting up error handlers is zero-cost in any case.
**
** - EXT provides full interoperability with C++ exceptions. You can throw
** Lua errors or C++ exceptions through a mix of Lua frames and C++ frames.
** C++ destructors are called as needed. C++ exceptions caught by pcall
** are converted to the string "C++ exception". Lua errors can be caught
** with catch (...) in C++.
**
** - INT has only limited support for automatically catching C++ exceptions
** on POSIX systems using DWARF2 stack unwinding. Other systems may use
** the wrapper function feature. Lua errors thrown through C++ frames
** cannot be caught by C++ code and C++ destructors are not run.
**
** EXT is the default on x64 systems, INT is the default on all other systems.
**
** EXT can be manually enabled on POSIX systems using GCC and DWARF2 stack
** unwinding with -DLUAJIT_UNWIND_EXTERNAL. *All* C code must be compiled
** with -funwind-tables (or -fexceptions). This includes LuaJIT itself (set
** TARGET_CFLAGS), all of your C/Lua binding code, all loadable C modules
** and all C libraries that have callbacks which may be used to call back
** into Lua. C++ code must *not* be compiled with -fno-exceptions.
**
** EXT cannot be enabled on WIN32 since system exceptions use code-driven SEH.
** EXT is mandatory on WIN64 since the calling convention has an abundance
** of callee-saved registers (rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15).
** EXT is mandatory on POSIX/x64 since the interpreter doesn't save r12/r13.
*/
附言我想您已经了解安全 Lua 类型检查 (lua_is*
) 和安全函数,例如 lua_pcall
。
关于c++ - 为什么 std::uncaught_exception 在 LuaJIT 抛出时返回 false?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38493718/
来自 java docs 公共(public) FileWriter(String fileName) 抛出 IOException 抛出: IOException - 如果指定的文件存在但它是目录而
我使用以下代码将我的 .net 客户端(基于 CQL)连接到 3 节点 Cassandra 集群。我以 30 条记录/秒的速度(从 RabbitMQ)获取数据,并且它们顺利地存储在 cassandra
如果在读取文件时缺少字段,我应该捕获 NoSuchElementException。如果缺少一个字段,我只需要跳到文件的下一行。我的问题是,我在哪里实现我的 try/catch 代码来做到这一点?这是
我正在尝试使用 ASP.NET MVC 实现 OpeinID 登录。我正在尝试按照 http://blog.nerdbank.net/2008/04/add-openid-login-support-
学习使用 Java 进行 xml 解析,并且正在编写一个测试程序来尝试各种东西。所有测试 System.out.println() 都是我在控制台中所期望的,除了 childElement 返回 [n
我正在尝试使用 SwingUtilities 创建 JFrame Thread tt = new Thread(new Runnable() { public void run
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我写了这段代码: MethodInfo method2 = typeof(IntPtr).GetMethod( "op_Explicit", Bind
我开始学习 Java,并且正在根据书本做一些练习。在执行此操作时,我遇到了以下错误:线程“main”java.util.InputMismatchException 中出现异常。我正在编写一个简单的程
我有一个文本文件,其中前两行是整数 m 和 n,然后有 m 行,每行都有 n 管道分隔值。我编写了一个程序,读取文件并使用文件中的值创建 m*n 数组,它工作了无数次,然后突然,使用相同的代码,使用相
所以我尝试使用在另一个类中生成的 bean 以在主应用程序中使用 package com.simon.spring.basics.properties; import org.spri
我还没有完成这个应用程序,但我希望在我的手机上看到它的样子。但是,它会强制关闭并引发 InstantiationException。 logcat 异常: 09-19 20:13:47.987: D/
我想从 UIViewController 加载一个基于 SwiftUI 的 View ,该 View 读取包本地的 json。仅 swiftUI 项目中的代码和绑定(bind)工作正常,当我利用 UI
'java.net.SocketTimeoutException:连接超时' 循环一段时间后我收到此错误。为什么我会收到 SocketTimeoutException?我该如何修复这个错误? @Ove
当有 null 值时抛出 ArgumentNullException() 是个好主意吗? This thread 没有提到在 null 上抛出的最明显的异常。 谢谢 最佳答案 ArgumentNull
我得到这个异常: NullReferenceException Object reference not set to an instance of an object at Namespace
所以其中一个方法的描述如下: public BasicLinkedList addToFront(T data) This operation is invalid for a sorted list
我正在使用 Intellij Idea,当我去生成 JavaDocs(通过工具 -> 生成 JavaDoc)时,我抛出了一个 IllegealArgumentException,没有关于发生了什么问题
我正在学习 C++ 中的互斥锁,但以下代码(摘自 N. Josuttis 的“C++ 标准库”)有问题。 我不明白为什么它会阻塞/抛出除非我在主线程中添加this_thread::sleep_for(
我正在试验 JavaFX 标签和组,通过鼠标拖动将它们移动到屏幕上。新节点从一些线程添加到动画组。但是,有时我会突然看到以下异常 - 我假设,当某些节点重叠时。但是不知道是什么问题……因为不涉及我的代
我是一名优秀的程序员,十分优秀!