FakeFishGames / Barotrauma

A 2D online multiplayer game taking place in a submarine travelling through the icy depths of Jupiter's moon Europa.
http://www.barotraumagame.com/
1.72k stars 401 forks source link

Infinite Recursion Caused by CharacterInfo.HeadSprite #12637

Closed MapleWheels closed 7 months ago

MapleWheels commented 1 year ago

message (7).txt message (6).txt

Disclaimers

What happened?

This call stack overflow (infinite recursion) bug seems to have been triggered by Improved Husks. However, the crash Stack Trace, attached logs and a code review shows that the issue is caused by CharacterInfo.HeadSprite being checked on Line 509: GetSpritePath() of Limb.cs for being null is causing a call loop since accessing the property when null causes a null check and initialization process that involves calling GetSpritePath().

I have attached the partial log saved by running the game from Command Prompt (to catch the VM crash).

message (7).txt

Reproduction steps

Access (get) CharacterInfo.HeadSprite while it is null from any method called from CharacterInfo::LoadHeadSprite().

Edit: More in-depth details:

There is a Call Recursion Loop because;

  1. The HeadSprite property when accessed in the null checking statement in GetSpritePath, this called the compiler-generated get_HeadSprite() method on Line 377 of CharacterInfo.
  2. In this method, there is also a null check, which when true makes a call to CharacterInfo::LoopHeadSprite().
  3. From here a call is made to LoadHeadSpriteProjectSpecific() wherein, on Line 50, if tintMaskPath is not null or empty, creates a new Sprite while invoking Limb.GeSpritePath() in the parameters.
  4. In GeSpritePath(), At Line 509, there is a Property Accessor call when characterInfo.HeadSprite != null is evaluated, which called the compiler-generated get_HeadSprite() method and return to Step 1.

Bug prevalence

Happens regularly

Single player or multiplayer?

Multiplayer hosted from the in-game menu (= using a listen server)

-

No response

Version

v1.0.21.0

-

No response

Which operating system did you encounter this bug on?

Windows

Relevant error messages and crash reports

NilanthAnimosus commented 1 year ago

Thanks for the report!

Gave this a test but was unable to reproduce it using the mentioned mod, The reproduction steps may invoke the problem but theres many areas of the game you could cause problems just invoking the code in unintended ways, and without it being done through gameplay means the real question is not that it has an error when its supplied with null here, but why and what scenario caused it occur as well, if it causes issues in other areas, and if its an issue where that null shouldn't be null to begin with (Such as an issue elsewhere).

I've tried a number of things to get this to occur, but it would be helpful to get a more clear picture, such as a modlist / list of mods used, What you were doing to cause the problem to the best you know of to replicate it, and any other potential useful information to trigger the crash?

MapleWheels commented 1 year ago

Here's the mod list, as requested. You will need to get to Biome 3. Seems to trigger when Human Immortals are involved.

Also, this error is as I've described and is a vanilla bug, mod triggered or not. It just seems that it's not been an issue until now.

There is a Call Recursion Loop because;

  1. The HeadSprite property when accessed in the null checking statement in GetSpritePath, this called the compiler-generated get_HeadSprite() method on Line 377 of CharacterInfo.
  2. In this method, there is also a null check, which when true makes a call to CharacterInfo::LoopHeadSprite().
  3. From here a call is made to LoadHeadSpriteProjectSpecific() wherein, on Line 50, if tintMaskPath is not null or empty, creates a new Sprite while invoking Limb.GeSpritePath() in the parameters.
  4. In GeSpritePath(), At Line 509, there is a Property Accessor call when characterInfo.HeadSprite != null is evaluated, which called the compiler-generated get_HeadSprite() method and return to Step 1.

This does not require more info I don't think. Maybe something else in the modlist caused this crash. However, this StackOverflow crash does not generate a crashlog under normal conditions and so it probably wasn't reported until it was captured by my IDE and running dotnet <application>.

For regular players, this produces an immediate crash to desktop with no logs or anything. This error may be more prevalent but underreported.

modlist_of_all_time.txt

NilanthAnimosus commented 11 months ago

Reproduced on release/traitor-update commit https://github.com/Regalis11/Barotrauma-development/commit/1bdad5950bda108b51afb178289e6f2d566b1544 by spawning "humanshambler" ingame, after a few spawns using the provided modlist below will cause a headsprite overflow.

Headsprite overflow.zip

The two mods needed are "Robotrauma" then "Improved Husks" loaded.

MapleWheels commented 11 months ago

Reproduced on release/traitor-update commit https://github.com/Regalis11/Barotrauma-development/commit/1bdad5950bda108b51afb178289e6f2d566b1544 by spawning "humanshambler" ingame, after a few spawns using the provided modlist below will cause a headsprite overflow.

Headsprite overflow.zip

The two mods needed are "Robotrauma" then "Improved Husks" loaded.

Thank you for testing this.

MapleWheels commented 10 months ago

Any updates on this?

itchyOwl commented 10 months ago

No, sorry. Haven't had time to look into it yet. I will, but might take a while before this gets into a released version...

Regalis11 commented 9 months ago

Fixed in https://github.com/Regalis11/Barotrauma-development/commit/79c6ebe70c6201c7326f64da481f8afe52abe34e

3e849f2e5c commented 7 months ago

Tested, wasn't able to repro the recursion crash but encountered another crash, not sure if it's within the scope of this PR or if it's something else misconfigured in the mod

System.NullReferenceException: Object reference not set to an instance of an object.
   at Barotrauma.Limb.Draw(SpriteBatch spriteBatch, Camera cam, Nullable`1 overrideColor, Boolean disableDeformations) in E:\Barotrauma-development\Barotrauma\BarotraumaClient\ClientSource\Characters\Limb.cs:line 792
   at Barotrauma.Ragdoll.Draw(SpriteBatch spriteBatch, Camera cam) in E:\Barotrauma-development\Barotrauma\BarotraumaClient\ClientSource\Characters\Animation\Ragdoll.cs:line 519
   at Barotrauma.Character.Draw(SpriteBatch spriteBatch, Camera cam) in E:\Barotrauma-development\Barotrauma\BarotraumaClient\ClientSource\Characters\Character.cs:line 818
   at Barotrauma.GameScreen.<>c__DisplayClass32_0.<DrawMap>g__DrawCharacters|4(Boolean deformed, Boolean firstPass) in E:\Barotrauma-development\Barotrauma\BarotraumaClient\ClientSource\Screens\GameScreen.cs:line 296
   at Barotrauma.GameScreen.DrawMap(GraphicsDevice graphics, SpriteBatch spriteBatch, Double deltaTime) in E:\Barotrauma-development\Barotrauma\BarotraumaClient\ClientSource\Screens\GameScreen.cs:line 267
   at Barotrauma.GameScreen.Draw(Double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch) in E:\Barotrauma-development\Barotrauma\BarotraumaClient\ClientSource\Screens\GameScreen.cs:line 122
   at Barotrauma.GameMain.Draw(GameTime gameTime) in E:\Barotrauma-development\Barotrauma\BarotraumaClient\ClientSource\GameMain.cs:line 985
   at Microsoft.Xna.Framework.Game.DoDraw(GameTime gameTime) in E:\Barotrauma-development\Libraries\MonoGame.Framework\Src\MonoGame.Framework\Game.cs:line 666
   at Microsoft.Xna.Framework.Game.Tick() in E:\Barotrauma-development\Libraries\MonoGame.Framework\Src\MonoGame.Framework\Game.cs:line 508
   at Microsoft.Xna.Framework.SdlGamePlatform.RunLoop() in E:\Barotrauma-development\Libraries\MonoGame.Framework\Src\MonoGame.Framework\SDL\SDLGamePlatform.cs:line 94
   at Microsoft.Xna.Framework.Game.Run(GameRunBehavior runBehavior) in E:\Barotrauma-development\Libraries\MonoGame.Framework\Src\MonoGame.Framework\Game.cs:line 397
   at Microsoft.Xna.Framework.Game.Run() in E:\Barotrauma-development\Libraries\MonoGame.Framework\Src\MonoGame.Framework\Game.cs:line 367
   at Barotrauma.Program.Main(String[] args) in E:\Barotrauma-development\Barotrauma\BarotraumaClient\ClientSource\Program.cs:line 58
3e849f2e5c commented 7 months ago

Tested, unable to repro a hard crash using the 2 mods