mirror of https://github.com/redis/redis.git
				
				
				
			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.
This commit is contained in:
		
							parent
							
								
									810e28a397
								
							
						
					
					
						commit
						8b70cb0ef8
					
				| 
						 | 
				
			
			@ -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
								
								
								
								
							| 
						 | 
				
			
			@ -1565,12 +1565,32 @@ 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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void doFastMemoryTest(void) {
 | 
			
		||||
#if defined(HAVE_PROC_MAPS)
 | 
			
		||||
    if (server.memcheck_enabled) {
 | 
			
		||||
        /* 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");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2879,6 +2879,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();
 | 
			
		||||
| 
						 | 
				
			
			@ -5174,7 +5175,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