Skip to content

luau_getinfo ensure when used immediately after a LOP_CALL Instruction #1369

Closed
@kalebs-anotheraxiom

Description

@kalebs-anotheraxiom

I'm currently in the process of implementing a luau debugger and have ran into one small issue

If you are running in step mode and breaking at every single instruction (The user is wanting to step forward for example), Once a LOP_CALL instruction is reached whenever you next call lua_getinfo a few odd conditions and assumptions are broken

When you call lua_getinfo and inside of the auxgetinfo call during the caculation of the current line

case 'l':
        {
            if (ci)
            {
/*=========>*/  ar->currentline = isLua(ci) ? currentline(L, ci) : -1;
            }
            else
            {
                ar->currentline = f->isC ? -1 : f->l.p->linedefined;
            }

            break;
        }

currentline(L, ci) is called. This is the call that ensures

current line is defined as follows and currentpc is the reason for the ensure

    return luaG_getline(ci_func(ci)->l.p, currentpc(L, ci));

The main issue is that currentpc returns -1 which immediately hits an ensure on the luaG_getline call

There's not much documentation on the very very internals of the lua/Luau engine but after doing some investigation my best guess as to what's happening is that CallInfo->savedpc (Which im guessing stands for procedure call) is exactly equal to the stacks current closure instruction pointer

the currentcp line uses pcRel

#define pcRel(pc, p) ((pc) ? cast_to(int, (pc) - (p)->code) - 1 : 0)

Which just subtracts the CallInfo's Procedure call from the targeted closure (In this case we are targeting level 0 so the top most closure) code pointer and subtracts 1 (Not sure why exactly but I'm guessing its due to things starting at 1) . And because this is Immediately after a
LOP_CALL the current closures code start and the call info's pc are equal.

This -1 value then hits the first ENSURE block of luaG_getline, And also returns junk data

I'm not entirely sure the best way to fix this but my suggestion would be to change

int luaG_getline(Proto* p, int pc)
{
    LUAU_ASSERT(pc >= 0 && pc < p->sizecode);

    if (!p->lineinfo)
        return 0;

    return p->abslineinfo[pc >> p->linegaplog2] + p->lineinfo[pc];
}

to

int luaG_getline(Proto* p, int pc)
{
    LUAU_ASSERT(pc >= -1 && pc < p->sizecode);
    
    if (pc == -1)
        return 0;
        
    if (!p->lineinfo)
        return 0;

    return p->abslineinfo[pc >> p->linegaplog2] + p->lineinfo[pc];
}

It's not the best solution but it's the one with the least changes needed

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions