Skip to content

Safely throwing errors #43

@Eyoko1

Description

@Eyoko1

If a function in lua is a tailcall, it is effectively removed from the callstack. This is very important for detours as it makes them much safer.

A function is considered a tailcall if the last action of it is returning the value of a function call - it must look like this:

return func(...)

Some functions cannot follow this format since the return values of the original function must first be edited. This is a problem if the detoured function can throw an error for any reason (for example a bad argument, or the lack of one).

Fortunately this can be solved by doing this: (code given is an example from a pairs detour)

if (select("#", ...) == 0) then
    return error(string.format("bad argument #1 to '%s' (value expected)", debug.getinfo(1, "n").name))
end

Tailcalling errors means the function does not show up in the stack, but still throws errors as expected. Tailcall detours only matter if an error is thrown, so if all possible errors are accounted for using this method it is not a problem if the main detour logic isn't a tailcall.

However, currently in autorun, this does not work because both Autorun.detour and Autorun.copyFastFunction do not tailcall the callbacks meaning that if they throw errors, the detour handler will be revealed to xpcall / pcall, or the stack trace.

I don't really have any suggestions for fixing this yet since I am not very experienced in using the C API, but what we need is a way of throwing errors in lua and having the handler made in Rust not appear in the stack

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions