diff --git a/CHANGELOG.md b/CHANGELOG.md index 22f382d5a..3647c6576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -95,14 +95,14 @@ Apart from all the above, a huge amount of work has gone into fixing bugs, refac * Replaced all built-in matrix and vector data types and functions with GLM library equivalents * Replaced some additional math functions and moved the remaining built-in functions to a math utility namespace * Added a function to generate MD5 hashes +* Improved thread safety at multiple places throughout the codebase * Made an optimization for SVG graphics to avoid a lot of unnecessary re-rasterizations -* Moved the "complex" mode functionality from GuiComplexTextEditPopup into GuiTextEditPopup and removed the source files for the former -* Updated the String::Utils::trim function with better code and removed some inline text trimming throughout the application +* Lots of other general code refactoring * Increased the warning level for Clang/LLVM and GCC by adding -Wall, -Wpedantic and some additional flags * Fixed a lot of compiler warnings introduced by the -Wall and -Wpedantic flags * Changed the language standard from C++14 to C++17 * Increased the minimal required compiler version to 5.0.0 for Clang/LLVM and 7.1 for GCC -* Added a CMake option to build with AddressSanitizer +* Added CMake options to build with AddressSanitizer, ThreadSanitizer and UndefinedBehaviorSanitizer * Changed two clang-format rules related to braced lists and reformatted the codebase * Bundled the October 2021 release of the Mozilla TLS/SSL certificates * Updated the MAME index files to include ROMs up to MAME version 0.237 @@ -129,6 +129,7 @@ Apart from all the above, a huge amount of work has gone into fixing bugs, refac * Leading and trailing whitespace characters would not get trimmed from the collection name when creating a new custom collection * Leading and trailing whitespace characters would get included in scraper search refines and TheGamesDB searches * Leading and trailing whitespace characters would get included in game name filters +* Fixed multiple data races throughout the codebase caused by insufficient thread safety * Game name (text) filters were matching the system names for collection systems if the "Show system names in collections" setting was enabled * Brackets such as () and [] were filtered from game names in collection systems if the "Show system names in collections" setting was enabled * If a theme used the forceUppercase property for a TextListComponent, this value was always set to true even if the theme defined it as false diff --git a/INSTALL-DEV.md b/INSTALL-DEV.md index d3bac13a0..94b89ff0d 100644 --- a/INSTALL-DEV.md +++ b/INSTALL-DEV.md @@ -193,9 +193,26 @@ cmake -DCMAKE_BUILD_TYPE=Debug -DASAN=on . make ``` -This tool isn't very useful without debug symbols so only include it for a Debug or Profiling build. Both Clang and GCC support this tool. +To enable ThreadSanitizer which helps with identifying data races for multi-threaded code, build with the TSAN option: +``` +cmake -DCMAKE_BUILD_TYPE=Debug -DTSAN=on . +make +``` -As for more advanced debugging, Valgrind is a very powerful and useful tool which can analyze many aspects of the application. Be aware that some of the Valgrind tools should be run with an optimized build, and some with optimizations turned off. Refer to the Valgrind documentation for more information. +To enable UndefinedBehaviorSanitizer which helps with identifying bugs that may otherwise be hard to find, build with the UBSAN option: +``` +cmake -DCMAKE_BUILD_TYPE=Debug -UBSAN=on . +make +``` + +To get stack traces printed as well, set this environmental variable: +``` +export UBSAN_OPTIONS=print_stacktrace=1 +``` + +These tools aren't very useful without debug symbols so only use them for a Debug or Profiling build. Clang and GCC support all three tools. Note that ASAN and TSAN can't be combined. + +As for advanced debugging, Valgrind is a very powerful and useful tool which can analyze many aspects of the application. Be aware that some of the Valgrind tools should be run with an optimized build, and some with optimizations turned off. Refer to the Valgrind documentation for more information. The most common tool is Memcheck to check for memory leaks, which you run like this: @@ -533,7 +550,24 @@ cmake -DCMAKE_BUILD_TYPE=Debug -DASAN=on . make ``` -This tool isn't very useful without debug symbols so only include it for a Debug or Profiling build. Both Clang and GCC support this tool. +To enable ThreadSanitizer which helps with identifying data races for multi-threaded code, build with the TSAN option: +``` +cmake -DCMAKE_BUILD_TYPE=Debug -DTSAN=on . +make +``` + +To enable UndefinedBehaviorSanitizer which helps with identifying bugs that may otherwise be hard to find, build with the UBSAN option: +``` +cmake -DCMAKE_BUILD_TYPE=Debug -UBSAN=on . +make +``` + +To get stack traces printed as well, set this environmental variable: +``` +export UBSAN_OPTIONS=print_stacktrace=1 +``` + +These tools aren't very useful without debug symbols so only use them for a Debug or Profiling build. Note that ASAN and TSAN can't be combined. Specifically on macOS it seems as if AddressSanitizer generates a lot of false positives regarding container overflows, so it may be necessary to ignore these: ``` @@ -1093,6 +1127,8 @@ cmake -G "NMake Makefiles" -DWIN32_INCLUDE_DIR=../include -DASAN=on . nmake ``` +ThreadSanitizer and UndefinedBehaviorSanitizer aren't available for the MSVC compiler. + For some annoying reason MSVC is the only compiler that creates a debug build by default and where you need to explicitly set the build type to Release. Unfortunately nmake does not support parallel compiles so it's very slow. There are third party solutions to get multi-core building working with MSVC, but I've not investigated this in depth. @@ -1121,7 +1157,7 @@ cmake -G "MinGW Makefiles" -DWIN32_INCLUDE_DIR=../include -DCMAKE_BUILD_TYPE=Deb make ``` -Unfortunately AddressSanitizer does not seem to be supported with MinGW. +Unfortunately AddressSanitizer, ThreadSanitizer and UndefinedBehaviorSanitizer do not seem to be supported with MinGW. For some reason defining the `../include` path doesn't work when running CMake from PowerShell (and no, changing to backslash doesn't help). Instead use Bash, by running from a Git Bash shell.