Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
5a9e3f58
Commit
5a9e3f58
authored
Nov 21, 2012
by
antirez
Browse files
Fast memory test on Redis crash.
parent
3cb43283
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/debug.c
View file @
5a9e3f58
...
...
@@ -665,6 +665,49 @@ void logCurrentClient(void) {
}
}
#if defined(HAVE_PROC_MAPS)
int
memtest_non_destructive
(
void
*
addr
,
size_t
size
);
/* memtest.c */
int
memtest_test_linux_anonymous_maps
(
void
)
{
FILE
*
fp
=
fopen
(
"/proc/self/maps"
,
"r"
);
char
line
[
1024
];
size_t
start_addr
,
end_addr
,
size
;
while
(
fgets
(
line
,
sizeof
(
line
),
fp
)
!=
NULL
)
{
char
*
start
,
*
end
,
*
p
=
line
;
int
j
;
start
=
p
;
p
=
strchr
(
p
,
'-'
);
if
(
!
p
)
continue
;
*
p
++
=
'\0'
;
end
=
p
;
p
=
strchr
(
p
,
' '
);
if
(
!
p
)
continue
;
*
p
++
=
'\0'
;
if
(
strstr
(
p
,
"stack"
)
||
strstr
(
p
,
"vdso"
)
||
strstr
(
p
,
"vsyscall"
))
continue
;
if
(
!
strstr
(
p
,
"00:00"
))
continue
;
if
(
!
strstr
(
p
,
"rw"
))
continue
;
start_addr
=
strtoul
(
start
,
NULL
,
16
);
end_addr
=
strtoul
(
end
,
NULL
,
16
);
size
=
end_addr
-
start_addr
;
redisLog
(
REDIS_WARNING
,
"Testing memory at %lx (%lu bytes)"
,
start_addr
,
size
);
for
(
j
=
0
;
j
<
3
;
j
++
)
{
if
(
memtest_non_destructive
((
void
*
)
start_addr
,
size
)
!=
0
)
{
fclose
(
fp
);
return
1
;
}
}
}
fclose
(
fp
);
return
0
;
}
#endif
void
sigsegvHandler
(
int
sig
,
siginfo_t
*
info
,
void
*
secret
)
{
ucontext_t
*
uc
=
(
ucontext_t
*
)
secret
;
sds
infostring
,
clients
;
...
...
@@ -700,6 +743,18 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
/* Log dump of processor registers */
logRegisters
(
uc
);
#if defined(HAVE_PROC_MAPS)
/* Test memory */
redisLog
(
REDIS_WARNING
,
"--- FAST MEMORY TEST"
);
if
(
memtest_test_linux_anonymous_maps
())
{
redisLog
(
REDIS_WARNING
,
"!!! MEMORY ERROR DETECTED! Check your memory ASAP !!!"
);
}
else
{
redisLog
(
REDIS_WARNING
,
"Fast memory test PASSED, however your memory can still be broken. Please run a memory test for several hours if possible."
);
}
#endif
redisLog
(
REDIS_WARNING
,
"
\n
=== REDIS BUG REPORT END. Make sure to include from START to END. ===
\n\n
"
" Please report the crash opening an issue on github:
\n\n
"
...
...
src/memtest.c
View file @
5a9e3f58
...
...
@@ -35,6 +35,7 @@
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include "config.h"
#if (ULONG_MAX == 4294967295UL)
#define MEMTEST_32BIT
...
...
@@ -240,6 +241,36 @@ void memtest_test(size_t megabytes, int passes) {
}
}
/* This is a fast O(N) best effort memory test, only ZERO-ONE tests and
* checkerboard tests are performed, without pauses between setting and
* reading the value, so this can only detect a subclass of permanent errors.
*
* However the function does not destroy the content of the memory tested that
* is left unmodified.
*
* If a memory error is detected, 1 is returned. Otherwise 0 is returned. */
int
memtest_non_destructive
(
void
*
addr
,
size_t
size
)
{
volatile
unsigned
long
*
p
=
addr
;
unsigned
long
val
;
size_t
j
;
size
/=
sizeof
(
unsigned
long
);
for
(
j
=
0
;
j
<
size
;
j
++
)
{
val
=
p
[
j
];
p
[
j
]
=
0
;
if
(
p
[
j
]
!=
0
)
goto
err
;
p
[
j
]
=
(
unsigned
long
)
-
1
;
if
(
p
[
j
]
!=
(
unsigned
long
)
-
1
)
goto
err
;
p
[
j
]
=
ULONG_ONEZERO
;
if
(
p
[
j
]
!=
ULONG_ONEZERO
)
goto
err
;
p
[
j
]
=
ULONG_ZEROONE
;
if
(
p
[
j
]
!=
ULONG_ZEROONE
)
goto
err
;
p
[
j
]
=
val
;
/* restore the original value. */
}
return
0
;
err:
/* memory error detected. */
p
[
j
]
=
val
;
return
1
;
}
void
memtest
(
size_t
megabytes
,
int
passes
)
{
if
(
ioctl
(
1
,
TIOCGWINSZ
,
&
ws
)
==
-
1
)
{
ws
.
ws_col
=
80
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment