forked from OSchip/llvm-project
				
			[tsan] Fix Darwin GCD support after separation of Processor and ThreadState
Recent TSan changes (r267678) which factor out parts of ThreadState into a Processor structure broke worker threads on OS X. This fixes it by properly calling ProcCreate for GCD worker threads and by replacing some CHECKs with RAW_CHECK in early process initialization. CHECK() in TSan calls the allocator, which requires a valid Processor. llvm-svn: 267864
This commit is contained in:
		
							parent
							
								
									24b5baed27
								
							
						
					
					
						commit
						dc7b607b09
					
				| 
						 | 
					@ -602,7 +602,7 @@ void MaybeReexec() {
 | 
				
			||||||
  // wrappers work. If it is not, set DYLD_INSERT_LIBRARIES and re-exec
 | 
					  // wrappers work. If it is not, set DYLD_INSERT_LIBRARIES and re-exec
 | 
				
			||||||
  // ourselves.
 | 
					  // ourselves.
 | 
				
			||||||
  Dl_info info;
 | 
					  Dl_info info;
 | 
				
			||||||
  CHECK(dladdr((void*)((uptr)&__sanitizer_report_error_summary), &info));
 | 
					  RAW_CHECK(dladdr((void*)((uptr)&__sanitizer_report_error_summary), &info));
 | 
				
			||||||
  char *dyld_insert_libraries =
 | 
					  char *dyld_insert_libraries =
 | 
				
			||||||
      const_cast<char*>(GetEnv(kDyldInsertLibraries));
 | 
					      const_cast<char*>(GetEnv(kDyldInsertLibraries));
 | 
				
			||||||
  uptr old_env_len = dyld_insert_libraries ?
 | 
					  uptr old_env_len = dyld_insert_libraries ?
 | 
				
			||||||
| 
						 | 
					@ -647,7 +647,7 @@ void MaybeReexec() {
 | 
				
			||||||
           "environment variable and re-execute itself, but execv() failed, "
 | 
					           "environment variable and re-execute itself, but execv() failed, "
 | 
				
			||||||
           "possibly because of sandbox restrictions. Make sure to launch the "
 | 
					           "possibly because of sandbox restrictions. Make sure to launch the "
 | 
				
			||||||
           "executable with:\n%s=%s\n", kDyldInsertLibraries, new_env);
 | 
					           "executable with:\n%s=%s\n", kDyldInsertLibraries, new_env);
 | 
				
			||||||
    CHECK("execv failed" && 0);
 | 
					    RAW_CHECK("execv failed" && 0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Verify that interceptors really work.  We'll use dlsym to locate
 | 
					  // Verify that interceptors really work.  We'll use dlsym to locate
 | 
				
			||||||
| 
						 | 
					@ -655,14 +655,14 @@ void MaybeReexec() {
 | 
				
			||||||
  // "wrap_pthread_create" within our own dylib.
 | 
					  // "wrap_pthread_create" within our own dylib.
 | 
				
			||||||
  Dl_info info_pthread_create;
 | 
					  Dl_info info_pthread_create;
 | 
				
			||||||
  void *dlopen_addr = dlsym(RTLD_DEFAULT, "pthread_create");
 | 
					  void *dlopen_addr = dlsym(RTLD_DEFAULT, "pthread_create");
 | 
				
			||||||
  CHECK(dladdr(dlopen_addr, &info_pthread_create));
 | 
					  RAW_CHECK(dladdr(dlopen_addr, &info_pthread_create));
 | 
				
			||||||
  if (internal_strcmp(info.dli_fname, info_pthread_create.dli_fname) != 0) {
 | 
					  if (internal_strcmp(info.dli_fname, info_pthread_create.dli_fname) != 0) {
 | 
				
			||||||
    Report(
 | 
					    Report(
 | 
				
			||||||
        "ERROR: Interceptors are not working. This may be because %s is "
 | 
					        "ERROR: Interceptors are not working. This may be because %s is "
 | 
				
			||||||
        "loaded too late (e.g. via dlopen). Please launch the executable "
 | 
					        "loaded too late (e.g. via dlopen). Please launch the executable "
 | 
				
			||||||
        "with:\n%s=%s\n",
 | 
					        "with:\n%s=%s\n",
 | 
				
			||||||
        SanitizerToolName, kDyldInsertLibraries, info.dli_fname);
 | 
					        SanitizerToolName, kDyldInsertLibraries, info.dli_fname);
 | 
				
			||||||
    CHECK("interceptors not installed" && 0);
 | 
					    RAW_CHECK("interceptors not installed" && 0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!lib_is_in_env)
 | 
					  if (!lib_is_in_env)
 | 
				
			||||||
| 
						 | 
					@ -677,7 +677,7 @@ void MaybeReexec() {
 | 
				
			||||||
  // sign and the '\0' char.
 | 
					  // sign and the '\0' char.
 | 
				
			||||||
  char *new_env = (char*)allocator_for_env.Allocate(
 | 
					  char *new_env = (char*)allocator_for_env.Allocate(
 | 
				
			||||||
      old_env_len + 2 + env_name_len);
 | 
					      old_env_len + 2 + env_name_len);
 | 
				
			||||||
  CHECK(new_env);
 | 
					  RAW_CHECK(new_env);
 | 
				
			||||||
  internal_memset(new_env, '\0', old_env_len + 2 + env_name_len);
 | 
					  internal_memset(new_env, '\0', old_env_len + 2 + env_name_len);
 | 
				
			||||||
  internal_strncpy(new_env, kDyldInsertLibraries, env_name_len);
 | 
					  internal_strncpy(new_env, kDyldInsertLibraries, env_name_len);
 | 
				
			||||||
  new_env[env_name_len] = '=';
 | 
					  new_env[env_name_len] = '=';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,10 +135,12 @@ static void my_pthread_introspection_hook(unsigned int event, pthread_t thread,
 | 
				
			||||||
  if (event == PTHREAD_INTROSPECTION_THREAD_CREATE) {
 | 
					  if (event == PTHREAD_INTROSPECTION_THREAD_CREATE) {
 | 
				
			||||||
    if (thread == pthread_self()) {
 | 
					    if (thread == pthread_self()) {
 | 
				
			||||||
      // The current thread is a newly created GCD worker thread.
 | 
					      // The current thread is a newly created GCD worker thread.
 | 
				
			||||||
 | 
					      ThreadState *thr = cur_thread();
 | 
				
			||||||
 | 
					      Processor *proc = ProcCreate();
 | 
				
			||||||
 | 
					      ProcWire(proc, thr);
 | 
				
			||||||
      ThreadState *parent_thread_state = nullptr;  // No parent.
 | 
					      ThreadState *parent_thread_state = nullptr;  // No parent.
 | 
				
			||||||
      int tid = ThreadCreate(parent_thread_state, 0, (uptr)thread, true);
 | 
					      int tid = ThreadCreate(parent_thread_state, 0, (uptr)thread, true);
 | 
				
			||||||
      CHECK_NE(tid, 0);
 | 
					      CHECK_NE(tid, 0);
 | 
				
			||||||
      ThreadState *thr = cur_thread();
 | 
					 | 
				
			||||||
      ThreadStart(thr, tid, GetTid());
 | 
					      ThreadStart(thr, tid, GetTid());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else if (event == PTHREAD_INTROSPECTION_THREAD_TERMINATE) {
 | 
					  } else if (event == PTHREAD_INTROSPECTION_THREAD_TERMINATE) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue