Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Game Freeze due to while loop with no timeout #81

Open
drojf opened this issue Aug 15, 2022 · 0 comments
Open

Game Freeze due to while loop with no timeout #81

drojf opened this issue Aug 15, 2022 · 0 comments

Comments

@drojf
Copy link
Contributor

drojf commented Aug 15, 2022

I trying to deliberately trigger the stuck sprite bug, but instead caused the game to freeze (not crash). By printing out the stack trace, it seems this happens due to a while loop which never terminates.

On Matsuribayashi ch8, here an edited _mats_op.txt which causes the crash near the start (completely unreasonable script, but it probably shouldn't crash):

_mats_op.txt

The while loop appears in a couple places (there may be more than the below):

public void DrawBustshot(int layer, string textureName, int x, int y, int z, int oldx, int oldy, int oldz, bool move, int priority, int type, float wait, bool isblocking)
{
if (MODSkipImage(textureName))
{
return;
}
Layer i = GetLayer(layer);
while (i.FadingOut)
{
i.HideLayer();
i = GetLayer(layer);
}

public void FadeBustshotWithFiltering(int layer, string mask, int style, float wait, bool isblocking)
{
Layer layer2 = GetLayer(layer);
while (layer2.FadingOut)
{
layer2.HideLayer();
layer2 = GetLayer(layer);
}

public void DrawBustshotWithFiltering(int layer, string textureName, string mask, int x, int y, int z, int originx, int originy, int oldx, int oldy, int oldz, bool move, int priority, int type, float wait, bool isblocking)
{
Layer i = GetLayer(layer);
while (i.FadingOut)
{
i.HideLayer();
i = GetLayer(layer);
}

It may be a good idea to add a timeout to the while loop, so at least the game doesn't crash, however doing so may put the game in an unknown state, so not sure what action should be taken if the timeout occurs.


The while loop relies on layer.FadingOut being set to false, which only happens once ReleaseTextures() is called (which is inside HideLayer()).

However, ReleaseTextures() won't set layer.FadingOut to false if primary (the primary texture for that layer) is null. primary is deliberately set to null in ReleaseTextures(), but I think it's also possible if the primary texture is destroyed or cleaned up by Unity for it to be set to null. So relying on layer.FadingOut to end the while loop seems dangerous.

public void ReleaseTextures()
{
if (!(primary == null))
{
ReleaseSecondaryTexture();
ReleaseMaskTexture();
Object.Destroy(primary);
primary = null;
material.shader = shaderDefault;
material.SetTexture("_Primary", null);
meshRenderer.enabled = false;
PrimaryName = string.Empty;
SecondaryName = string.Empty;
MaskName = string.Empty;
Object.Destroy(mesh);
mesh = null;
meshFilter.mesh = null;
FadingOut = false;
shaderType = 0;
targetAngle = 0f;
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant