OpenXRay/xray-16

[SUGGESTION] Reviving lua profiler (profiler.script)

Open

#1,436 opened on Sep 4, 2023

View on GitHub
 (2 comments) (0 reactions) (0 assignees)C++ (519 forks)auto 404
Developer ExperienceHelp wantedLuaModmaker Experience

Repository metrics

Stars
 (3,524 stars)
PR merge metrics
 (PR metrics pending)

Description

What is

Lua profiling tools are very useful since they allow precise profiling of codebase performance/timing. Right now profiler.script start attempts cause game to fail with exceptions.

Observations

After spending some time with few attempts to revive it I found following things:

  • Main reason of errors is setting hook with "c" mask. debug.sethook works fine with "r" flag and allows counting how many time functions were called. Setting / removing / resetting hook in runtime many times does not break gameplay
  • JIT compilation does not work well with profiling. Following flags can help to test/measure anything: -nojit -luadumpstate
  • The issue is fairly predictable and order of things is deterministic - following same scenario allows to reproduce issues exactly in the same way
  • Main reason of failures with "c" hook mask is that at some point of time Lua starts adding garbage parameter in function calls, as result logics breaks (in case of custom scripts), or game just crashes (luabind cannot find matching method override, native libs get more params than expected or wrong types)
  • I have tried to trace method call where addition of garbage happens, seems like here something unexpected happens: https://github.com/OpenXRay/LuaJIT/blob/0bc04c4768a71a6bf7f7d6a973b06a97e58dc722/src/lj_api.c#L1169 , I could not follow further to assembly
  • Lua VM stack looked similar in case of hook turned on and off -> same count of items in stack, exactly same order and types
  • I saw somewhere in repo that it may be related to super call in constructors, but nope. In my codebase all luabind classes are using Parent.__init(self) + issue can be reproduced with global methods like time_global
  • My guess is that with 'c' flag something happens inside xray custom script_engine / luabind / luajit and some garbage is added to stack without proper cleanup. As result, it appears in lua methods calls and causes game to crash

Leaving observations / context here since someone more experienced with C++/lua integration may pick it up

Contributor guide