diff --git a/mod/box/box_lua.m b/mod/box/box_lua.m
index f558a470ca80b7923113abdeaeb386b4e9439227..dbd9e72032cb1d410a1e9c8d21279e87ab25fa4a 100644
--- a/mod/box/box_lua.m
+++ b/mod/box/box_lua.m
@@ -760,14 +760,6 @@ void box_lua_find(lua_State *L, const char *name, const char *name_end)
 		lua_remove(L, index);
 }
 
-
-static int
-box_lua_panic(struct lua_State *L)
-{
-	tnt_raise(ClientError, :ER_PROC_LUA, lua_tostring(L, -1));
-	return 0;
-}
-
 @implementation Call
 /**
  * Invoke a Lua stored procedure from the binary protocol
@@ -795,6 +787,10 @@ box_lua_panic(struct lua_State *L)
 		lua_call(L, nargs, LUA_MULTRET);
 		/* Send results of the called procedure to the client. */
 		[port addLuaMultret: L];
+	} @catch (tnt_Exception *e) {
+		@throw;
+	} @catch (...) {
+		tnt_raise(ClientError, :ER_PROC_LUA, lua_tostring(L, -1));
 	} @finally {
 		/*
 		 * Allow the used coro to be garbage collected.
@@ -808,7 +804,6 @@ box_lua_panic(struct lua_State *L)
 struct lua_State *
 mod_lua_init(struct lua_State *L)
 {
-	lua_atpanic(L, box_lua_panic);
 	/* box, box.tuple */
 	tarantool_lua_register_type(L, tuplelib_name, lbox_tuple_meta);
 	luaL_register(L, "box", boxlib);
diff --git a/src/tarantool_lua.m b/src/tarantool_lua.m
index ba2314b049400b34b79b9efff8c9b45e2d07914d..f3593cf20137844c5dfb803bd77fbd800a2fc773 100644
--- a/src/tarantool_lua.m
+++ b/src/tarantool_lua.m
@@ -590,6 +590,12 @@ box_lua_fiber_run(void *arg __attribute__((unused)))
 		lua_pushboolean(L, false);
 		/* error message */
 		lua_pushstring(L, e->errmsg);
+	} @catch (tnt_Exception *e) {
+		@throw;
+	} @catch (...) {
+		lua_settop(L, 1);
+		lua_pushboolean(L, false);
+		lua_insert(L, -2);
 	} @finally {
 		/*
 		 * If the coroutine has detached itself, collect
@@ -939,6 +945,14 @@ lbox_pcall(struct lua_State *L)
 		lua_pushboolean(L, false);
 		/* error message */
 		lua_pushstring(L, e->errmsg);
+	} @catch (tnt_Exception *e) {
+		@throw;
+	} @catch (...) {
+		lua_settop(L, 1);
+		/* completion status */
+		lua_pushboolean(L, false);
+		/* put the completion status below the error message. */
+		lua_insert(L, -2);
 	}
 	return lua_gettop(L);
 }
@@ -1042,6 +1056,10 @@ tarantool_lua_dostring(struct lua_State *L, const char *str)
 	} @catch (ClientError *e) {
 		lua_pushstring(L, e->errmsg);
 		return 1;
+	} @catch (tnt_Exception *e) {
+		@throw;
+	} @catch (...) {
+		return 1;
 	}
 	return 0;
 }
diff --git a/test/box/lua.result b/test/box/lua.result
index 75d43ca275a31bb774848b2e7da69e498a5ef266..921feab4a3a65d0a83d9dc3fee16563986a8122a 100644
--- a/test/box/lua.result
+++ b/test/box/lua.result
@@ -34,15 +34,15 @@ lua for n in pairs(box) do print('  - box.', n) end
 ...
 lua box.pack()
 ---
-error: 'Lua error: bad argument #1 to ''?'' (string expected, got no value)'
+error: 'bad argument #1 to ''?'' (string expected, got no value)'
 ...
 lua box.pack(1)
 ---
-error: 'Lua error: box.pack: argument count does not match the format'
+error: 'box.pack: argument count does not match the format'
 ...
 lua box.pack('abc')
 ---
-error: 'Lua error: box.pack: argument count does not match the format'
+error: 'box.pack: argument count does not match the format'
 ...
 lua print(box.pack('a', ' - hello'))
 ---
@@ -62,7 +62,7 @@ lua print(box.pack('www', 0x30, 0x30, 0x30))
 ...
 lua print(box.pack('www', 0x3030, 0x30))
 ---
-error: 'Lua error: [string "return print(box.pack(''www'', 0x3030, 0x30))"]:1: box.pack: argument count does not match the format'
+error: '[string "return print(box.pack(''www'', 0x3030, 0x30))"]:1: box.pack: argument count does not match the format'
 ...
 lua print(string.byte(box.pack('w', 212345), 1, 2))
 ---
@@ -93,7 +93,7 @@ lua box.process(17, box.pack('iiiiiip', 0, 0, 0, 2^31, 1, 1, 1))
 ...
 lua box.process(22, box.pack('iii', 0, 0, 0))
 ---
-error: 'Lua error: box.process(CALL, ...) is not allowed'
+error: 'box.process(CALL, ...) is not allowed'
 ...
 call box.process('abc', 'def')
 An error occurred: ER_ILLEGAL_PARAMS, 'Illegal parameters, unsupported command code, check the error log'
@@ -405,15 +405,15 @@ lua for k,v in pairs(box.space[0]) do if type(v) ~= 'table' then print(' - ', k,
 ...
 lua box.cfg.nosuchoption = 1
 ---
-error: 'Lua error: [string "box.cfg = {}..."]:52: Attempt to modify a read-only table'
+error: '[string "box.cfg = {}..."]:52: Attempt to modify a read-only table'
 ...
 lua box.space[300] = 1
 ---
-error: 'Lua error: [string "box.cfg = {}..."]:52: Attempt to modify a read-only table'
+error: '[string "box.cfg = {}..."]:52: Attempt to modify a read-only table'
 ...
 lua box.index.new('abc', 'cde')
 ---
-error: 'Lua error: bad argument #1 to ''?'' (number expected, got string)'
+error: 'bad argument #1 to ''?'' (number expected, got string)'
 ...
 lua box.index.new(1, 2)
 ---
@@ -488,19 +488,19 @@ lua t=box.space[0]:insert('test')
 ...
 lua t:next('abcd')
 ---
-error: 'Lua error: tuple.next(): bad arguments'
+error: 'tuple.next(): bad arguments'
 ...
 lua t:next(1)
 ---
-error: 'Lua error: tuple.next(): bad arguments'
+error: 'tuple.next(): bad arguments'
 ...
 lua t:next(t)
 ---
-error: 'Lua error: tuple.next(): bad arguments'
+error: 'tuple.next(): bad arguments'
 ...
 lua t:next(t:next())
 ---
-error: 'Lua error: tuple.next(): bad arguments'
+error: 'tuple.next(): bad arguments'
 ...
 lua for k, v in t:pairs() do print(v) end
 ---
@@ -537,11 +537,11 @@ lua box.fiber.sleep(0.0001)
 ...
 lua box.fiber.sleep('hello')
 ---
-error: 'Lua error: fiber.sleep(delay): bad arguments'
+error: 'fiber.sleep(delay): bad arguments'
 ...
 lua box.fiber.sleep(box, 0.001)
 ---
-error: 'Lua error: fiber.sleep(delay): bad arguments'
+error: 'fiber.sleep(delay): bad arguments'
 ...
 lua box.fiber.cancel(box.fiber.self())
 lua f = box.fiber.self()
@@ -580,7 +580,7 @@ error: '[string "f = box.fiber.create(print(''hello'')"]:1: '')'' expected near
 ...
 lua box.fiber.resume(f)
 ---
-error: 'Lua error: fiber.resume(): can''t resume a detached fiber'
+error: 'fiber.resume(): can''t resume a detached fiber'
 ...
 lua function r(a, b) print(a) print(b) return a, b end
 ---
@@ -666,7 +666,7 @@ lua box.fiber.cancel(f)
 ...
 lua box.fiber.resume(f)
 ---
-error: 'Lua error: fiber.resume(): can''t resume a detached fiber'
+error: 'fiber.resume(): can''t resume a detached fiber'
 ...
 lua f=nil
 ---
@@ -885,7 +885,7 @@ lua box.space[0]:truncate()
 
 lua os.execute('ls')
 ---
-error: 'Lua error: [string "return os.execute(''ls'')"]:1: attempt to call field ''execute'' (a nil value)'
+error: '[string "return os.execute(''ls'')"]:1: attempt to call field ''execute'' (a nil value)'
 ...
 
 #
@@ -900,15 +900,15 @@ lua dofile(...)
 
 lua box.fiber.status(1)
 ---
-error: 'Lua error: bad argument #1 to ''?'' (box.fiber expected, got number)'
+error: 'bad argument #1 to ''?'' (box.fiber expected, got number)'
 ...
 lua box.fiber.status('fafa-gaga')
 ---
-error: 'Lua error: bad argument #1 to ''?'' (box.fiber expected, got string)'
+error: 'bad argument #1 to ''?'' (box.fiber expected, got string)'
 ...
 lua box.fiber.status(nil)
 ---
-error: 'Lua error: bad argument #1 to ''?'' (box.fiber expected, got nil)'
+error: 'bad argument #1 to ''?'' (box.fiber expected, got nil)'
 ...
 
 # run fiber's test
@@ -973,7 +973,7 @@ lua tonumber64(-1)
 ...
 lua tonumber64('184467440737095516155')
 ---
-error: 'Lua error: lua_tointeger64: bad argument'
+error: 'lua_tointeger64: bad argument'
 ...
 lua string.byte(box.pack('p', tonumber64(123)))
 ---
@@ -1300,11 +1300,11 @@ lua t:slice(1)
 ...
 lua t:slice(-1, -1)
 ---
-error: 'Lua error: tuple.slice(): start must be less than end'
+error: 'tuple.slice(): start must be less than end'
 ...
 lua t:slice(-1, 1)
 ---
-error: 'Lua error: tuple.slice(): start must be less than end'
+error: 'tuple.slice(): start must be less than end'
 ...
 lua t:slice(1, -1)
 ---
@@ -1326,11 +1326,11 @@ lua t:slice(7)
 ...
 lua t:slice(9)
 ---
-error: 'Lua error: tuple.slice(): start must be less than end'
+error: 'tuple.slice(): start must be less than end'
 ...
 lua t:slice(9, -1)
 ---
-error: 'Lua error: tuple.slice(): start must be less than end'
+error: 'tuple.slice(): start must be less than end'
 ...
 lua t:slice(6, -1)
 ---
@@ -1338,11 +1338,11 @@ lua t:slice(6, -1)
 ...
 lua t:slice(9, 10)
 ---
-error: 'Lua error: tuple.slice(): start must be less than end'
+error: 'tuple.slice(): start must be less than end'
 ...
 lua t:slice(500, 700)
 ---
-error: 'Lua error: tuple.slice(): start must be less than end'
+error: 'tuple.slice(): start must be less than end'
 ...
 lua box.space[0]:truncate()
 ---
diff --git a/test/box_big/lua.result b/test/box_big/lua.result
index d383bb6668ccd4dab4c582f67977d900e0c795c2..cda5c198c7cbeefb9cf22279fbe66c45253c5b41 100644
--- a/test/box_big/lua.result
+++ b/test/box_big/lua.result
@@ -308,5 +308,5 @@ lua box.space[17].index[1].idx:count(3, 3)
 ...
 lua box.space[17].index[1].idx:count()
 ---
-error: 'Lua error: index.count(): one or more arguments expected'
+error: 'index.count(): one or more arguments expected'
 ...
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index f8297cfd008415709c42a563f964ee3af636c027..6e213d18592bdbe18db7c31addfacb6ba24d80db 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -28,9 +28,7 @@ macro (luajit_build)
     else ()
         set (luajit_copt ${luajit_copt} -O2)
     endif()
-    if (NOT HAVE_UNWIND_H)
-        set (luajit_copt ${luajit_copt} -I${PROJECT_SOURCE_DIR}/third_party/compat)
-    endif()
+    set (luajit_copt ${luajit_copt} -I${PROJECT_SOURCE_DIR}/libobjc)
     set (luajit_cc ${CMAKE_C_COMPILER})
     if (NOT luajit_cc)
         set (luajit_cc cc)
@@ -72,8 +70,10 @@ endmacro()
 macro(libobjc_build)
     if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
         set (extra_cflags "-g -O0 -fno-inline")
+        set (extra_ldflags "")
     else ()
-        set (extra_cflags "-O3")
+        set (extra_cflags "-O3 -Wno-unused-result")
+        set (extra_ldflags "-s")
     endif()
     if (${TARGET_OS_LINUX})
         set (extra_cflags "${extra_cflags} -D_GNU_SOURCE")
@@ -91,13 +91,14 @@ macro(libobjc_build)
     add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/libobjc/libobjc.a
         WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/third_party/libobjc
         COMMAND $(MAKE) clean
-        COMMAND $(MAKE) EXTRA_CFLAGS=""${extra_cflags}""
+        COMMAND $(MAKE) EXTRA_CFLAGS=""${extra_cflags}"" EXTRA_LDFLAGS=""${extra_ldflags}""
         DEPENDS ${PROJECT_BINARY_DIR}/CMakeCache.txt
     )
     add_custom_target(libobjc
         DEPENDS ${PROJECT_BINARY_DIR}/third_party/libobjc/libobjc.a
     )
     unset (extra_cflags)
+    unset (extra_ldlags)
 endmacro()
 
 #
diff --git a/third_party/libobjc/Makefile b/third_party/libobjc/Makefile
index 30eaebad64d450279df29d76a63c8fcaff20b3e3..dbe0adbdc3187dcadbc63683162d1230c13cf3dc 100644
--- a/third_party/libobjc/Makefile
+++ b/third_party/libobjc/Makefile
@@ -11,12 +11,12 @@ LIBOBJCLIBNAME=objc
 LIBOBJC=libobjc
 LIBOBJCXX=libobjcxx
 
-SILENT=@
+#SILENT=@
 
-CFLAGS += -std=gnu99 -fPIC -fexceptions
-CXXFLAGS += -fPIC -fexceptions
-CPPFLAGS += -DTYPE_DEPENDENT_DISPATCH -DGNUSTEP
-CPPFLAGS += -D__OBJC_RUNTIME_INTERNAL__=1 -D_XOPEN_SOURCE=500 -D__BSD_VISIBLE=1 -D_BSD_SOURCE=1
+CFLAGS+= -std=gnu99 -fexceptions
+CXXFLAGS+= -fexceptions
+CPPFLAGS+= -DTYPE_DEPENDENT_DISPATCH -DGNUSTEP
+CPPFLAGS+= -D__OBJC_RUNTIME_INTERNAL__=1 -D_XOPEN_SOURCE=500 -D__BSD_VISIBLE=1 -D_BSD_SOURCE=1
 
 ASMFLAGS += `if $(CC) -v 2>&1| grep -q 'clang' ; then echo -no-integrated-as ; fi`
 
@@ -83,7 +83,7 @@ $(LIBOBJC).so.$(VERSION): $(OBJECTS)
 
 $(LIBOBJC).a: $(OBJECTS)
 	$(SILENT)echo Linking static Objective-C runtime library...
-	$(SILENT)ld -r -o $@ $(OBJECTS)
+	$(SILENT)ld -r ${EXTRA_LDFLAGS} -o $@ $(OBJECTS)
 
 .cc.o: Makefile
 	$(SILENT)echo Compiling `basename $<`...