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

[Crash]: NewGRF with multi-tile object causes OpenTTD 12.0-beta2 to crash on map generation #9527

Closed
BadBrett opened this issue Aug 31, 2021 · 7 comments

Comments

@BadBrett
Copy link

Version of OpenTTD

OpenTTD 12.0-beta2

Steps to reproduce

  1. Create a simple 2x2 object in nml with the following switch (or use attached NewGRF)
switch (FEAT_OBJECTS, SELF, switch_sprite_layouts_rocks, relative_pos) {
		relative_coord(0, 0):			spritelayout_rocks;
		relative_coord(0, 1):			spritelayout_rocks;
		relative_coord(1, 0):			spritelayout_rocks;
		relative_coord(1, 1):			spritelayout_rocks;
}
  1. Build the NewGRF with NML 0.6.0

  2. Start a new game

  3. OpenTTD will crash during map generation
    image

The same NewGRF works properly in OpenTTD 1.10.2.

Upload crash files

crash.zip
multitile_object.zip

@LordAro
Copy link
Member

LordAro commented Aug 31, 2021

The error message suggests that the object has tried to be placed on the world border - which is essentially random.

Therefore it's entirely possible it's broken in 1.10.2 (and before as well)... If you can narrow down a seed in which this reliably happens, that would be very useful

@LordAro
Copy link
Member

LordAro commented Aug 31, 2021

(gdb) bt
#0  0x00007fffcb914ed9 in RaiseException ()
   from C:\WINDOWS\System32\KernelBase.dll
#1  0x00007ff6b9e08550 in CustomAbort (signal=22)
    at C:/msys64/home/LordAro/OpenTTD/src/os/windows/crashlog_win.cpp:592
#2  0x00007fffcc16adfb in raise () from C:\WINDOWS\System32\msvcrt.dll
#3  0x00007fffcc16da29 in msvcrt!_wassert ()
   from C:\WINDOWS\System32\msvcrt.dll
#4  0x00007ff6b9ff8934 in GetTileType (tile=65569)
    at C:/msys64/home/LordAro/OpenTTD/src/tile_map.h:98
#5  0x00007ff6b9ff8aa7 in IsTileType (tile=65569, type=MP_WATER)
    at C:/msys64/home/LordAro/OpenTTD/src/tile_map.h:152
#6  0x00007ff6b9ff90ac in HasTileWaterClass (t=65569)
    at C:/msys64/home/LordAro/OpenTTD/src/water_map.h:97
#7  0x00007ff6b9ff92dd in HasTileWaterGround (t=65569)
    at C:/msys64/home/LordAro/OpenTTD/src/water_map.h:346
#8  0x00007ff6b9ffa1f4 in CmdBuildObject (tile=65313,
    flags=(DC_EXEC | DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING), p1=5, p2=0, text="")
    at C:/msys64/home/LordAro/OpenTTD/src/object_cmd.cpp:234
#9  0x00007ff6b9ffc4b4 in GenerateObjects ()
    at C:/msys64/home/LordAro/OpenTTD/src/object_cmd.cpp:772
#10 0x00007ff6b9f3522b in _GenerateWorld ()
    at C:/msys64/home/LordAro/OpenTTD/src/genworld.cpp:135
#11 0x00007ff6b9f35c2c in GenerateWorld (mode=GWM_NEWGAME, size_x=256,
    size_y=256, reset_settings=true)
    at C:/msys64/home/LordAro/OpenTTD/src/genworld.cpp:327
#12 0x00007ff6ba000b2c in MakeNewGame (from_heightmap=false,
    reset_settings=true) at C:/msys64/home/LordAro/OpenTTD/src/openttd.cpp:903
#13 0x00007ff6ba001036 in SwitchToMode (new_mode=SM_NEWGAME)
    at C:/msys64/home/LordAro/OpenTTD/src/openttd.cpp:1031
#14 0x00007ff6ba004397 in GameLoop ()
    at C:/msys64/home/LordAro/OpenTTD/src/openttd.cpp:1447
#15 0x00007ff6b9eb4617 in VideoDriver::GameLoop (this=0x26ae7e2be90)
    at C:/msys64/home/LordAro/OpenTTD/src/video/video_driver.cpp:37
#16 0x00007ff6b9eb4670 in VideoDriver::GameThread (this=0x26ae7e2be90)
    at C:/msys64/home/LordAro/OpenTTD/src/video/video_driver.cpp:44
#17 0x00007ff6b9eb4779 in VideoDriver::GameThreadThunk (drv=0x26ae7e2be90)
    at C:/msys64/home/LordAro/OpenTTD/src/video/video_driver.cpp:81
...

Basically just missing bounds checks in the CmdBuildObject function, I would guess. Although, the game seems to display the object's size as 0x0, which might be an artefact of the test grf, or might be something else...

EDIT: Aha, thought it felt familiar - see also #8276

@BadBrett
Copy link
Author

Basically just missing bounds checks in the CmdBuildObject function, I would guess. Although, the game seems to display the object's size as 0x0, which might be an artefact of the test grf, or might be something else...

EDIT: Aha, thought it felt familiar - see also #8276

I haven't been able to replicate this error on older versions. Setting count_per_map256 to 255 will cause OpenTTD 12.0-beta2 to crash pretty much every time, which I guess make sense. Setting it to a lower value makes the error less frequent.

Of course, it could still be an error with my nml, but I'm pretty sure that the size is correctly set, and it doesn't explain why the error doesn't apperar in older versions (although there could be something I'm overlooking):

item(FEAT_OBJECTS, object_rocks_1, 0) {
	property {
		class:           		"NATR";
		name:           		string(STR_NAME_ROCKS);
		climates_available:	    bitmask(CLIMATE_TROPICAL);
		size:           		[2,2];
		build_cost_multiplier:0;
		remove_cost_multiplier:0;
		introduction_date: 		date(1800,1,1);
		end_of_life_date: 		date(2000,1,1);
		object_flags:			bitmask(OBJ_FLAG_ANYTHING_REMOVE);
		height:10;
		num_views:1;
		count_per_map256:255;
	}
	graphics {
		default:        		switch_sprite_layouts_rocks;
	}
}

@LordAro
Copy link
Member

LordAro commented Aug 31, 2021

Older (released) versions don't have asserts, so that'd be why you don't see any crash - but the object that's partially off the map might cause... issues

@BadBrett
Copy link
Author

Older (released) versions don't have asserts, so that'd be why you don't see any crash - but the object that's partially off the map might cause... issues

You're right. I've done some more testing, and can indeed replicate the bug in 1.10.2 if I allow objects to be built on the map edge (by setting all edges to Freeform instead of Water). So, the difference seems to be when the bug occurs. 1.10.2 only seems to crash if the the object is actually built, while beta2 crash on the lookup.

@LordAro
Copy link
Member

LordAro commented Aug 31, 2021

Found the strange issue with the object size in the test grf - the size of the object is actually 0x02 - i.e. one of the dimensions (higher nibble) is 0. The NML looks right, but I don't speak NML/GRF, so I've no idea at what level the issue is being introduced...

@glx22
Copy link
Contributor

glx22 commented Aug 31, 2021

I checked NFO output and it is 0x22 as expected.

LordAro added a commit to LordAro/OpenTTD that referenced this issue Aug 31, 2021
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

3 participants