danielga / gm_luaerror

A module for Garry's Mod that adds hooks for obtaining errors that happen on the client and server (if activated on server, it also pushes errors from clients).
https://github.com/danielga/gm_luaerror
Other
54 stars 8 forks source link

Potential crash event with the latest GMod update #39

Closed TeddiO closed 2 years ago

TeddiO commented 2 years ago
Exe build: 20:02:11 Dec 14 2021 (8438) (4000)
GMod version 2021.12.14, branch: unknown
Windows 32bit Dedicated Server

If an error is thrown before ISteamHTTP is available (e.g. close to or on server boot), the server will hang and endlessly consume RAM until the server echos not enough memory.

Example error trace:

[ERROR] HTTP failed - ISteamHTTP isn't available!
  1. Post - lua/includes/modules/http.lua:71
   2. v - gamemode/path/that/hooks
    3. unknown - lua/includes/modules/hook.lua:96
     4. HTTP - [C]:-1
TeddiO commented 2 years ago

Additionally after some testing with a vanilla install of GMod, even calling something via an http based function in GM:Initialize() is still too early 👀

danielga commented 2 years ago

To understand this issue better, is the server hang only happening with the module active? Is that example trace what seems to be causing the hang?

danielga commented 2 years ago

Also, can you make a small sample that reproduces the problem, so I can do it locally?

TeddiO commented 2 years ago

So it looks like the issue isn't to do with gm_luaerror directly, but instead there's an infinite loop when trying to handle a specific scenario.

In this particular scenario the http.Fetch (or any http* based operation) function is what's actually failing which causes gm_luaerror to attempt to handle the newly generated error, ad infinitum leading to an infinite loop.

Below is an example that should work if you dump it in to autorun/server, but at this point it's not specifically a luaerror issue anymore.

require("luaerror")
luaerror.EnableCompiletimeDetour(true)
luaerror.EnableRuntimeDetour(true)
hook.Add("LuaError", "Example", function()
    http.Fetch("https://google.com")
end)

error("This is an error")
TeddiO commented 2 years ago

Updated my previous comment with an updated example.

Having luaerror.EnableCompiletimeDetour set to true or luaerror.EnableRuntimeDetour set to true will help facilitate an infinite loop if used in conjunction with a http function and ISteamHTTP is not yet available.

TeddiO commented 2 years ago

I've included an example in gamemode format as well if that's of better / more use to you.

crash.zip

danielga commented 2 years ago

I've replicated the problem and it's easy to fix. However, I'm undecided on whether to completely disallow reentrancy or allow a couple loops before stopping.

danielga commented 2 years ago

Please try this build (when it's done).

TeddiO commented 2 years ago

For some reason Windows keeps flagging it as a virus when the download completes (gmsv_luaerror_win32.dll)

image

danielga commented 2 years ago

Tried it on my Windows Defender and it didn't report anything, although VirusTotal reports the same as you. https://www.virustotal.com/gui/file/dcac940d3f6c1bed2e8ca0ee5237943f56c0fec62acb48f4a407a996ae1ffd15

danielga commented 2 years ago

Not much I can do, I'm afraid. Detouring and signature scanning seems like relative common things for viruses.

TeddiO commented 2 years ago

That's fair, I'll just tell Windows to ignore it, can't help false positives!

TeddiO commented 2 years ago

Yep, that works! 🎉

danielga commented 2 years ago

Just to put it out there, I went with the no reentrancy route, which means you won't receive LuaError hook calls for errors that occurred inside a LuaError.