summaryrefslogtreecommitdiff
path: root/src/memtest.c
diff options
context:
space:
mode:
authorOzan Tezcan <ozantezcan@gmail.com>2021-11-11 14:51:33 +0300
committerGitHub <noreply@github.com>2021-11-11 13:51:33 +0200
commitb91d8b289bb64965c5eaa445809f9f49293e99c0 (patch)
tree7e921ab63b0c7535f2a13f1ed75391a01d757a26 /src/memtest.c
parentcd6b3d558be0703b1a43f9fe58fd5f1ed7452829 (diff)
downloadredis-b91d8b289bb64965c5eaa445809f9f49293e99c0.tar.gz
Add sanitizer support and clean up sanitizer findings (#9601)
- Added sanitizer support. `address`, `undefined` and `thread` sanitizers are available. - To build Redis with desired sanitizer : `make SANITIZER=undefined` - There were some sanitizer findings, cleaned up codebase - Added tests with address and undefined behavior sanitizers to daily CI. - Added tests with address sanitizer to the per-PR CI (smoke out mem leaks sooner). Basically, there are three types of issues : **1- Unaligned load/store** : Most probably, this issue may cause a crash on a platform that does not support unaligned access. Redis does unaligned access only on supported platforms. **2- Signed integer overflow.** Although, signed overflow issue can be problematic time to time and change how compiler generates code, current findings mostly about signed shift or simple addition overflow. For most platforms Redis can be compiled for, this wouldn't cause any issue as far as I can tell (checked generated code on godbolt.org). **3 -Minor leak** (redis-cli), **use-after-free**(just before calling exit()); UB means nothing guaranteed and risky to reason about program behavior but I don't think any of the fixes here worth backporting. As sanitizers are now part of the CI, preventing new issues will be the real benefit.
Diffstat (limited to 'src/memtest.c')
-rw-r--r--src/memtest.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/memtest.c b/src/memtest.c
index bc0ac3a66..1ca4b82cf 100644
--- a/src/memtest.c
+++ b/src/memtest.c
@@ -56,6 +56,16 @@
#define ULONG_ZEROONE 0x5555555555555555UL
#endif
+#if defined(__has_attribute)
+#if __has_attribute(no_sanitize)
+#define NO_SANITIZE(sanitizer) __attribute__((no_sanitize(sanitizer)))
+#endif
+#endif
+
+#if !defined(NO_SANITIZE)
+#define NO_SANITIZE(sanitizer)
+#endif
+
static struct winsize ws;
size_t progress_printed; /* Printed chars in screen-wide progress bar. */
size_t progress_full; /* How many chars to write to fill the progress bar. */
@@ -277,6 +287,8 @@ int memtest_test(unsigned long *m, size_t bytes, int passes, int interactive) {
* end of the region between fill and compare cycles in order to trash
* the cache. */
#define MEMTEST_DECACHE_SIZE (1024*8)
+
+NO_SANITIZE("undefined")
int memtest_preserving_test(unsigned long *m, size_t bytes, int passes) {
unsigned long backup[MEMTEST_BACKUP_WORDS];
unsigned long *p = m;