Make WFL's error-reporting machinery thread_local

To report the WFL call stack in the event of errors, a static stack is used to
record that call-stack. This wasn't thread-safe, and it intermittently crashed
when the game config was movetype patching (the other WFL thread involved is
the GUI2 layout code).

Also a Rule of Three fix for the call_stack_manager class. While this wasn't
the cause of the crash, it could also have lead to a call_stack.pop_back() on
an empty stack.
This commit is contained in:
Steve Cotton 2021-03-29 13:45:21 +02:00
parent 884fa9ca6f
commit b8b06d0862
3 changed files with 13 additions and 1 deletions

View file

@ -17,6 +17,7 @@
### WML Engine
### Miscellaneous and Bug Fixes
* Fixed units with max movement set to zero being given one max movement point by `[unstore_unit]` or when loading a saved game
* Fixed an intermittent crash on the loading screen (issue #5629)
## Version 1.15.11
### AI

View file

@ -37,7 +37,13 @@ static lg::log_domain log_scripting_formula("scripting/formula");
namespace wfl
{
static std::deque<std::string> call_stack;
/**
* For printing error messages when WFL parsing or evaluation fails, this contains the names of the WFL functions being evaluated.
*
* Two C++ threads might be evaluating WFL at the same; declaring this thread_local is a quick bugfix which should probably be replaced
* by having a context-object for each WFL evaluation.
*/
thread_local static std::deque<std::string> call_stack;
call_stack_manager::call_stack_manager(const std::string& str)
{

View file

@ -47,9 +47,14 @@ namespace wfl
#define DECLARE_WFL_FUNCTION(name) \
functions_table.add_function(#name, std::make_shared<builtin_formula_function<name##_function>>(#name))
/**
* Provides debugging information for error messages.
*/
struct call_stack_manager
{
explicit call_stack_manager(const std::string& str);
call_stack_manager(const call_stack_manager&) = delete;
call_stack_manager& operator=(const call_stack_manager&) = delete;
~call_stack_manager();
static std::string get();