Lua coroutine error: tempt to yield across metamethod/C-call boundary - lua

I'm using a game engine that allows you to program in Lua. The game engine commands are in a DLL created from C. There is a exe created in C that calls a Lua file. This Lua file is where you put all your game code including the main loop. There is no going back and forth with the exe, but you can call functions from the DLL.
So in here before the main loop I create a function which I'm going to create a coroutine from. This function iterates over a pretty big table so every n iterations I yield. This function has an infinite while loop around that because I need this stuff to run every single cycle of the main game loop, but it's OK if it's split between multiple cycles.
I then create a coroutine with this function as the parameter. In the main game loop I then resume this coroutine.
When I run my code I get the error: tempt to yield across metamethod/C-call boundary
I was reading some stuff online but not really understanding what the issue is here. Once the exe calls the Lua file it doesn't go back to the exe at all until the Lua file is finished, and since I have my main loop in the Lua file it never finishes in my test case.
What are my options with this then?

The error is telling you that you are attempting to yield from within Lua code where there is some C function between the Lua code doing the yielding and the Lua code that resumed the coroutine. To hit this error, what you have to have done is call some C function from Lua, which calls back into Lua code, which then calls coroutine.yield().
You can't do that. You must instead restructure your code to avoid this. Since you didn't provide any code, there's not much that can be suggested.

There are several things you can do if you cannot change your code to avoid the C/metamethod boundary:
If you are using standard Lua, and are compiling it yourself, try patching it with Coco — True C Coroutines for Lua.
True C coroutine semantics mean you can yield from a coroutine across a C call boundary and resume back to it.
Try using LuaJIT instead of the standard Lua interpreter. It uses a fully resumable VM meaning the boundary is not an issue.
Try using Lua 5.2. It features yieldable pcall and metamethods which means that it can handle your problem. However, there are some changes and incompatibilities between Lua 5.1 and Lua 5.2.

Related

How to call a function from a lua file of a c++/lua project on interactive terminal?

I'm reading some source codes of a project, which is a combination of c++ and lua, they are interwined through luabind.
There is a la.lua file, in which there is a function exec(arg). The lua file also uses functions/variables from other lua file, so it has statements as below in the beginning
module(..., package.seeall);
print("Loading "..debug.getinfo(1).source.."...")
require "client_config"
now I want to run la.exec() from interactive terminal(on linux), but I get errors like
attempt to index global 'lg' (a nil value)
if I want to import la.lua, I get
require "la"
Loading #./la.lua...
./la.lua:68: attempt to index global 'ld' (a nil value)
stack traceback:
./lg.lua:68: in main chunk
[C]: in function 'require'
stdin:1: in main chunk
[C]: ?
what can I do?
Well, what could be going wrong?
(Really general guesswork following, there's not much information in what you provided…)
One option is that you're missing dependencies because the files don't properly require all the things they depend on. (If A depends on & requires B and then C, and C depends on B but doesn't require it because it's implicitly loaded by A, directly loading C will fail.) So if you throw some hours at tracking down & fixing dependencies, things might suddenly work.
(However, depending on how the modules are written this may be impossible without a lot of restructuring. As an example, unless you set package.loaded["foo"] to foo's module table in foo before loading submdules, those submodules cannot require"foo". (Luckily, module does that, in newer code without module that's often forgotten – and then you'll get an endless loop (until the stack overflows) of foo loading other modules which load foo which loads other modules which …) Further, while "fixing" things so they load in the interpreter you might accidentally break the load order used by the program/library under normal operation which you won't notice until you try to run that one normally again. So it may simply cost too much time to fix dependencies. You might still be able to track down enough to construct a long lua -lfoo-lbar… one-off dependency list which might get things to run, but don't depend on it.)
Another option is that there are missing parts provided by C(++) modules. If these are written in the style of a Lua library (i.e. they have luaopen_FOO), they might load in the interpreter. (IIRC that's unlikely for C++ because it expects the main program to be C++-aware but lua is (usually? always?) plain C.) It's also possible that these modules don't work that way and need to be loaded in some other way. Yet another possibility might be that the main program pre-defines things in the Lua state(s) that it creates, which means that there is no module that you could load to get those things.
While there are some more variations on the above, these should be all of the general categories. If you suspect that your problem is the first one (merely missing dependency information), maybe throw some more time at this as you have a pretty good chance of getting it to work. If you suspect it's one of the latter two, there's a very high chance that you won't get it to work (at least not directly).
You might be able to side-step that problem by patching the program to open up a REPL and then do whatever it is you want to do from there. (The simplest way to do that is to call debug.debug(). It's really limited (no multiline, no implicit return, crappy error information), but if you need/want something better, something that behaves very much like the normal Lua REPL can be written in ~30 lines or so of Lua.)

Hacking Lua - Inject new functions into built Lua

I am trying to hack a game (not for cheating though) by introducing new built-in methods and functions in order to communicate with the game using sockets. Here is a small "pseudo code" example of what I want to accomplish:
Inside the Lua code I am calling my_hack() and pass the current game state:
GameState = {}
-- Game state object to be passed on
function GameState:new()
-- Data
end
local gameState = GameState:new()
-- Collect game state data and pass it to 'my_hack' ..
my_hack(gameState)
and inside my_hack the object is getting sent away:
int my_hack(lua_State * l)
{
void* gameState= lua_topointer(l, 1);
// Send the game state:
socket->send_data(gameState);
return 0;
}
Now, the big question is how to introduce my_hack() to the game?
I assume, that all built in functions must be kept in some sort of lookup table. Since all Lua code is getting interpreted, functions like import etc. will have to be statically available, right? If that is correct, then it should be "enough" to find out where this code is residing in order to smuggle my code into the game that would allow me to call my_hack() in a Lua script.
There should be two options: The first is that the Lua built is embedded inside the executable and is completely static and the second is that all Lua code gets loaded dynamically from a DLL.
This question goes out to anybody who has a slightest clue about where and how I should keep looking for the built in functions. I've tried a few things with Cheat Engine but I wasn't too successful. I was able to cheat a bit ^^ but that's not what I'm looking out for.
Sorry for not providing a full answer, but if you can provide a custom Lua VM and change the standard libraries, you should be able to to change the luaL_openlibs method in the Lua source to provide a table with my_hack() inside of it.
Since the Lua interpreter is usually statically compiled into the host executable, modifying the interpreter in some way will probably not be possible.
I think your best bet is to find some piece of Lua code which gets called by the host, and from that file use dofile to run your own code.

Can I have a custom function stop a Lua script in Delphi without exiting the application?

I have an application that periodically will run a Lua script. Within the script, on occasion, I have created a custom registered Lua function to check some parameters and decide if the Lua script should continue or exit. The logic ideally should not be part of the script and I can think of using a Lua script to work around this, but I'm wondering if it is possible to stop the execution of a Lua script without ending the application.
I have a custom function written in Delphi and exposed to Lua scripts using Lua 5.1. The Lua script looks something like that shown below and the script in Lua is started using luaL_loadbuffer.
io.write("Script starting\n");
--Custom Function
ExitIfFound();
io.write("Script continuing\n");
My custom function looks something like this, below I have provided one of my attempts where I tried to use lua_error to stop the script...
function ExitIfFound(LuaState: TLuaState): Integer;
var
s: AnsiString;
begin
s := 'ExitIfFound ending script, next Lua script line not called';
lua_pushstring(LuaState, PAnsiString(s));
lua_error(LuaState);
end;
When my custom function is called, I'm unsure as to how to exit the Lua script without any further evaluation. I have seen posts referring to Lua and using setjmp and longjmp in C, but I'm curious how these may translate Delphi.
In the example above, when I use lua_error, the entire program crashes with Windows doing its typical, [luarun.exe has stopped working] ...
With all of this, I'm am still pretty new to integrating Lua to Delphi and hoping that I can find some cleaner options to explore.
There is no clean way to entirely abort a Lua script. The lua_error function is the correct way to signal an error. It is the caller's responsibility to catch the error and propagate it to the next caller.
If you cannot rely on the caller to cooperate, then you can try to exert more control by installing debug hooks. Then the host program will be consulted before continuing to run the script. However, the script can still avoid exiting by using pcall to catch any errors.
The crash in your program is probably not simply from setting an error. Rather, it's likely from using the wrong calling convention on your ExitIfFound function. It needs to be cdecl, but Delphi's default, if you don't specify anything else, is register. Using the wrong calling convention will give you unpredictable parameter values and can lead to a corrupted stack. If you type-casted the function or used the # operator when you called lua_register, then you might have hidden the calling-convention mismatch from the compiler's type checker, which would have otherwise alerted you to the problem at compile time.
When compiled as C++, lua_error will use a exception instead of longjmp, but either way, the caller always catches the error. Exceptions are important, though, when your Delphi code uses compiler-managed types like string, or exception-sensitive constructs like try-finally blocks. In C mode, lua_error calls longjmp to jump directly to the waypoint set by a previous call to setjmp. That jump will skip over any exception handlers like the ones the Delphi compiler sets up to ensure the finally block runs and the string gets cleaned up.
A further headache is that since the compiler cleans up the string while exiting the function, the pointer you put on the Lua stack might not be valid by the time it's used; that depends on whether lua_pushstring makes a copy of its argument.

Storing scripts

I'm implementing Lua scripting engine in my c++ game engine and I was wondering what is the best way to store and execute Lua scripts. I have many scene nodes where each of them could have it's own script assigned. Is calling lauL_dofile(...) every frame for that specific script a viable option, or is there a better way? For example, is there a way to store already parsed scripts? I was looking at luaL_loadfile and lua_pcall. I thought I would load scripts with first one, and call them with second one when I need, but lua_pcall doesn't seem to have an unique id as a parameter, so how should I know which script to execute?
If you're going to use the Lua API, you need to become comfortable with the Lua stack. And one of the most important things you can learn to do is understanding how to read the Lua API docs. For every function, there is a notation on the right about exactly how it affects the stack (if it modifies the stack at all).
luaL_loadfile loads a file and pushes that file as a Lua function onto the stack. lua_pcall executes a function on the stack. But it has a number of caveats about how it does stuff.
The way calling functions through Lua works in terms of the stack is simple. You push the function you want to call. Then you push all of the arguments, in order, from first to last. Then you issue your call of that function. lua_pcall works in this way. This means that the location of the function to execute is always nargs + 1, relative to the top of the stack, where nargs is the number of arguments you're passing to the function.
Note that lua_pcall will pop the function from the stack (along with all of the arguments). If you just loaded the file, this will be the only reference to that function in Lua. Thus, you will not be able to execute the file again. You should duplicate the function before pushing its arguments onto the stack, using lua_pushvalue to copy it. You should probably stick it in the LUA_REGISTRYINDEX table or something, so that it's value is preserved.
As I commented, you usually call luaL_loadfile at initialization time. The loaded files usually define some [global] names (or fill some slots in some global table) as Lua functions. The lua 5.2 documentation gives an example (§4 lua_call) of how to call one of them. You'll do such calls (perhaps using lua_pcall or lua_call) at appropriate places of your application, by pushing appropriate things on the Lua stack.

How to check if a script is included via dofile() or run directly in Lua? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
“main” function in Lua?
In Python, you can check if a script is being called direcly (and call some functions if it is, usually for testing) pretty easily:
if __name__ == "__main__":
main()
Is there a way to do the same in Lua, to detect if it is run directly (lua foo.lua) or included in another script (dofile('foo.lua')).
There is always the trivial (and ugly) way of defining some dummy global variable in the main script file before dofile('foo.lua'), and checking in foo.lua if it is defined or not, but it would be great if there was a better way to do this.
At the top level you can check if debug.getinfo(2) is nil
From http://www.lua.org/manual/5.1/manual.html#pdf-debug.getinfo
you can give a number as the value of function, which means the function running at level function of the call stack of the given thread: level 0 is the current function (getinfo itself); level 1 is the function that called getinfo; and so on. If function is a number larger than the number of active functions, then getinfo returns nil.
No. Lua has no way to tell if a script is being invoked "directly".
Remember: Lua and Python exist for different purposes. Python is designed for command-line scripting. You write a script, which calls modules that may be written in Python, C++, or whatever. The Python script is ultimately what is in charge of which code gets called when.
Lua is an embedded scripting language, first and foremost. While you can certainly use the standalone lua.exe interpreter to create command-line scripts, that is something of a kludge. The language's primary purpose is to be embedded in some application written in C, C++, or whatever.
Because of this, there is no concept of a "main" script. How would you define what is "main" and what is not? If C code can load any script at any time, for any purpose, which one of them is "main"?
If you want to define this concept, it's fairly simple. Just stick this at the top of your "main" script:
do
local old_dofile = dofile
function new_dofile(...)
if(__is_main) then
__is_main = __is_main + 1
else
__is_main = 1
end
old_dofile(...)
__is_main = __is_main - 1
if(__is_main == 0) then __is_main = nil end
end
dofile = new_dofile
end
Granted, this won't work for anything loaded with require; you'd need to write a version of this for require as well. And it certainly won't work if external code uses the C-API loading functions (which is why require probably won't work).

Resources