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

Fix thread safety issues around the cursor and cursor sprites in the OpenGL backends #8993

Merged
merged 2 commits into from Apr 10, 2021

Conversation

JGRennison
Copy link
Contributor

@JGRennison JGRennison commented Apr 10, 2021

Motivation / Problem

The main/OpenGL thread unnecessarily gets the cursor sprites from the global sprite cache without holding any locks.
The OpenGL does cache the cursor sprites along with the associated sprite data, but it still looks up some of the sprite properties form the sprite cache each time.
The sprite cache, sprite processing and everything to do with fio cannot be used from more than one thread at once.
In the case where the cursor sprites are already in the cache this results in the race conditions listed in #8870.
In the case where the cursor sprites need to be added to the cache the additional race conditions listed below occur.
In the case where two threads end up writing sprites into the sprite cache at the same time, such as after the sprite cache has been cleared, the two threads writing over each other could cause the sort of invalid state induced crash seen in #8977.

Additionally, a number of cursor state properties are accessed without holding the required lock.

Additional race conditions when OpenGLBackend::DrawMouseCursor inserts a sprite into the cache
==================
WARNING: ThreadSanitizer: data race (pid=1195394)
Write of size 8 at 0x7b9800039040 by thread T3 (mutexes: write M721):
  #0 memset <null> (libtsan.so.0+0x3792f)
  #1 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:66 (openttd+0xd5c48f)
  #2 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #3 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #4 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #5 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #6 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #7 GetSprite /home/jgr/misc/openttd-2/src/spritecache.h:43 (openttd+0x140d637)
  #8 VehicleSpriteSeq::GetBounds(Rect*) const /home/jgr/misc/openttd-2/src/vehicle.cpp:102 (openttd+0x140e31d)
  #9 Vehicle::UpdateBoundingBoxCoordinates(bool) const /home/jgr/misc/openttd-2/src/vehicle.cpp:1610 (openttd+0x1415589)
  #10 Vehicle::UpdateViewport(bool) /home/jgr/misc/openttd-2/src/vehicle.cpp:1644 (openttd+0x1415959)
  #11 SpecializedVehicle<Train, (VehicleType)0>::UpdateViewport(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../vehicle_base.h:1222 (openttd+0xf512a5)
  #12 GroundVehicle<Train, (VehicleType)0>::UpdateInclination(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../ground_vehicle.hpp:242 (openttd+0xf4f36e)
  #13 TrainController(Train*, Vehicle*, bool) /home/jgr/misc/openttd-2/src/train_cmd.cpp:3356 (openttd+0x13ead0a)
  #14 TrainLocoHandler /home/jgr/misc/openttd-2/src/train_cmd.cpp:3848 (openttd+0x13ecaf0)
  #15 Train::Tick() /home/jgr/misc/openttd-2/src/train_cmd.cpp:3920 (openttd+0x13ecf90)
  #16 CallVehicleTicks() /home/jgr/misc/openttd-2/src/vehicle.cpp:961 (openttd+0x1411dc7)
  #17 StateGameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1400 (openttd+0x116d5ed)
  #18 GameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1506 (openttd+0x116dd44)
  #19 VideoDriver::GameLoop() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:36 (openttd+0xd7d6b3)
  #20 VideoDriver::GameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:43 (openttd+0xd7d73d)
  #21 VideoDriver::GameThreadThunk(VideoDriver*) /home/jgr/misc/openttd-2/src/video/video_driver.cpp:80 (openttd+0xd7d8b0)
  #22 StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}::operator()(char const*, void (*&&)(VideoDriver*), VideoDriver*&&) const /home/jgr/misc/openttd-2/src/video/../thread.h:54 (openttd+0xd7eda6)
  #23 void std::__invoke_impl<void, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*>(std::__invoke_other, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&&&)(VideoDriver*), VideoDriver*&&)#1}, char const*&&, void (*&&)(VideoDriver*), VideoDriver*&&) /usr/include/c++/9/bits/invoke.h:60 (openttd+0xd8023a)
  #24 _ZSt8__invokeIZ14StartNewThreadIPFvP11VideoDriverEJS2_EEbPSt6threadPKcOT_DpOT0_EUlS8_OS4_OS2_E_JS8_S4_S2_EENSt15__invoke_resultIS9_JDpSB_EE4typeESA_SD_ /usr/include/c++/9/bits/invoke.h:95 (openttd+0xd80063)
  #25 void std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::_M_invoke<0ul, 1ul, 2ul, 3ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) /usr/include/c++/9/thread:244 (openttd+0xd7fea0)
  #26 std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::operator()() /usr/include/c++/9/thread:251 (openttd+0xd7fdee)
  #27 std::thread::_State_impl<std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> > >::_M_run() /usr/include/c++/9/thread:195 (openttd+0xd7fda0)
  #28 <null> <null> (libstdc++.so.6+0xd6d83)

Previous read of size 1 at 0x7b9800039047 by main thread:
  #0 Sprite* Blitter_32bppOptimized::EncodeInternal<false>(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/32bpp_optimized.cpp:347 (openttd+0xa626a3)
  #1 Blitter_40bppAnim::Encode(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/40bpp_anim.cpp:383 (openttd+0xa9d8f9)
  #2 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:498 (openttd+0x1297820)
  #3 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #4 GetSprite /home/jgr/misc/openttd-2/src/video/../blitter/../spritecache.h:43 (openttd+0xd5ce11)
  #5 OpenGLBackend::DrawMouseCursor() /home/jgr/misc/openttd-2/src/video/opengl.cpp:1063 (openttd+0xd62020)
  #6 VideoDriver_SDL_OpenGL::Paint() /home/jgr/misc/openttd-2/src/video/sdl2_opengl_v.cpp:177 (openttd+0xd7b2c8)
  #7 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:178 (openttd+0xd7e23d)
  #8 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #9 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #10 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #11 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Location is heap block of size 11520 at 0x7b9800039000 allocated by main thread:
  #0 calloc <null> (libtsan.so.0+0x305ca)
  #1 CallocT<SpriteLoader::CommonPixel> /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_func.hpp:94 (openttd+0xd5c6a3)
  #2 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:63 (openttd+0xd5c429)
  #3 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #4 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #5 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #6 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #7 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #8 GetSprite /home/jgr/misc/openttd-2/src/blitter/../spritecache.h:43 (openttd+0x1462527)
  #9 AddSortableSpriteToDraw(unsigned int, unsigned int, int, int, int, int, int, int, bool, int, int, int, SubSprite const*) /home/jgr/misc/openttd-2/src/viewport.cpp:689 (openttd+0x1464a59)
  #10 DrawCommonTileSeq(TileInfo const*, DrawTileSprites const*, TransparencyOption, int, unsigned int, unsigned int, bool) /home/jgr/misc/openttd-2/src/sprite.cpp:58 (openttd+0x12945c5)
  #11 DrawNewGRFTileSeq /home/jgr/misc/openttd-2/src/sprite.h:126 (openttd+0x110eb3c)
  #12 IndustryDrawTileLayout /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:178 (openttd+0x111008a)
  #13 DrawNewIndustryTile(TileInfo*, Industry*, unsigned short, IndustryTileSpec const*) /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:211 (openttd+0x1110497)
  #14 DrawTile_Industry /home/jgr/misc/openttd-2/src/industry_cmd.cpp:332 (openttd+0xf7c31b)
  #15 ViewportAddLandscape /home/jgr/misc/openttd-2/src/viewport.cpp:1272 (openttd+0x1467243)
  #16 ViewportDoDraw(Viewport const*, int, int, int, int) /home/jgr/misc/openttd-2/src/viewport.cpp:1736 (openttd+0x146b3b8)
  #17 ViewportDraw /home/jgr/misc/openttd-2/src/viewport.cpp:1799 (openttd+0x146bbd6)
  #18 Window::DrawViewport() const /home/jgr/misc/openttd-2/src/viewport.cpp:1819 (openttd+0x146bda2)
  #19 NWidgetViewport::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1922 (openttd+0x14a4867)
  #20 NWidgetPIPContainer::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1120 (openttd+0x149e55d)
  #21 Window::DrawWidgets() const /home/jgr/misc/openttd-2/src/widget.cpp:604 (openttd+0x149c239)
  #22 MainWindow::OnPaint() /home/jgr/misc/openttd-2/src/main_gui.cpp:235 (openttd+0x10060aa)
  #23 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:948 (openttd+0x14af85a)
  #24 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #25 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #26 DrawOverlappedWindowForAll(int, int, int, int) /home/jgr/misc/openttd-2/src/window.cpp:974 (openttd+0x14afb49)
  #27 RedrawScreenRect(int, int, int, int) /home/jgr/misc/openttd-2/src/gfx.cpp:1453 (openttd+0xef33d0)
  #28 DrawDirtyBlocks() /home/jgr/misc/openttd-2/src/gfx.cpp:1528 (openttd+0xef371b)
  #29 UpdateWindows() /home/jgr/misc/openttd-2/src/window.cpp:3204 (openttd+0x14ba724)
  #30 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:171 (openttd+0xd7e19e)
  #31 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #32 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #33 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #34 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Mutex M721 (0x7b6400005f38) created at:
  #0 pthread_mutex_lock <null> (libtsan.so.0+0x5271c)
  #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:749 (openttd+0xb23b59)
  #2 std::mutex::lock() /usr/include/c++/9/bits/std_mutex.h:100 (openttd+0xb2552a)
  #3 std::lock_guard<std::mutex>::lock_guard(std::mutex&) /usr/include/c++/9/bits/std_mutex.h:159 (openttd+0xb2931a)
  #4 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:157 (openttd+0xd7e07d)
  #5 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #6 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #7 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #8 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Thread T3 'ottd:game' (tid=1195403, running) created by main thread at:
  #0 pthread_create <null> (libtsan.so.0+0x5ea99)
  #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd7048)
  #2 bool StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&) /home/jgr/misc/openttd-2/src/video/../thread.h:49 (openttd+0xd7ee62)
  #3 VideoDriver::StartGameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:86 (openttd+0xd7d95b)
  #4 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:657 (openttd+0xd7324a)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

SUMMARY: ThreadSanitizer: data race (/usr/lib/x86_64-linux-gnu/libtsan.so.0+0x3792f) in memset
==================
==================
WARNING: ThreadSanitizer: data race (pid=1195394)
Write of size 8 at 0x7b98000390a0 by thread T3 (mutexes: write M721):
  #0 memset <null> (libtsan.so.0+0x3792f)
  #1 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:66 (openttd+0xd5c48f)
  #2 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #3 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #4 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #5 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #6 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #7 GetSprite /home/jgr/misc/openttd-2/src/spritecache.h:43 (openttd+0x140d637)
  #8 VehicleSpriteSeq::GetBounds(Rect*) const /home/jgr/misc/openttd-2/src/vehicle.cpp:102 (openttd+0x140e31d)
  #9 Vehicle::UpdateBoundingBoxCoordinates(bool) const /home/jgr/misc/openttd-2/src/vehicle.cpp:1610 (openttd+0x1415589)
  #10 Vehicle::UpdateViewport(bool) /home/jgr/misc/openttd-2/src/vehicle.cpp:1644 (openttd+0x1415959)
  #11 SpecializedVehicle<Train, (VehicleType)0>::UpdateViewport(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../vehicle_base.h:1222 (openttd+0xf512a5)
  #12 GroundVehicle<Train, (VehicleType)0>::UpdateInclination(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../ground_vehicle.hpp:242 (openttd+0xf4f36e)
  #13 TrainController(Train*, Vehicle*, bool) /home/jgr/misc/openttd-2/src/train_cmd.cpp:3356 (openttd+0x13ead0a)
  #14 TrainLocoHandler /home/jgr/misc/openttd-2/src/train_cmd.cpp:3848 (openttd+0x13ecaf0)
  #15 Train::Tick() /home/jgr/misc/openttd-2/src/train_cmd.cpp:3920 (openttd+0x13ecf90)
  #16 CallVehicleTicks() /home/jgr/misc/openttd-2/src/vehicle.cpp:961 (openttd+0x1411dc7)
  #17 StateGameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1400 (openttd+0x116d5ed)
  #18 GameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1506 (openttd+0x116dd44)
  #19 VideoDriver::GameLoop() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:36 (openttd+0xd7d6b3)
  #20 VideoDriver::GameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:43 (openttd+0xd7d73d)
  #21 VideoDriver::GameThreadThunk(VideoDriver*) /home/jgr/misc/openttd-2/src/video/video_driver.cpp:80 (openttd+0xd7d8b0)
  #22 StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}::operator()(char const*, void (*&&)(VideoDriver*), VideoDriver*&&) const /home/jgr/misc/openttd-2/src/video/../thread.h:54 (openttd+0xd7eda6)
  #23 void std::__invoke_impl<void, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*>(std::__invoke_other, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&&&)(VideoDriver*), VideoDriver*&&)#1}, char const*&&, void (*&&)(VideoDriver*), VideoDriver*&&) /usr/include/c++/9/bits/invoke.h:60 (openttd+0xd8023a)
  #24 _ZSt8__invokeIZ14StartNewThreadIPFvP11VideoDriverEJS2_EEbPSt6threadPKcOT_DpOT0_EUlS8_OS4_OS2_E_JS8_S4_S2_EENSt15__invoke_resultIS9_JDpSB_EE4typeESA_SD_ /usr/include/c++/9/bits/invoke.h:95 (openttd+0xd80063)
  #25 void std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::_M_invoke<0ul, 1ul, 2ul, 3ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) /usr/include/c++/9/thread:244 (openttd+0xd7fea0)
  #26 std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::operator()() /usr/include/c++/9/thread:251 (openttd+0xd7fdee)
  #27 std::thread::_State_impl<std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> > >::_M_run() /usr/include/c++/9/thread:195 (openttd+0xd7fda0)
  #28 <null> <null> (libstdc++.so.6+0xd6d83)

Previous read of size 1 at 0x7b98000390a3 by main thread:
  #0 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:244 (openttd+0x1295bb4)
  #1 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #2 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #3 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #4 GetSprite /home/jgr/misc/openttd-2/src/video/../blitter/../spritecache.h:43 (openttd+0xd5ce11)
  #5 OpenGLBackend::DrawMouseCursor() /home/jgr/misc/openttd-2/src/video/opengl.cpp:1063 (openttd+0xd62020)
  #6 VideoDriver_SDL_OpenGL::Paint() /home/jgr/misc/openttd-2/src/video/sdl2_opengl_v.cpp:177 (openttd+0xd7b2c8)
  #7 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:178 (openttd+0xd7e23d)
  #8 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #9 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #10 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #11 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Location is heap block of size 11520 at 0x7b9800039000 allocated by main thread:
  #0 calloc <null> (libtsan.so.0+0x305ca)
  #1 CallocT<SpriteLoader::CommonPixel> /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_func.hpp:94 (openttd+0xd5c6a3)
  #2 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:63 (openttd+0xd5c429)
  #3 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #4 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #5 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #6 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #7 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #8 GetSprite /home/jgr/misc/openttd-2/src/blitter/../spritecache.h:43 (openttd+0x1462527)
  #9 AddSortableSpriteToDraw(unsigned int, unsigned int, int, int, int, int, int, int, bool, int, int, int, SubSprite const*) /home/jgr/misc/openttd-2/src/viewport.cpp:689 (openttd+0x1464a59)
  #10 DrawCommonTileSeq(TileInfo const*, DrawTileSprites const*, TransparencyOption, int, unsigned int, unsigned int, bool) /home/jgr/misc/openttd-2/src/sprite.cpp:58 (openttd+0x12945c5)
  #11 DrawNewGRFTileSeq /home/jgr/misc/openttd-2/src/sprite.h:126 (openttd+0x110eb3c)
  #12 IndustryDrawTileLayout /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:178 (openttd+0x111008a)
  #13 DrawNewIndustryTile(TileInfo*, Industry*, unsigned short, IndustryTileSpec const*) /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:211 (openttd+0x1110497)
  #14 DrawTile_Industry /home/jgr/misc/openttd-2/src/industry_cmd.cpp:332 (openttd+0xf7c31b)
  #15 ViewportAddLandscape /home/jgr/misc/openttd-2/src/viewport.cpp:1272 (openttd+0x1467243)
  #16 ViewportDoDraw(Viewport const*, int, int, int, int) /home/jgr/misc/openttd-2/src/viewport.cpp:1736 (openttd+0x146b3b8)
  #17 ViewportDraw /home/jgr/misc/openttd-2/src/viewport.cpp:1799 (openttd+0x146bbd6)
  #18 Window::DrawViewport() const /home/jgr/misc/openttd-2/src/viewport.cpp:1819 (openttd+0x146bda2)
  #19 NWidgetViewport::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1922 (openttd+0x14a4867)
  #20 NWidgetPIPContainer::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1120 (openttd+0x149e55d)
  #21 Window::DrawWidgets() const /home/jgr/misc/openttd-2/src/widget.cpp:604 (openttd+0x149c239)
  #22 MainWindow::OnPaint() /home/jgr/misc/openttd-2/src/main_gui.cpp:235 (openttd+0x10060aa)
  #23 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:948 (openttd+0x14af85a)
  #24 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #25 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #26 DrawOverlappedWindowForAll(int, int, int, int) /home/jgr/misc/openttd-2/src/window.cpp:974 (openttd+0x14afb49)
  #27 RedrawScreenRect(int, int, int, int) /home/jgr/misc/openttd-2/src/gfx.cpp:1453 (openttd+0xef33d0)
  #28 DrawDirtyBlocks() /home/jgr/misc/openttd-2/src/gfx.cpp:1528 (openttd+0xef371b)
  #29 UpdateWindows() /home/jgr/misc/openttd-2/src/window.cpp:3204 (openttd+0x14ba724)
  #30 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:171 (openttd+0xd7e19e)
  #31 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #32 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #33 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #34 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Mutex M721 (0x7b6400005f38) created at:
  #0 pthread_mutex_lock <null> (libtsan.so.0+0x5271c)
  #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:749 (openttd+0xb23b59)
  #2 std::mutex::lock() /usr/include/c++/9/bits/std_mutex.h:100 (openttd+0xb2552a)
  #3 std::lock_guard<std::mutex>::lock_guard(std::mutex&) /usr/include/c++/9/bits/std_mutex.h:159 (openttd+0xb2931a)
  #4 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:157 (openttd+0xd7e07d)
  #5 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #6 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #7 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #8 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Thread T3 'ottd:game' (tid=1195403, running) created by main thread at:
  #0 pthread_create <null> (libtsan.so.0+0x5ea99)
  #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd7048)
  #2 bool StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&) /home/jgr/misc/openttd-2/src/video/../thread.h:49 (openttd+0xd7ee62)
  #3 VideoDriver::StartGameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:86 (openttd+0xd7d95b)
  #4 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:657 (openttd+0xd7324a)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

SUMMARY: ThreadSanitizer: data race (/usr/lib/x86_64-linux-gnu/libtsan.so.0+0x3792f) in memset
==================
==================
WARNING: ThreadSanitizer: data race (pid=1195394)
Write of size 8 at 0x7b98000390c0 by thread T3 (mutexes: write M721):
  #0 memset <null> (libtsan.so.0+0x3792f)
  #1 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:66 (openttd+0xd5c48f)
  #2 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #3 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #4 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #5 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #6 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #7 GetSprite /home/jgr/misc/openttd-2/src/spritecache.h:43 (openttd+0x140d637)
  #8 VehicleSpriteSeq::GetBounds(Rect*) const /home/jgr/misc/openttd-2/src/vehicle.cpp:102 (openttd+0x140e31d)
  #9 Vehicle::UpdateBoundingBoxCoordinates(bool) const /home/jgr/misc/openttd-2/src/vehicle.cpp:1610 (openttd+0x1415589)
  #10 Vehicle::UpdateViewport(bool) /home/jgr/misc/openttd-2/src/vehicle.cpp:1644 (openttd+0x1415959)
  #11 SpecializedVehicle<Train, (VehicleType)0>::UpdateViewport(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../vehicle_base.h:1222 (openttd+0xf512a5)
  #12 GroundVehicle<Train, (VehicleType)0>::UpdateInclination(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../ground_vehicle.hpp:242 (openttd+0xf4f36e)
  #13 TrainController(Train*, Vehicle*, bool) /home/jgr/misc/openttd-2/src/train_cmd.cpp:3356 (openttd+0x13ead0a)
  #14 TrainLocoHandler /home/jgr/misc/openttd-2/src/train_cmd.cpp:3848 (openttd+0x13ecaf0)
  #15 Train::Tick() /home/jgr/misc/openttd-2/src/train_cmd.cpp:3920 (openttd+0x13ecf90)
  #16 CallVehicleTicks() /home/jgr/misc/openttd-2/src/vehicle.cpp:961 (openttd+0x1411dc7)
  #17 StateGameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1400 (openttd+0x116d5ed)
  #18 GameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1506 (openttd+0x116dd44)
  #19 VideoDriver::GameLoop() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:36 (openttd+0xd7d6b3)
  #20 VideoDriver::GameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:43 (openttd+0xd7d73d)
  #21 VideoDriver::GameThreadThunk(VideoDriver*) /home/jgr/misc/openttd-2/src/video/video_driver.cpp:80 (openttd+0xd7d8b0)
  #22 StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}::operator()(char const*, void (*&&)(VideoDriver*), VideoDriver*&&) const /home/jgr/misc/openttd-2/src/video/../thread.h:54 (openttd+0xd7eda6)
  #23 void std::__invoke_impl<void, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*>(std::__invoke_other, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&&&)(VideoDriver*), VideoDriver*&&)#1}, char const*&&, void (*&&)(VideoDriver*), VideoDriver*&&) /usr/include/c++/9/bits/invoke.h:60 (openttd+0xd8023a)
  #24 _ZSt8__invokeIZ14StartNewThreadIPFvP11VideoDriverEJS2_EEbPSt6threadPKcOT_DpOT0_EUlS8_OS4_OS2_E_JS8_S4_S2_EENSt15__invoke_resultIS9_JDpSB_EE4typeESA_SD_ /usr/include/c++/9/bits/invoke.h:95 (openttd+0xd80063)
  #25 void std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::_M_invoke<0ul, 1ul, 2ul, 3ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) /usr/include/c++/9/thread:244 (openttd+0xd7fea0)
  #26 std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::operator()() /usr/include/c++/9/thread:251 (openttd+0xd7fdee)
  #27 std::thread::_State_impl<std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> > >::_M_run() /usr/include/c++/9/thread:195 (openttd+0xd7fda0)
  #28 <null> <null> (libstdc++.so.6+0xd6d83)

Previous read of size 1 at 0x7b98000390c2 by main thread:
  #0 Sprite* Blitter_32bppOptimized::EncodeInternal<false>(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/32bpp_optimized.cpp:344 (openttd+0xa62615)
  #1 Blitter_40bppAnim::Encode(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/40bpp_anim.cpp:383 (openttd+0xa9d8f9)
  #2 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:498 (openttd+0x1297820)
  #3 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #4 GetSprite /home/jgr/misc/openttd-2/src/video/../blitter/../spritecache.h:43 (openttd+0xd5ce11)
  #5 OpenGLBackend::DrawMouseCursor() /home/jgr/misc/openttd-2/src/video/opengl.cpp:1063 (openttd+0xd62020)
  #6 VideoDriver_SDL_OpenGL::Paint() /home/jgr/misc/openttd-2/src/video/sdl2_opengl_v.cpp:177 (openttd+0xd7b2c8)
  #7 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:178 (openttd+0xd7e23d)
  #8 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #9 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #10 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #11 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Location is heap block of size 11520 at 0x7b9800039000 allocated by main thread:
  #0 calloc <null> (libtsan.so.0+0x305ca)
  #1 CallocT<SpriteLoader::CommonPixel> /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_func.hpp:94 (openttd+0xd5c6a3)
  #2 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:63 (openttd+0xd5c429)
  #3 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #4 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #5 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #6 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #7 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #8 GetSprite /home/jgr/misc/openttd-2/src/blitter/../spritecache.h:43 (openttd+0x1462527)
  #9 AddSortableSpriteToDraw(unsigned int, unsigned int, int, int, int, int, int, int, bool, int, int, int, SubSprite const*) /home/jgr/misc/openttd-2/src/viewport.cpp:689 (openttd+0x1464a59)
  #10 DrawCommonTileSeq(TileInfo const*, DrawTileSprites const*, TransparencyOption, int, unsigned int, unsigned int, bool) /home/jgr/misc/openttd-2/src/sprite.cpp:58 (openttd+0x12945c5)
  #11 DrawNewGRFTileSeq /home/jgr/misc/openttd-2/src/sprite.h:126 (openttd+0x110eb3c)
  #12 IndustryDrawTileLayout /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:178 (openttd+0x111008a)
  #13 DrawNewIndustryTile(TileInfo*, Industry*, unsigned short, IndustryTileSpec const*) /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:211 (openttd+0x1110497)
  #14 DrawTile_Industry /home/jgr/misc/openttd-2/src/industry_cmd.cpp:332 (openttd+0xf7c31b)
  #15 ViewportAddLandscape /home/jgr/misc/openttd-2/src/viewport.cpp:1272 (openttd+0x1467243)
  #16 ViewportDoDraw(Viewport const*, int, int, int, int) /home/jgr/misc/openttd-2/src/viewport.cpp:1736 (openttd+0x146b3b8)
  #17 ViewportDraw /home/jgr/misc/openttd-2/src/viewport.cpp:1799 (openttd+0x146bbd6)
  #18 Window::DrawViewport() const /home/jgr/misc/openttd-2/src/viewport.cpp:1819 (openttd+0x146bda2)
  #19 NWidgetViewport::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1922 (openttd+0x14a4867)
  #20 NWidgetPIPContainer::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1120 (openttd+0x149e55d)
  #21 Window::DrawWidgets() const /home/jgr/misc/openttd-2/src/widget.cpp:604 (openttd+0x149c239)
  #22 MainWindow::OnPaint() /home/jgr/misc/openttd-2/src/main_gui.cpp:235 (openttd+0x10060aa)
  #23 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:948 (openttd+0x14af85a)
  #24 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #25 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #26 DrawOverlappedWindowForAll(int, int, int, int) /home/jgr/misc/openttd-2/src/window.cpp:974 (openttd+0x14afb49)
  #27 RedrawScreenRect(int, int, int, int) /home/jgr/misc/openttd-2/src/gfx.cpp:1453 (openttd+0xef33d0)
  #28 DrawDirtyBlocks() /home/jgr/misc/openttd-2/src/gfx.cpp:1528 (openttd+0xef371b)
  #29 UpdateWindows() /home/jgr/misc/openttd-2/src/window.cpp:3204 (openttd+0x14ba724)
  #30 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:171 (openttd+0xd7e19e)
  #31 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #32 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #33 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #34 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Mutex M721 (0x7b6400005f38) created at:
  #0 pthread_mutex_lock <null> (libtsan.so.0+0x5271c)
  #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:749 (openttd+0xb23b59)
  #2 std::mutex::lock() /usr/include/c++/9/bits/std_mutex.h:100 (openttd+0xb2552a)
  #3 std::lock_guard<std::mutex>::lock_guard(std::mutex&) /usr/include/c++/9/bits/std_mutex.h:159 (openttd+0xb2931a)
  #4 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:157 (openttd+0xd7e07d)
  #5 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #6 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #7 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #8 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Thread T3 'ottd:game' (tid=1195403, running) created by main thread at:
  #0 pthread_create <null> (libtsan.so.0+0x5ea99)
  #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd7048)
  #2 bool StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&) /home/jgr/misc/openttd-2/src/video/../thread.h:49 (openttd+0xd7ee62)
  #3 VideoDriver::StartGameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:86 (openttd+0xd7d95b)
  #4 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:657 (openttd+0xd7324a)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

SUMMARY: ThreadSanitizer: data race (/usr/lib/x86_64-linux-gnu/libtsan.so.0+0x3792f) in memset
==================
==================
WARNING: ThreadSanitizer: data race (pid=1195394)
Write of size 8 at 0x7b98000390e8 by thread T3 (mutexes: write M721):
  #0 memset <null> (libtsan.so.0+0x3792f)
  #1 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:66 (openttd+0xd5c48f)
  #2 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #3 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #4 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #5 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #6 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #7 GetSprite /home/jgr/misc/openttd-2/src/spritecache.h:43 (openttd+0x140d637)
  #8 VehicleSpriteSeq::GetBounds(Rect*) const /home/jgr/misc/openttd-2/src/vehicle.cpp:102 (openttd+0x140e31d)
  #9 Vehicle::UpdateBoundingBoxCoordinates(bool) const /home/jgr/misc/openttd-2/src/vehicle.cpp:1610 (openttd+0x1415589)
  #10 Vehicle::UpdateViewport(bool) /home/jgr/misc/openttd-2/src/vehicle.cpp:1644 (openttd+0x1415959)
  #11 SpecializedVehicle<Train, (VehicleType)0>::UpdateViewport(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../vehicle_base.h:1222 (openttd+0xf512a5)
  #12 GroundVehicle<Train, (VehicleType)0>::UpdateInclination(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../ground_vehicle.hpp:242 (openttd+0xf4f36e)
  #13 TrainController(Train*, Vehicle*, bool) /home/jgr/misc/openttd-2/src/train_cmd.cpp:3356 (openttd+0x13ead0a)
  #14 TrainLocoHandler /home/jgr/misc/openttd-2/src/train_cmd.cpp:3848 (openttd+0x13ecaf0)
  #15 Train::Tick() /home/jgr/misc/openttd-2/src/train_cmd.cpp:3920 (openttd+0x13ecf90)
  #16 CallVehicleTicks() /home/jgr/misc/openttd-2/src/vehicle.cpp:961 (openttd+0x1411dc7)
  #17 StateGameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1400 (openttd+0x116d5ed)
  #18 GameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1506 (openttd+0x116dd44)
  #19 VideoDriver::GameLoop() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:36 (openttd+0xd7d6b3)
  #20 VideoDriver::GameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:43 (openttd+0xd7d73d)
  #21 VideoDriver::GameThreadThunk(VideoDriver*) /home/jgr/misc/openttd-2/src/video/video_driver.cpp:80 (openttd+0xd7d8b0)
  #22 StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}::operator()(char const*, void (*&&)(VideoDriver*), VideoDriver*&&) const /home/jgr/misc/openttd-2/src/video/../thread.h:54 (openttd+0xd7eda6)
  #23 void std::__invoke_impl<void, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*>(std::__invoke_other, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&&&)(VideoDriver*), VideoDriver*&&)#1}, char const*&&, void (*&&)(VideoDriver*), VideoDriver*&&) /usr/include/c++/9/bits/invoke.h:60 (openttd+0xd8023a)
  #24 _ZSt8__invokeIZ14StartNewThreadIPFvP11VideoDriverEJS2_EEbPSt6threadPKcOT_DpOT0_EUlS8_OS4_OS2_E_JS8_S4_S2_EENSt15__invoke_resultIS9_JDpSB_EE4typeESA_SD_ /usr/include/c++/9/bits/invoke.h:95 (openttd+0xd80063)
  #25 void std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::_M_invoke<0ul, 1ul, 2ul, 3ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) /usr/include/c++/9/thread:244 (openttd+0xd7fea0)
  #26 std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::operator()() /usr/include/c++/9/thread:251 (openttd+0xd7fdee)
  #27 std::thread::_State_impl<std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> > >::_M_run() /usr/include/c++/9/thread:195 (openttd+0xd7fda0)
  #28 <null> <null> (libstdc++.so.6+0xd6d83)

Previous read of size 1 at 0x7b98000390ee by main thread:
  #0 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:241 (openttd+0x1295b4e)
  #1 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #2 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #3 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #4 GetSprite /home/jgr/misc/openttd-2/src/video/../blitter/../spritecache.h:43 (openttd+0xd5ce11)
  #5 OpenGLBackend::DrawMouseCursor() /home/jgr/misc/openttd-2/src/video/opengl.cpp:1063 (openttd+0xd62020)
  #6 VideoDriver_SDL_OpenGL::Paint() /home/jgr/misc/openttd-2/src/video/sdl2_opengl_v.cpp:177 (openttd+0xd7b2c8)
  #7 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:178 (openttd+0xd7e23d)
  #8 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #9 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #10 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #11 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Location is heap block of size 11520 at 0x7b9800039000 allocated by main thread:
  #0 calloc <null> (libtsan.so.0+0x305ca)
  #1 CallocT<SpriteLoader::CommonPixel> /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_func.hpp:94 (openttd+0xd5c6a3)
  #2 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:63 (openttd+0xd5c429)
  #3 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #4 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #5 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #6 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #7 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #8 GetSprite /home/jgr/misc/openttd-2/src/blitter/../spritecache.h:43 (openttd+0x1462527)
  #9 AddSortableSpriteToDraw(unsigned int, unsigned int, int, int, int, int, int, int, bool, int, int, int, SubSprite const*) /home/jgr/misc/openttd-2/src/viewport.cpp:689 (openttd+0x1464a59)
  #10 DrawCommonTileSeq(TileInfo const*, DrawTileSprites const*, TransparencyOption, int, unsigned int, unsigned int, bool) /home/jgr/misc/openttd-2/src/sprite.cpp:58 (openttd+0x12945c5)
  #11 DrawNewGRFTileSeq /home/jgr/misc/openttd-2/src/sprite.h:126 (openttd+0x110eb3c)
  #12 IndustryDrawTileLayout /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:178 (openttd+0x111008a)
  #13 DrawNewIndustryTile(TileInfo*, Industry*, unsigned short, IndustryTileSpec const*) /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:211 (openttd+0x1110497)
  #14 DrawTile_Industry /home/jgr/misc/openttd-2/src/industry_cmd.cpp:332 (openttd+0xf7c31b)
  #15 ViewportAddLandscape /home/jgr/misc/openttd-2/src/viewport.cpp:1272 (openttd+0x1467243)
  #16 ViewportDoDraw(Viewport const*, int, int, int, int) /home/jgr/misc/openttd-2/src/viewport.cpp:1736 (openttd+0x146b3b8)
  #17 ViewportDraw /home/jgr/misc/openttd-2/src/viewport.cpp:1799 (openttd+0x146bbd6)
  #18 Window::DrawViewport() const /home/jgr/misc/openttd-2/src/viewport.cpp:1819 (openttd+0x146bda2)
  #19 NWidgetViewport::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1922 (openttd+0x14a4867)
  #20 NWidgetPIPContainer::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1120 (openttd+0x149e55d)
  #21 Window::DrawWidgets() const /home/jgr/misc/openttd-2/src/widget.cpp:604 (openttd+0x149c239)
  #22 MainWindow::OnPaint() /home/jgr/misc/openttd-2/src/main_gui.cpp:235 (openttd+0x10060aa)
  #23 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:948 (openttd+0x14af85a)
  #24 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #25 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #26 DrawOverlappedWindowForAll(int, int, int, int) /home/jgr/misc/openttd-2/src/window.cpp:974 (openttd+0x14afb49)
  #27 RedrawScreenRect(int, int, int, int) /home/jgr/misc/openttd-2/src/gfx.cpp:1453 (openttd+0xef33d0)
  #28 DrawDirtyBlocks() /home/jgr/misc/openttd-2/src/gfx.cpp:1528 (openttd+0xef371b)
  #29 UpdateWindows() /home/jgr/misc/openttd-2/src/window.cpp:3204 (openttd+0x14ba724)
  #30 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:171 (openttd+0xd7e19e)
  #31 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #32 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #33 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #34 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Mutex M721 (0x7b6400005f38) created at:
  #0 pthread_mutex_lock <null> (libtsan.so.0+0x5271c)
  #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:749 (openttd+0xb23b59)
  #2 std::mutex::lock() /usr/include/c++/9/bits/std_mutex.h:100 (openttd+0xb2552a)
  #3 std::lock_guard<std::mutex>::lock_guard(std::mutex&) /usr/include/c++/9/bits/std_mutex.h:159 (openttd+0xb2931a)
  #4 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:157 (openttd+0xd7e07d)
  #5 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #6 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #7 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #8 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Thread T3 'ottd:game' (tid=1195403, running) created by main thread at:
  #0 pthread_create <null> (libtsan.so.0+0x5ea99)
  #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd7048)
  #2 bool StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&) /home/jgr/misc/openttd-2/src/video/../thread.h:49 (openttd+0xd7ee62)
  #3 VideoDriver::StartGameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:86 (openttd+0xd7d95b)
  #4 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:657 (openttd+0xd7324a)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

SUMMARY: ThreadSanitizer: data race (/usr/lib/x86_64-linux-gnu/libtsan.so.0+0x3792f) in memset
==================
==================
WARNING: ThreadSanitizer: data race (pid=1195394)
Write of size 8 at 0x7b7800009008 by thread T3 (mutexes: write M721):
  #0 memset <null> (libtsan.so.0+0x3792f)
  #1 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:66 (openttd+0xd5c48f)
  #2 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #3 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #4 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #5 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #6 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #7 GetSprite /home/jgr/misc/openttd-2/src/spritecache.h:43 (openttd+0x140d637)
  #8 VehicleSpriteSeq::GetBounds(Rect*) const /home/jgr/misc/openttd-2/src/vehicle.cpp:102 (openttd+0x140e31d)
  #9 Vehicle::UpdateBoundingBoxCoordinates(bool) const /home/jgr/misc/openttd-2/src/vehicle.cpp:1610 (openttd+0x1415589)
  #10 Vehicle::UpdateViewport(bool) /home/jgr/misc/openttd-2/src/vehicle.cpp:1644 (openttd+0x1415959)
  #11 SpecializedVehicle<Train, (VehicleType)0>::UpdateViewport(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../vehicle_base.h:1222 (openttd+0xf512a5)
  #12 GroundVehicle<Train, (VehicleType)0>::UpdateInclination(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../ground_vehicle.hpp:242 (openttd+0xf4f36e)
  #13 TrainController(Train*, Vehicle*, bool) /home/jgr/misc/openttd-2/src/train_cmd.cpp:3356 (openttd+0x13ead0a)
  #14 TrainLocoHandler /home/jgr/misc/openttd-2/src/train_cmd.cpp:3848 (openttd+0x13ecaf0)
  #15 Train::Tick() /home/jgr/misc/openttd-2/src/train_cmd.cpp:3920 (openttd+0x13ecf90)
  #16 CallVehicleTicks() /home/jgr/misc/openttd-2/src/vehicle.cpp:961 (openttd+0x1411dc7)
  #17 StateGameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1400 (openttd+0x116d5ed)
  #18 GameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1506 (openttd+0x116dd44)
  #19 VideoDriver::GameLoop() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:36 (openttd+0xd7d6b3)
  #20 VideoDriver::GameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:43 (openttd+0xd7d73d)
  #21 VideoDriver::GameThreadThunk(VideoDriver*) /home/jgr/misc/openttd-2/src/video/video_driver.cpp:80 (openttd+0xd7d8b0)
  #22 StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}::operator()(char const*, void (*&&)(VideoDriver*), VideoDriver*&&) const /home/jgr/misc/openttd-2/src/video/../thread.h:54 (openttd+0xd7eda6)
  #23 void std::__invoke_impl<void, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*>(std::__invoke_other, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&&&)(VideoDriver*), VideoDriver*&&)#1}, char const*&&, void (*&&)(VideoDriver*), VideoDriver*&&) /usr/include/c++/9/bits/invoke.h:60 (openttd+0xd8023a)
  #24 _ZSt8__invokeIZ14StartNewThreadIPFvP11VideoDriverEJS2_EEbPSt6threadPKcOT_DpOT0_EUlS8_OS4_OS2_E_JS8_S4_S2_EENSt15__invoke_resultIS9_JDpSB_EE4typeESA_SD_ /usr/include/c++/9/bits/invoke.h:95 (openttd+0xd80063)
  #25 void std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::_M_invoke<0ul, 1ul, 2ul, 3ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) /usr/include/c++/9/thread:244 (openttd+0xd7fea0)
  #26 std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::operator()() /usr/include/c++/9/thread:251 (openttd+0xd7fdee)
  #27 std::thread::_State_impl<std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> > >::_M_run() /usr/include/c++/9/thread:195 (openttd+0xd7fda0)
  #28 <null> <null> (libstdc++.so.6+0xd6d83)

Previous read of size 1 at 0x7b7800009009 by main thread:
  #0 Sprite* Blitter_32bppOptimized::EncodeInternal<false>(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/32bpp_optimized.cpp:373 (openttd+0xa62909)
  #1 Blitter_40bppAnim::Encode(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/40bpp_anim.cpp:383 (openttd+0xa9d8f9)
  #2 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:498 (openttd+0x1297820)
  #3 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #4 GetSprite /home/jgr/misc/openttd-2/src/video/../blitter/../spritecache.h:43 (openttd+0xd5ce11)
  #5 OpenGLBackend::DrawMouseCursor() /home/jgr/misc/openttd-2/src/video/opengl.cpp:1063 (openttd+0xd62020)
  #6 VideoDriver_SDL_OpenGL::Paint() /home/jgr/misc/openttd-2/src/video/sdl2_opengl_v.cpp:177 (openttd+0xd7b2c8)
  #7 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:178 (openttd+0xd7e23d)
  #8 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #9 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #10 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #11 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Location is heap block of size 2880 at 0x7b7800009000 allocated by main thread:
  #0 calloc <null> (libtsan.so.0+0x305ca)
  #1 CallocT<SpriteLoader::CommonPixel> /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_func.hpp:94 (openttd+0xd5c6a3)
  #2 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:63 (openttd+0xd5c429)
  #3 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #4 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #5 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #6 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #7 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #8 GetSprite /home/jgr/misc/openttd-2/src/blitter/../spritecache.h:43 (openttd+0x1462527)
  #9 AddSortableSpriteToDraw(unsigned int, unsigned int, int, int, int, int, int, int, bool, int, int, int, SubSprite const*) /home/jgr/misc/openttd-2/src/viewport.cpp:689 (openttd+0x1464a59)
  #10 DrawCommonTileSeq(TileInfo const*, DrawTileSprites const*, TransparencyOption, int, unsigned int, unsigned int, bool) /home/jgr/misc/openttd-2/src/sprite.cpp:58 (openttd+0x12945c5)
  #11 DrawNewGRFTileSeq /home/jgr/misc/openttd-2/src/sprite.h:126 (openttd+0x110eb3c)
  #12 IndustryDrawTileLayout /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:178 (openttd+0x111008a)
  #13 DrawNewIndustryTile(TileInfo*, Industry*, unsigned short, IndustryTileSpec const*) /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:211 (openttd+0x1110497)
  #14 DrawTile_Industry /home/jgr/misc/openttd-2/src/industry_cmd.cpp:332 (openttd+0xf7c31b)
  #15 ViewportAddLandscape /home/jgr/misc/openttd-2/src/viewport.cpp:1272 (openttd+0x1467243)
  #16 ViewportDoDraw(Viewport const*, int, int, int, int) /home/jgr/misc/openttd-2/src/viewport.cpp:1736 (openttd+0x146b3b8)
  #17 ViewportDraw /home/jgr/misc/openttd-2/src/viewport.cpp:1799 (openttd+0x146bbd6)
  #18 Window::DrawViewport() const /home/jgr/misc/openttd-2/src/viewport.cpp:1819 (openttd+0x146bda2)
  #19 NWidgetViewport::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1922 (openttd+0x14a4867)
  #20 NWidgetPIPContainer::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1120 (openttd+0x149e55d)
  #21 Window::DrawWidgets() const /home/jgr/misc/openttd-2/src/widget.cpp:604 (openttd+0x149c239)
  #22 MainWindow::OnPaint() /home/jgr/misc/openttd-2/src/main_gui.cpp:235 (openttd+0x10060aa)
  #23 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:948 (openttd+0x14af85a)
  #24 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #25 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #26 DrawOverlappedWindowForAll(int, int, int, int) /home/jgr/misc/openttd-2/src/window.cpp:974 (openttd+0x14afb49)
  #27 RedrawScreenRect(int, int, int, int) /home/jgr/misc/openttd-2/src/gfx.cpp:1453 (openttd+0xef33d0)
  #28 DrawDirtyBlocks() /home/jgr/misc/openttd-2/src/gfx.cpp:1528 (openttd+0xef371b)
  #29 UpdateWindows() /home/jgr/misc/openttd-2/src/window.cpp:3204 (openttd+0x14ba724)
  #30 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:171 (openttd+0xd7e19e)
  #31 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #32 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #33 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #34 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Mutex M721 (0x7b6400005f38) created at:
  #0 pthread_mutex_lock <null> (libtsan.so.0+0x5271c)
  #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:749 (openttd+0xb23b59)
  #2 std::mutex::lock() /usr/include/c++/9/bits/std_mutex.h:100 (openttd+0xb2552a)
  #3 std::lock_guard<std::mutex>::lock_guard(std::mutex&) /usr/include/c++/9/bits/std_mutex.h:159 (openttd+0xb2931a)
  #4 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:157 (openttd+0xd7e07d)
  #5 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #6 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #7 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #8 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Thread T3 'ottd:game' (tid=1195403, running) created by main thread at:
  #0 pthread_create <null> (libtsan.so.0+0x5ea99)
  #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd7048)
  #2 bool StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&) /home/jgr/misc/openttd-2/src/video/../thread.h:49 (openttd+0xd7ee62)
  #3 VideoDriver::StartGameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:86 (openttd+0xd7d95b)
  #4 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:657 (openttd+0xd7324a)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

SUMMARY: ThreadSanitizer: data race (/usr/lib/x86_64-linux-gnu/libtsan.so.0+0x3792f) in memset
==================
==================
WARNING: ThreadSanitizer: data race (pid=1195394)
Write of size 8 at 0x7b7800009028 by thread T3 (mutexes: write M721):
  #0 memset <null> (libtsan.so.0+0x3792f)
  #1 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:66 (openttd+0xd5c48f)
  #2 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #3 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #4 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #5 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #6 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #7 GetSprite /home/jgr/misc/openttd-2/src/spritecache.h:43 (openttd+0x140d637)
  #8 VehicleSpriteSeq::GetBounds(Rect*) const /home/jgr/misc/openttd-2/src/vehicle.cpp:102 (openttd+0x140e31d)
  #9 Vehicle::UpdateBoundingBoxCoordinates(bool) const /home/jgr/misc/openttd-2/src/vehicle.cpp:1610 (openttd+0x1415589)
  #10 Vehicle::UpdateViewport(bool) /home/jgr/misc/openttd-2/src/vehicle.cpp:1644 (openttd+0x1415959)
  #11 SpecializedVehicle<Train, (VehicleType)0>::UpdateViewport(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../vehicle_base.h:1222 (openttd+0xf512a5)
  #12 GroundVehicle<Train, (VehicleType)0>::UpdateInclination(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../ground_vehicle.hpp:242 (openttd+0xf4f36e)
  #13 TrainController(Train*, Vehicle*, bool) /home/jgr/misc/openttd-2/src/train_cmd.cpp:3356 (openttd+0x13ead0a)
  #14 TrainLocoHandler /home/jgr/misc/openttd-2/src/train_cmd.cpp:3848 (openttd+0x13ecaf0)
  #15 Train::Tick() /home/jgr/misc/openttd-2/src/train_cmd.cpp:3920 (openttd+0x13ecf90)
  #16 CallVehicleTicks() /home/jgr/misc/openttd-2/src/vehicle.cpp:961 (openttd+0x1411dc7)
  #17 StateGameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1400 (openttd+0x116d5ed)
  #18 GameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1506 (openttd+0x116dd44)
  #19 VideoDriver::GameLoop() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:36 (openttd+0xd7d6b3)
  #20 VideoDriver::GameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:43 (openttd+0xd7d73d)
  #21 VideoDriver::GameThreadThunk(VideoDriver*) /home/jgr/misc/openttd-2/src/video/video_driver.cpp:80 (openttd+0xd7d8b0)
  #22 StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}::operator()(char const*, void (*&&)(VideoDriver*), VideoDriver*&&) const /home/jgr/misc/openttd-2/src/video/../thread.h:54 (openttd+0xd7eda6)
  #23 void std::__invoke_impl<void, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*>(std::__invoke_other, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&&&)(VideoDriver*), VideoDriver*&&)#1}, char const*&&, void (*&&)(VideoDriver*), VideoDriver*&&) /usr/include/c++/9/bits/invoke.h:60 (openttd+0xd8023a)
  #24 _ZSt8__invokeIZ14StartNewThreadIPFvP11VideoDriverEJS2_EEbPSt6threadPKcOT_DpOT0_EUlS8_OS4_OS2_E_JS8_S4_S2_EENSt15__invoke_resultIS9_JDpSB_EE4typeESA_SD_ /usr/include/c++/9/bits/invoke.h:95 (openttd+0xd80063)
  #25 void std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::_M_invoke<0ul, 1ul, 2ul, 3ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) /usr/include/c++/9/thread:244 (openttd+0xd7fea0)
  #26 std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::operator()() /usr/include/c++/9/thread:251 (openttd+0xd7fdee)
  #27 std::thread::_State_impl<std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> > >::_M_run() /usr/include/c++/9/thread:195 (openttd+0xd7fda0)
  #28 <null> <null> (libstdc++.so.6+0xd6d83)

Previous read of size 1 at 0x7b780000902d by main thread:
  #0 Sprite* Blitter_32bppOptimized::EncodeInternal<false>(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/32bpp_optimized.cpp:360 (openttd+0xa6278f)
  #1 Blitter_40bppAnim::Encode(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/40bpp_anim.cpp:383 (openttd+0xa9d8f9)
  #2 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:498 (openttd+0x1297820)
  #3 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #4 GetSprite /home/jgr/misc/openttd-2/src/video/../blitter/../spritecache.h:43 (openttd+0xd5ce11)
  #5 OpenGLBackend::DrawMouseCursor() /home/jgr/misc/openttd-2/src/video/opengl.cpp:1063 (openttd+0xd62020)
  #6 VideoDriver_SDL_OpenGL::Paint() /home/jgr/misc/openttd-2/src/video/sdl2_opengl_v.cpp:177 (openttd+0xd7b2c8)
  #7 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:178 (openttd+0xd7e23d)
  #8 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #9 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #10 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #11 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Location is heap block of size 2880 at 0x7b7800009000 allocated by main thread:
  #0 calloc <null> (libtsan.so.0+0x305ca)
  #1 CallocT<SpriteLoader::CommonPixel> /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_func.hpp:94 (openttd+0xd5c6a3)
  #2 ReusableBuffer<SpriteLoader::CommonPixel>::ZeroAllocate(unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_type.hpp:63 (openttd+0xd5c429)
  #3 SpriteLoader::Sprite::AllocateData(ZoomLevel, unsigned long) /home/jgr/misc/openttd-2/src/spriteloader/spriteloader.hpp:61 (openttd+0xd5c2fb)
  #4 ResizeSpriteOut /home/jgr/misc/openttd-2/src/spritecache.cpp:228 (openttd+0x129593d)
  #5 ResizeSprites /home/jgr/misc/openttd-2/src/spritecache.cpp:374 (openttd+0x1296ca6)
  #6 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:483 (openttd+0x1297496)
  #7 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #8 GetSprite /home/jgr/misc/openttd-2/src/blitter/../spritecache.h:43 (openttd+0x1462527)
  #9 AddSortableSpriteToDraw(unsigned int, unsigned int, int, int, int, int, int, int, bool, int, int, int, SubSprite const*) /home/jgr/misc/openttd-2/src/viewport.cpp:689 (openttd+0x1464a59)
  #10 DrawCommonTileSeq(TileInfo const*, DrawTileSprites const*, TransparencyOption, int, unsigned int, unsigned int, bool) /home/jgr/misc/openttd-2/src/sprite.cpp:58 (openttd+0x12945c5)
  #11 DrawNewGRFTileSeq /home/jgr/misc/openttd-2/src/sprite.h:126 (openttd+0x110eb3c)
  #12 IndustryDrawTileLayout /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:178 (openttd+0x111008a)
  #13 DrawNewIndustryTile(TileInfo*, Industry*, unsigned short, IndustryTileSpec const*) /home/jgr/misc/openttd-2/src/newgrf_industrytiles.cpp:211 (openttd+0x1110497)
  #14 DrawTile_Industry /home/jgr/misc/openttd-2/src/industry_cmd.cpp:332 (openttd+0xf7c31b)
  #15 ViewportAddLandscape /home/jgr/misc/openttd-2/src/viewport.cpp:1272 (openttd+0x1467243)
  #16 ViewportDoDraw(Viewport const*, int, int, int, int) /home/jgr/misc/openttd-2/src/viewport.cpp:1736 (openttd+0x146b3b8)
  #17 ViewportDraw /home/jgr/misc/openttd-2/src/viewport.cpp:1799 (openttd+0x146bbd6)
  #18 Window::DrawViewport() const /home/jgr/misc/openttd-2/src/viewport.cpp:1819 (openttd+0x146bda2)
  #19 NWidgetViewport::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1922 (openttd+0x14a4867)
  #20 NWidgetPIPContainer::Draw(Window const*) /home/jgr/misc/openttd-2/src/widget.cpp:1120 (openttd+0x149e55d)
  #21 Window::DrawWidgets() const /home/jgr/misc/openttd-2/src/widget.cpp:604 (openttd+0x149c239)
  #22 MainWindow::OnPaint() /home/jgr/misc/openttd-2/src/main_gui.cpp:235 (openttd+0x10060aa)
  #23 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:948 (openttd+0x14af85a)
  #24 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #25 DrawOverlappedWindow /home/jgr/misc/openttd-2/src/window.cpp:912 (openttd+0x14af52f)
  #26 DrawOverlappedWindowForAll(int, int, int, int) /home/jgr/misc/openttd-2/src/window.cpp:974 (openttd+0x14afb49)
  #27 RedrawScreenRect(int, int, int, int) /home/jgr/misc/openttd-2/src/gfx.cpp:1453 (openttd+0xef33d0)
  #28 DrawDirtyBlocks() /home/jgr/misc/openttd-2/src/gfx.cpp:1528 (openttd+0xef371b)
  #29 UpdateWindows() /home/jgr/misc/openttd-2/src/window.cpp:3204 (openttd+0x14ba724)
  #30 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:171 (openttd+0xd7e19e)
  #31 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #32 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #33 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #34 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Mutex M721 (0x7b6400005f38) created at:
  #0 pthread_mutex_lock <null> (libtsan.so.0+0x5271c)
  #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:749 (openttd+0xb23b59)
  #2 std::mutex::lock() /usr/include/c++/9/bits/std_mutex.h:100 (openttd+0xb2552a)
  #3 std::lock_guard<std::mutex>::lock_guard(std::mutex&) /usr/include/c++/9/bits/std_mutex.h:159 (openttd+0xb2931a)
  #4 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:157 (openttd+0xd7e07d)
  #5 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #6 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #7 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #8 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Thread T3 'ottd:game' (tid=1195403, running) created by main thread at:
  #0 pthread_create <null> (libtsan.so.0+0x5ea99)
  #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd7048)
  #2 bool StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&) /home/jgr/misc/openttd-2/src/video/../thread.h:49 (openttd+0xd7ee62)
  #3 VideoDriver::StartGameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:86 (openttd+0xd7d95b)
  #4 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:657 (openttd+0xd7324a)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

SUMMARY: ThreadSanitizer: data race (/usr/lib/x86_64-linux-gnu/libtsan.so.0+0x3792f) in memset
==================
==================
WARNING: ThreadSanitizer: data race (pid=1195394)
Read of size 8 at 0x7fa7a5924320 by thread T3 (mutexes: write M721):
  #0 AllocSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:788 (openttd+0x12987d0)
  #1 Sprite* Blitter_32bppOptimized::EncodeInternal<false>(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/32bpp_optimized.cpp:403 (openttd+0xa62c21)
  #2 Blitter_40bppAnim::Encode(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/40bpp_anim.cpp:383 (openttd+0xa9d8f9)
  #3 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:498 (openttd+0x1297820)
  #4 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #5 GetSprite /home/jgr/misc/openttd-2/src/spritecache.h:43 (openttd+0x140d637)
  #6 VehicleSpriteSeq::GetBounds(Rect*) const /home/jgr/misc/openttd-2/src/vehicle.cpp:102 (openttd+0x140e31d)
  #7 Vehicle::UpdateBoundingBoxCoordinates(bool) const /home/jgr/misc/openttd-2/src/vehicle.cpp:1610 (openttd+0x1415589)
  #8 Vehicle::UpdateViewport(bool) /home/jgr/misc/openttd-2/src/vehicle.cpp:1644 (openttd+0x1415959)
  #9 SpecializedVehicle<Train, (VehicleType)0>::UpdateViewport(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../vehicle_base.h:1222 (openttd+0xf512a5)
  #10 GroundVehicle<Train, (VehicleType)0>::UpdateInclination(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../ground_vehicle.hpp:242 (openttd+0xf4f36e)
  #11 TrainController(Train*, Vehicle*, bool) /home/jgr/misc/openttd-2/src/train_cmd.cpp:3356 (openttd+0x13ead0a)
  #12 TrainLocoHandler /home/jgr/misc/openttd-2/src/train_cmd.cpp:3848 (openttd+0x13ecaf0)
  #13 Train::Tick() /home/jgr/misc/openttd-2/src/train_cmd.cpp:3920 (openttd+0x13ecf90)
  #14 CallVehicleTicks() /home/jgr/misc/openttd-2/src/vehicle.cpp:961 (openttd+0x1411dc7)
  #15 StateGameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1400 (openttd+0x116d5ed)
  #16 GameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1506 (openttd+0x116dd44)
  #17 VideoDriver::GameLoop() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:36 (openttd+0xd7d6b3)
  #18 VideoDriver::GameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:43 (openttd+0xd7d73d)
  #19 VideoDriver::GameThreadThunk(VideoDriver*) /home/jgr/misc/openttd-2/src/video/video_driver.cpp:80 (openttd+0xd7d8b0)
  #20 StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}::operator()(char const*, void (*&&)(VideoDriver*), VideoDriver*&&) const /home/jgr/misc/openttd-2/src/video/../thread.h:54 (openttd+0xd7eda6)
  #21 void std::__invoke_impl<void, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*>(std::__invoke_other, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&&&)(VideoDriver*), VideoDriver*&&)#1}, char const*&&, void (*&&)(VideoDriver*), VideoDriver*&&) /usr/include/c++/9/bits/invoke.h:60 (openttd+0xd8023a)
  #22 _ZSt8__invokeIZ14StartNewThreadIPFvP11VideoDriverEJS2_EEbPSt6threadPKcOT_DpOT0_EUlS8_OS4_OS2_E_JS8_S4_S2_EENSt15__invoke_resultIS9_JDpSB_EE4typeESA_SD_ /usr/include/c++/9/bits/invoke.h:95 (openttd+0xd80063)
  #23 void std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::_M_invoke<0ul, 1ul, 2ul, 3ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) /usr/include/c++/9/thread:244 (openttd+0xd7fea0)
  #24 std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::operator()() /usr/include/c++/9/thread:251 (openttd+0xd7fdee)
  #25 std::thread::_State_impl<std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> > >::_M_run() /usr/include/c++/9/thread:195 (openttd+0xd7fda0)
  #26 <null> <null> (libstdc++.so.6+0xd6d83)

Previous write of size 8 at 0x7fa7a5924320 by main thread:
  #0 AllocSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:797 (openttd+0x129883e)
  #1 Sprite* Blitter_32bppOptimized::EncodeInternal<false>(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/32bpp_optimized.cpp:403 (openttd+0xa62c21)
  #2 Blitter_40bppAnim::Encode(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/40bpp_anim.cpp:383 (openttd+0xa9d8f9)
  #3 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:498 (openttd+0x1297820)
  #4 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #5 GetSprite /home/jgr/misc/openttd-2/src/video/../blitter/../spritecache.h:43 (openttd+0xd5ce11)
  #6 OpenGLBackend::DrawMouseCursor() /home/jgr/misc/openttd-2/src/video/opengl.cpp:1063 (openttd+0xd62020)
  #7 VideoDriver_SDL_OpenGL::Paint() /home/jgr/misc/openttd-2/src/video/sdl2_opengl_v.cpp:177 (openttd+0xd7b2c8)
  #8 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:178 (openttd+0xd7e23d)
  #9 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #10 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #11 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #12 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Location is heap block of size 2147483648 at 0x7fa7a575b000 allocated by main thread:
  #0 operator new[](unsigned long) <null> (libtsan.so.0+0x8c162)
  #1 GfxInitSpriteCache /home/jgr/misc/openttd-2/src/spritecache.cpp:935 (openttd+0x1298f81)
  #2 GfxInitSpriteMem() /home/jgr/misc/openttd-2/src/spritecache.cpp:962 (openttd+0x1299203)
  #3 GfxLoadSprites() /home/jgr/misc/openttd-2/src/gfxinit.cpp:337 (openttd+0xf2b0c4)
  #4 GenerateWorld(GenWorldMode, unsigned int, unsigned int, bool) /home/jgr/misc/openttd-2/src/genworld.cpp:306 (openttd+0xedd698)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:829 (openttd+0x116a3d7)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Mutex M721 (0x7b6400005f38) created at:
  #0 pthread_mutex_lock <null> (libtsan.so.0+0x5271c)
  #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:749 (openttd+0xb23b59)
  #2 std::mutex::lock() /usr/include/c++/9/bits/std_mutex.h:100 (openttd+0xb2552a)
  #3 std::lock_guard<std::mutex>::lock_guard(std::mutex&) /usr/include/c++/9/bits/std_mutex.h:159 (openttd+0xb2931a)
  #4 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:157 (openttd+0xd7e07d)
  #5 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #6 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #7 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #8 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Thread T3 'ottd:game' (tid=1195403, running) created by main thread at:
  #0 pthread_create <null> (libtsan.so.0+0x5ea99)
  #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd7048)
  #2 bool StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&) /home/jgr/misc/openttd-2/src/video/../thread.h:49 (openttd+0xd7ee62)
  #3 VideoDriver::StartGameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:86 (openttd+0xd7d95b)
  #4 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:657 (openttd+0xd7324a)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

SUMMARY: ThreadSanitizer: data race /home/jgr/misc/openttd-2/src/spritecache.cpp:788 in AllocSprite
==================
==================
WARNING: ThreadSanitizer: data race (pid=1195394)
Read of size 8 at 0x7fa7a5924a40 by thread T3 (mutexes: write M721):
  #0 AllocSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:788 (openttd+0x12987d0)
  #1 Sprite* Blitter_32bppOptimized::EncodeInternal<false>(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/32bpp_optimized.cpp:403 (openttd+0xa62c21)
  #2 Blitter_40bppAnim::Encode(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/40bpp_anim.cpp:383 (openttd+0xa9d8f9)
  #3 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:498 (openttd+0x1297820)
  #4 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #5 GetSprite /home/jgr/misc/openttd-2/src/spritecache.h:43 (openttd+0x140d637)
  #6 VehicleSpriteSeq::GetBounds(Rect*) const /home/jgr/misc/openttd-2/src/vehicle.cpp:102 (openttd+0x140e31d)
  #7 Vehicle::UpdateBoundingBoxCoordinates(bool) const /home/jgr/misc/openttd-2/src/vehicle.cpp:1610 (openttd+0x1415589)
  #8 Vehicle::UpdateViewport(bool) /home/jgr/misc/openttd-2/src/vehicle.cpp:1644 (openttd+0x1415959)
  #9 SpecializedVehicle<Train, (VehicleType)0>::UpdateViewport(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../vehicle_base.h:1222 (openttd+0xf512a5)
  #10 GroundVehicle<Train, (VehicleType)0>::UpdateInclination(bool, bool) /home/jgr/misc/openttd-2/src/pathfinder/yapf/../../ground_vehicle.hpp:242 (openttd+0xf4f36e)
  #11 TrainController(Train*, Vehicle*, bool) /home/jgr/misc/openttd-2/src/train_cmd.cpp:3356 (openttd+0x13ead0a)
  #12 TrainLocoHandler /home/jgr/misc/openttd-2/src/train_cmd.cpp:3848 (openttd+0x13ecaf0)
  #13 Train::Tick() /home/jgr/misc/openttd-2/src/train_cmd.cpp:3920 (openttd+0x13ecf90)
  #14 CallVehicleTicks() /home/jgr/misc/openttd-2/src/vehicle.cpp:961 (openttd+0x1411dc7)
  #15 StateGameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1400 (openttd+0x116d5ed)
  #16 GameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1506 (openttd+0x116dd44)
  #17 VideoDriver::GameLoop() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:36 (openttd+0xd7d6b3)
  #18 VideoDriver::GameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:43 (openttd+0xd7d73d)
  #19 VideoDriver::GameThreadThunk(VideoDriver*) /home/jgr/misc/openttd-2/src/video/video_driver.cpp:80 (openttd+0xd7d8b0)
  #20 StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}::operator()(char const*, void (*&&)(VideoDriver*), VideoDriver*&&) const /home/jgr/misc/openttd-2/src/video/../thread.h:54 (openttd+0xd7eda6)
  #21 void std::__invoke_impl<void, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*>(std::__invoke_other, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&&&)(VideoDriver*), VideoDriver*&&)#1}, char const*&&, void (*&&)(VideoDriver*), VideoDriver*&&) /usr/include/c++/9/bits/invoke.h:60 (openttd+0xd8023a)
  #22 _ZSt8__invokeIZ14StartNewThreadIPFvP11VideoDriverEJS2_EEbPSt6threadPKcOT_DpOT0_EUlS8_OS4_OS2_E_JS8_S4_S2_EENSt15__invoke_resultIS9_JDpSB_EE4typeESA_SD_ /usr/include/c++/9/bits/invoke.h:95 (openttd+0xd80063)
  #23 void std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::_M_invoke<0ul, 1ul, 2ul, 3ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) /usr/include/c++/9/thread:244 (openttd+0xd7fea0)
  #24 std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::operator()() /usr/include/c++/9/thread:251 (openttd+0xd7fdee)
  #25 std::thread::_State_impl<std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> > >::_M_run() /usr/include/c++/9/thread:195 (openttd+0xd7fda0)
  #26 <null> <null> (libstdc++.so.6+0xd6d83)

Previous write of size 8 at 0x7fa7a5924a40 by main thread:
  #0 AllocSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:801 (openttd+0x129887c)
  #1 Sprite* Blitter_32bppOptimized::EncodeInternal<false>(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/32bpp_optimized.cpp:403 (openttd+0xa62c21)
  #2 Blitter_40bppAnim::Encode(SpriteLoader::Sprite const*, void* (*)(unsigned long)) /home/jgr/misc/openttd-2/src/blitter/40bpp_anim.cpp:383 (openttd+0xa9d8f9)
  #3 ReadSprite /home/jgr/misc/openttd-2/src/spritecache.cpp:498 (openttd+0x1297820)
  #4 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d1b)
  #5 GetSprite /home/jgr/misc/openttd-2/src/video/../blitter/../spritecache.h:43 (openttd+0xd5ce11)
  #6 OpenGLBackend::DrawMouseCursor() /home/jgr/misc/openttd-2/src/video/opengl.cpp:1063 (openttd+0xd62020)
  #7 VideoDriver_SDL_OpenGL::Paint() /home/jgr/misc/openttd-2/src/video/sdl2_opengl_v.cpp:177 (openttd+0xd7b2c8)
  #8 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:178 (openttd+0xd7e23d)
  #9 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #10 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #11 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #12 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Location is heap block of size 2147483648 at 0x7fa7a575b000 allocated by main thread:
  #0 operator new[](unsigned long) <null> (libtsan.so.0+0x8c162)
  #1 GfxInitSpriteCache /home/jgr/misc/openttd-2/src/spritecache.cpp:935 (openttd+0x1298f81)
  #2 GfxInitSpriteMem() /home/jgr/misc/openttd-2/src/spritecache.cpp:962 (openttd+0x1299203)
  #3 GfxLoadSprites() /home/jgr/misc/openttd-2/src/gfxinit.cpp:337 (openttd+0xf2b0c4)
  #4 GenerateWorld(GenWorldMode, unsigned int, unsigned int, bool) /home/jgr/misc/openttd-2/src/genworld.cpp:306 (openttd+0xedd698)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:829 (openttd+0x116a3d7)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Mutex M721 (0x7b6400005f38) created at:
  #0 pthread_mutex_lock <null> (libtsan.so.0+0x5271c)
  #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:749 (openttd+0xb23b59)
  #2 std::mutex::lock() /usr/include/c++/9/bits/std_mutex.h:100 (openttd+0xb2552a)
  #3 std::lock_guard<std::mutex>::lock_guard(std::mutex&) /usr/include/c++/9/bits/std_mutex.h:159 (openttd+0xb2931a)
  #4 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:157 (openttd+0xd7e07d)
  #5 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #6 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #7 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #8 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Thread T3 'ottd:game' (tid=1195403, running) created by main thread at:
  #0 pthread_create <null> (libtsan.so.0+0x5ea99)
  #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd7048)
  #2 bool StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&) /home/jgr/misc/openttd-2/src/video/../thread.h:49 (openttd+0xd7ee62)
  #3 VideoDriver::StartGameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:86 (openttd+0xd7d95b)
  #4 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:657 (openttd+0xd7324a)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

SUMMARY: ThreadSanitizer: data race /home/jgr/misc/openttd-2/src/spritecache.cpp:788 in AllocSprite
==================
==================
WARNING: ThreadSanitizer: data race (pid=1195394)
Write of size 8 at 0x7fa7a2842000 by main thread:
  #0 GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*) /home/jgr/misc/openttd-2/src/spritecache.cpp:899 (openttd+0x1298d2a)
  #1 GetSprite /home/jgr/misc/openttd-2/src/video/../blitter/../spritecache.h:43 (openttd+0xd5ce11)
  #2 OpenGLBackend::DrawMouseCursor() /home/jgr/misc/openttd-2/src/video/opengl.cpp:1063 (openttd+0xd62020)
  #3 VideoDriver_SDL_OpenGL::Paint() /home/jgr/misc/openttd-2/src/video/sdl2_opengl_v.cpp:177 (openttd+0xd7b2c8)
  #4 VideoDriver::Tick() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:178 (openttd+0xd7e23d)
  #5 VideoDriver_SDL_Base::LoopOnce() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:642 (openttd+0xd731ed)
  #6 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:660 (openttd+0xd7326d)
  #7 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #8 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

Previous read of size 8 at 0x7fa7a2842000 by thread T3:
  [failed to restore the stack]

Location is heap block of size 1605632 at 0x7fa7a2842000 allocated by thread T3:
  #0 realloc <null> (libtsan.so.0+0x32666)
  #1 ReallocT<SpriteCache> /home/jgr/misc/openttd-2/src/spriteloader/../core/alloc_func.hpp:126 (openttd+0x1299459)
  #2 AllocateSpriteCache /home/jgr/misc/openttd-2/src/spritecache.cpp:65 (openttd+0x1294dc8)
  #3 LoadNextSprite(int, unsigned char, unsigned int, unsigned char) /home/jgr/misc/openttd-2/src/spritecache.cpp:601 (openttd+0x1297c13)
  #4 NewSpriteSet /home/jgr/misc/openttd-2/src/newgrf.cpp:4904 (openttd+0x10357aa)
  #5 DecodeSpecialSprite /home/jgr/misc/openttd-2/src/newgrf.cpp:9312 (openttd+0x1048c55)
  #6 LoadNewGRFFile(GRFConfig*, unsigned int, GrfLoadingStage, Subdirectory) /home/jgr/misc/openttd-2/src/newgrf.cpp:9434 (openttd+0x10492a1)
  #7 LoadNewGRF(unsigned int, unsigned int, unsigned int) /home/jgr/misc/openttd-2/src/newgrf.cpp:9845 (openttd+0x104b973)
  #8 LoadSpriteTables /home/jgr/misc/openttd-2/src/gfxinit.cpp:230 (openttd+0xf2aa03)
  #9 GfxLoadSprites() /home/jgr/misc/openttd-2/src/gfxinit.cpp:338 (openttd+0xf2b0c9)
  #10 AfterLoadGame() /home/jgr/misc/openttd-2/src/saveload/afterload.cpp:763 (openttd+0xcb2142)
  #11 DoLoad /home/jgr/misc/openttd-2/src/saveload/saveload.cpp:2728 (openttd+0xd17f5d)
  #12 SaveOrLoad(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, SaveLoadOperation, DetailedFileType, Subdirectory, bool) /home/jgr/misc/openttd-2/src/saveload/saveload.cpp:2837 (openttd+0xd184b2)
  #13 SafeLoad(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, SaveLoadOperation, DetailedFileType, GameMode, Subdirectory, LoadFilter*) /home/jgr/misc/openttd-2/src/openttd.cpp:961 (openttd+0x116adb0)
  #14 SwitchToMode(SwitchMode) /home/jgr/misc/openttd-2/src/openttd.cpp:1061 (openttd+0x116b177)
  #15 GameLoop() /home/jgr/misc/openttd-2/src/openttd.cpp:1487 (openttd+0x116db91)
  #16 VideoDriver::GameLoop() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:36 (openttd+0xd7d6b3)
  #17 VideoDriver::GameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:43 (openttd+0xd7d73d)
  #18 VideoDriver::GameThreadThunk(VideoDriver*) /home/jgr/misc/openttd-2/src/video/video_driver.cpp:80 (openttd+0xd7d8b0)
  #19 StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}::operator()(char const*, void (*&&)(VideoDriver*), VideoDriver*&&) const /home/jgr/misc/openttd-2/src/video/../thread.h:54 (openttd+0xd7eda6)
  #20 void std::__invoke_impl<void, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*>(std::__invoke_other, StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&&&)(VideoDriver*), VideoDriver*&&)#1}, char const*&&, void (*&&)(VideoDriver*), VideoDriver*&&) /usr/include/c++/9/bits/invoke.h:60 (openttd+0xd8023a)
  #21 _ZSt8__invokeIZ14StartNewThreadIPFvP11VideoDriverEJS2_EEbPSt6threadPKcOT_DpOT0_EUlS8_OS4_OS2_E_JS8_S4_S2_EENSt15__invoke_resultIS9_JDpSB_EE4typeESA_SD_ /usr/include/c++/9/bits/invoke.h:95 (openttd+0xd80063)
  #22 void std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::_M_invoke<0ul, 1ul, 2ul, 3ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) /usr/include/c++/9/thread:244 (openttd+0xd7fea0)
  #23 std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> >::operator()() /usr/include/c++/9/thread:251 (openttd+0xd7fdee)
  #24 std::thread::_State_impl<std::thread::_Invoker<std::tuple<StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&)::{lambda(char const*, void (*&&)(VideoDriver*), VideoDriver*&&)#1}, char const*, void (*)(VideoDriver*), VideoDriver*> > >::_M_run() /usr/include/c++/9/thread:195 (openttd+0xd7fda0)
  #25 <null> <null> (libstdc++.so.6+0xd6d83)

Thread T3 'ottd:game' (tid=1195403, running) created by main thread at:
  #0 pthread_create <null> (libtsan.so.0+0x5ea99)
  #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd7048)
  #2 bool StartNewThread<void (*)(VideoDriver*), VideoDriver*>(std::thread*, char const*, void (*&&)(VideoDriver*), VideoDriver*&&) /home/jgr/misc/openttd-2/src/video/../thread.h:49 (openttd+0xd7ee62)
  #3 VideoDriver::StartGameThread() /home/jgr/misc/openttd-2/src/video/video_driver.cpp:86 (openttd+0xd7d95b)
  #4 VideoDriver_SDL_Base::MainLoop() /home/jgr/misc/openttd-2/src/video/sdl2_v.cpp:657 (openttd+0xd7324a)
  #5 openttd_main(int, char**) /home/jgr/misc/openttd-2/src/openttd.cpp:837 (openttd+0x116a432)
  #6 main /home/jgr/misc/openttd-2/src/os/unix/unix.cpp:262 (openttd+0xc3df20)

SUMMARY: ThreadSanitizer: data race /home/jgr/misc/openttd-2/src/spritecache.cpp:899 in GetRawSprite(unsigned int, SpriteType, void* (*)(unsigned long), SpriteEncoder*)
==================

Description

Remove all direct accesses to _cursor and the sprite cache from the parts of the OpenGL code where the lock is not held.
Cache additional cursor properties as required.
Retrieve the cursor sprite properties from the local copy of the sprites, not the sprite cache sprite.

Limitations

This doesn't address the other race conditions, however the other ones that I've found so far are less important.

Checklist for review

Some things are not automated, and forgotten often. This list is a reminder for the reviewers.

  • The bug fix is important enough to be backported? (label: 'backport requested')
  • This PR affects the save game format? (label 'savegame upgrade')
  • This PR affects the GS/AI API? (label 'needs review: Script API')
    • ai_changelog.hpp, gs_changelog.hpp need updating.
    • The compatibility wrappers (compat_*.nut) need updating.
  • This PR affects the NewGRF API? (label 'needs review: NewGRF')

@LordAro
Copy link
Member

LordAro commented Apr 10, 2021

Think commit message probably needs amending, as this does not "fix" the issue that _fio exists (in its current form)

@TrueBrain TrueBrain added the backport requested This PR should be backport to current release (RC / stable) label Apr 10, 2021
@michicc michicc merged commit 39b7ef3 into OpenTTD:master Apr 10, 2021
@JGRennison JGRennison deleted the fix-opengl-cursor-races branch April 10, 2021 17:16
@LordAro LordAro added backported This PR is backported to a current release (RC / stable) and removed backport requested This PR should be backport to current release (RC / stable) labels Apr 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backported This PR is backported to a current release (RC / stable)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants