mirror of
http://github.com/valkey-io/valkey
synced 2024-11-22 00:52:38 +00:00
bio: fix doFastMemoryTest.
If one thread got SIGSEGV, function sigsegvHandler() would be triggered,
it would call bioKillThreads(). But call pthread_cancel() to cancel itself
would make it block. Also note that if SIGSEGV is caught by bio thread, it
should kill the main thread in order to give a positive report.
(cherry picked from commit 8b70cb0ef8
)
This commit is contained in:
parent
7601ed344c
commit
5d9332266d
@ -268,10 +268,11 @@ void bioKillThreads(void) {
|
||||
int err, j;
|
||||
|
||||
for (j = 0; j < BIO_NUM_OPS; j++) {
|
||||
if (bio_threads[j] == pthread_self()) continue;
|
||||
if (bio_threads[j] && pthread_cancel(bio_threads[j]) == 0) {
|
||||
if ((err = pthread_join(bio_threads[j],NULL)) != 0) {
|
||||
serverLog(LL_WARNING,
|
||||
"Bio thread for job type #%d can be joined: %s",
|
||||
"Bio thread for job type #%d can not be joined: %s",
|
||||
j, strerror(err));
|
||||
} else {
|
||||
serverLog(LL_WARNING,
|
||||
|
22
src/debug.c
22
src/debug.c
@ -1512,6 +1512,26 @@ int memtest_test_linux_anonymous_maps(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static void killMainThread(void) {
|
||||
int err;
|
||||
if (pthread_self() != server.main_thread_id && pthread_cancel(server.main_thread_id) == 0) {
|
||||
if ((err = pthread_join(server.main_thread_id,NULL)) != 0) {
|
||||
serverLog(LL_WARNING, "main thread can not be joined: %s", strerror(err));
|
||||
} else {
|
||||
serverLog(LL_WARNING, "main thread terminated");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Kill the running threads (other than current) in an unclean way. This function
|
||||
* should be used only when it's critical to stop the threads for some reason.
|
||||
* Currently Redis does this only on crash (for instance on SIGSEGV) in order
|
||||
* to perform a fast memory check without other threads messing with memory. */
|
||||
static void killThreads(void) {
|
||||
killMainThread();
|
||||
bioKillThreads();
|
||||
}
|
||||
|
||||
/* Scans the (assumed) x86 code starting at addr, for a max of `len`
|
||||
* bytes, searching for E8 (callq) opcodes, and dumping the symbols
|
||||
* and the call offset if they appear to be valid. */
|
||||
@ -1589,7 +1609,7 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
|
||||
#if defined(HAVE_PROC_MAPS)
|
||||
/* Test memory */
|
||||
serverLogRaw(LL_WARNING|LL_RAW, "\n------ FAST MEMORY TEST ------\n");
|
||||
bioKillThreads();
|
||||
killThreads();
|
||||
if (memtest_test_linux_anonymous_maps()) {
|
||||
serverLogRaw(LL_WARNING|LL_RAW,
|
||||
"!!! MEMORY ERROR DETECTED! Check your memory ASAP !!!\n");
|
||||
|
@ -2814,6 +2814,7 @@ void initServer(void) {
|
||||
server.aof_state = server.aof_enabled ? AOF_ON : AOF_OFF;
|
||||
server.hz = server.config_hz;
|
||||
server.pid = getpid();
|
||||
server.main_thread_id = pthread_self();
|
||||
server.current_client = NULL;
|
||||
server.fixed_time_expire = 0;
|
||||
server.clients = listCreate();
|
||||
@ -5091,7 +5092,6 @@ int iAmMaster(void) {
|
||||
(server.cluster_enabled && nodeIsMaster(server.cluster->myself)));
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct timeval tv;
|
||||
int j;
|
||||
|
@ -1050,6 +1050,7 @@ struct clusterState;
|
||||
struct redisServer {
|
||||
/* General */
|
||||
pid_t pid; /* Main process pid. */
|
||||
pthread_t main_thread_id; /* Main thread id */
|
||||
char *configfile; /* Absolute config file path, or NULL */
|
||||
char *executable; /* Absolute executable file path. */
|
||||
char **exec_argv; /* Executable argv vector (copy). */
|
||||
|
Loading…
Reference in New Issue
Block a user