-
Notifications
You must be signed in to change notification settings - Fork 480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
REGRESSION: Fix console command completion help #5040
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
works on my end too
This actually would not be that hard to test from Lua:
but I'm not sure how to best make it robust to new tools being added, because the current logic gives no completions if there are too many possibilities:
|
Looks like this broke way back in 2022 with commit e926e11. |
if helpdb handled command aliases we could make some nonsense alias to a command and do it that way. Otherwise we'd have to construct a new one - and I don't know how to do that in a test. There aren't that many commands, the limit of 8 should be much higher. Maybe even no limit provided that the list of possibles isn't the full command set. |
Previously, calling a Lua C API function that throws an error (e.g. with any of the `lua_error()` family of functions, which use `luaD_throw()` internally) in a function that also uses our own `StackUnwinder` would deadlock, because: - `luaD_throw()` calls `lua_lock()` but apparently expects something else to call `lua_unlock()` - `~StackUnwinder()` calls `lua_settop()` to rewind the stack, which internally also calls `lua_lock()` and `lua_unlock()`. This is called before the mutex can be unlocked. This was the root cause of the issue behind DFHack#5040, DFHack#5055, DFHack#5056 - `GetVector()` was called with an invalid index (only when invoked from `gui/launcher`, because this changed the data on the Lua stack) and threw an exception, which caused the `~StackUnwinder()` destructor to run while the Lua state was still locked. Other things to note: - We control the locking/unlocking implementation - the default, defined in `llimits.h`, is a _no-op_. - @ab9rf points out that the `CRITICAL_SECTION` API we're using on Windows already appears to be equivalent to a recursive mutex, so this issue likely would not have occurred there. The issue can be reproduced relatively easily with a simple test command, e.g.: ```diff @@ -716,6 +723,15 @@ void ls_helper(color_ostream &con, const std::vector<std::string> ¶ms) { command_result Core::runCommand(color_ostream &con, const std::string &first_, std::vector<std::string> &parts) { std::string first = first_; + if (first == "luaerror") { + auto L = Lua::Core::State; + Lua::StackUnwinder top(L); + + luaL_error(L, "test error"); + + return CR_OK; + } + CommandDepthCounter counter; if (!counter.ok()) { ``` In `gui/launcher`: - before this change, invoking `luaerror` would hang DF. - after this change, `luaerror` prints `nil` in red to the native console and does nothing. This comes from the last-resort error handler in `LuaTools.cpp:report_error()`, and is equivalent to how other unexpected errors are handled in code invoked from Lua. Not ideal, but better than a crash. From the native console, invoking `luaerror` crashes DF in both cases (SIGABRT), and logs `PANIC: unprotected error in call to Lua API (test error)` to `stderr.log`. The difference in behavior is because `report_error()` above is part of the error handling system present when code is called _from Lua_, through variants of `SafeCall`. There is no Lua layer involved in the native console. (Note: the same crash would have been observed in the original issue in DFHack#5056 et. al. if the error had occurred when invoked through the console.)
Previously, calling a Lua C API function that throws an error (e.g. with any of the `lua_error()` family of functions, which use `luaD_throw()` internally) in a function that also uses our own `StackUnwinder` would deadlock, because: - `luaD_throw()` calls `lua_lock()` but apparently expects something else to call `lua_unlock()` - `~StackUnwinder()` calls `lua_settop()` to rewind the stack, which internally also calls `lua_lock()` and `lua_unlock()`. This is called before the mutex can be unlocked. This was the root cause of the issue behind #5040, #5055, #5056 - `GetVector()` was called with an invalid index (only when invoked from `gui/launcher`, because this changed the data on the Lua stack) and threw an exception, which caused the `~StackUnwinder()` destructor to run while the Lua state was still locked. Other things to note: - We control the locking/unlocking implementation - the default, defined in `llimits.h`, is a _no-op_. - @ab9rf points out that the `CRITICAL_SECTION` API we're using on Windows already appears to be equivalent to a recursive mutex, so this issue likely would not have occurred there. The issue can be reproduced relatively easily with a simple test command, e.g.: ```diff @@ -716,6 +723,15 @@ void ls_helper(color_ostream &con, const std::vector<std::string> ¶ms) { command_result Core::runCommand(color_ostream &con, const std::string &first_, std::vector<std::string> &parts) { std::string first = first_; + if (first == "luaerror") { + auto L = Lua::Core::State; + Lua::StackUnwinder top(L); + + luaL_error(L, "test error"); + + return CR_OK; + } + CommandDepthCounter counter; if (!counter.ok()) { ``` In `gui/launcher`: - before this change, invoking `luaerror` would hang DF. - after this change, `luaerror` prints `nil` in red to the native console and does nothing. This comes from the last-resort error handler in `LuaTools.cpp:report_error()`, and is equivalent to how other unexpected errors are handled in code invoked from Lua. Not ideal, but better than a crash. From the native console, invoking `luaerror` crashes DF in both cases (SIGABRT), and logs `PANIC: unprotected error in call to Lua API (test error)` to `stderr.log`. The difference in behavior is because `report_error()` above is part of the error handling system present when code is called _from Lua_, through variants of `SafeCall`. There is no Lua layer involved in the native console. (Note: the same crash would have been observed in the original issue in #5056 et. al. if the error had occurred when invoked through the console.)
Console command completion help was inadvertently broken in a prior commit. This PR should resolve the issue. Tested on posix console.
This could probably use a test, if I can figure out a proper way to do it.