Skip to content

Infinite loop in LatteSHRC_RemoveFromCaches when removing a non-head shader from a chain #1979

Description

@1e1

Summary

LatteSHRC_RemoveFromCaches (src/Cafe/HW/Latte/Core/LatteShader.cpp, ~line 182) can spin forever when the shader being removed is not the first entry of its cache chain, hard-hanging the emulator.

Details

The chain-walk loop never advances shaderChain:

LatteDecompilerShader* shaderChain = baseIt->second;
while (shaderChain->next)
{
    if (shaderChain->next == shader)
    {
        shaderChain->next = shaderChain->next->next;
        removed = true;
        break;
    }
    // shaderChain is never advanced -> infinite loop if the target isn't the first 'next'
}

When shaderChain->next != shader, neither the loop condition nor the body changes, so it loops forever. It only terminates when the target happens to be the head's direct next.

Trigger

Reachable from the async deleteShader path (LatteAsyncCommandsLatteSHRC_RemoveFromCacheByHashRemoveFromCaches) when a shader resolves to a non-head aux variant of a chain with 2+ members.

Suggested direction

Advance the pointer at the end of the loop body (shaderChain = shaderChain->next;).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions