1

I have a piece of code like this

class Test
{
public:
    Test() {printf(">>> Test()\n");}
    ~Test() {printf(">>> ~Test()\n");}
}

int myFunc(lua_State *L)
{
    Test t;
    luaL_error(L, "error");
    return 0;
}

I know when lua complied by c complier it use longjmp to raise an error. So, I compiled it use c++ compiler so that it use c++ exception to hand the errors and the destructor should be called even if an error is thrown. But my problem is that the object's destructor is not called.

However, the following code is working (the destructor is called)

int myFunc(lua_State *L)
{
    Test t;
    throw(1) // just for testing
    return 0;
}

Why this happend? I'm sure the LUAI_THROW macro is interpreted as throw key word.

greatwolf
  • 20,287
  • 13
  • 71
  • 105
Kery
  • 513
  • 8
  • 22

2 Answers2

1

The function luaL_error() will call exit() which cancels the whole execution of your program! The desctructor is not called then because the scope where Test t is in does not end. You should use a different functionality to be able to recover from an error.

How do you call the error from lua? I think you need to do a protected call using lua_cpcall to go arround this exit on error feature!

clambake
  • 772
  • 4
  • 15
  • Yes, myFunc is protected by lua_pcall. It's is an api function exposed to lua script file. So, the root cause is not as you mentioned above. – Kery Apr 28 '14 at 09:24
  • have you tried surrounding the luaL_error(L, "error"); with a try/catch block? – clambake Apr 28 '14 at 09:30
  • After your reminding, I have a try, the error thrown by luaL_error is catched by try {} catch(...) {} block. And " Microsoft C++ exception: lua_longjmp at memory location 0x003fdc6c.." is outputted when the exception is thrown. – Kery Apr 28 '14 at 09:40
  • is your destructor called then? – clambake Apr 28 '14 at 09:42
  • Yes, but this not solve my problem because I want to propagate the error to the position where lua_pcall is called. – Kery Apr 28 '14 at 09:48
  • ah okay I did not get that from your main question. – clambake Apr 28 '14 at 10:01
  • @Kery How can your code be calling longjump if it is C++? Did you somehow link part of your code to the C version of the Lua DLL instead of the C++ version? Please update your post with the pertinent information from these comments so people don't have to dig through this. Right now it is not clear if this is settled or not. – Oliver Apr 28 '14 at 20:39
1

The root cause is related to exception handling mode in visual c++ compiler. I use the lua function (such as luaL_error) with extern "C" modifier to prevent compiler from name-mangling. And the default exception handling mode is /EHsc which assume extern "C" function don't throw exception. So, the exception can't be catched. The solution is change /EHsc to /EHs.

For more information please refer to http://msdn.microsoft.com/en-us/library/1deeycx5.aspx.

Kery
  • 513
  • 8
  • 22