c++ - gtest DEATH_TEST complains about fork() and threads, but only threads found had been joined -


i'm using gtest unit testing and, in particular, have death_tests assertions in debug builds. setup() test, have create object creates thread, goes off , work, returns data, , joins on object's thread. test fixture's setup() returns, allowing test body run.

i've noticed death_test complain death tests use fork(), unsafe particularly in threaded context. test, google test detected 2 threads. is, of course, valid problem if there's multiple threads running. sometimes, however, no such warning exists. seems race condition.

so looking it, discovered gtest using /proc/self/task pseudo filesystem discover threads. since of threads named, decided use /proc/self/task/[tid]/comm discover thread might lingering. indeed, it's exact same thread join()ed. came example source code reproduce issue 1) reproduces gtest's thread detection gtest, , 2) if target thread lingering, emits message stdout.

// g++ test.cpp --std=c++11 -pthread #include <iostream> #include <fstream> #include <string> #include <thread>  #include <dirent.h> // dir*, dirent*, opendir(), closedir(); enumerate pseudo-fs /proc/self/task #include <string.h> // strcmp();  #include <sys/prctl.h> // prctl(), pr_set_name; sets name of current thread  std::string get_thread_name(std::string tid_str) {     std::fstream f(std::string("/proc/self/task/") + tid_str + std::string("/comm"));     tid_str.clear();     std::getline(f, tid_str);     return tid_str; }  int main(int argc, char **argv) {     // until sigterm (ctrl-c)     while (true) {         std::thread a([](){             prctl(pr_set_name,"target",0,0,0);         });         a.join();         if (dir *dir = opendir("/proc/self/task")) {             bool found = false;             while (dirent *entry = readdir(dir)) {                 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {                     std::string name = get_thread_name(entry->d_name);                     if ( found = (name == "target") ) {                         std::cout << "thread " << entry->d_name << " -- " << name << std::endl;                     }                 }             }             closedir(dir);             if ( not found ) {                 std::cout << "not found" << std::endl;             }         } else {             std::cout << "cannot enumerate" << std::endl;         }     }      return 0; } 

using ubuntu 14.04 , gcc 4.8.2-19ubuntu1 , command commented on first line of example source, end output stdout indicating race condition seem exist. of output states "not found", while output interspersed tid of target-named thread. disable output of "not found" , observe emitted tid changes.

in working on this, discovered system's thread id ([tid] in /proc/self/task/[tid]) different pthread's pthread_t expected in pthread_getname_np(). discovered there prctl pr_get_name appears retrieve name of current (calling) thread. 1 of questions is: is there documented api retrieve thread's name if given system tid (eg, don't have read /proc/self/task/[tid]/comm)? that's side question.

more importantly, is there way guarantee false positive far fork() problems concerned?, , related question: is there better way ensure std::thread has finished join()?

  1. i think w/o tracking system tid <-> pthread id mappings you're out of luck; pthread id opaque value decouple platform-specific process abstractions , don't believe there public apis extract it.

  2. i think procfs & std::thread::join / pthread_join race unavoidable, @ least in present linux implementations. pthread_join waits kernel clear registered memory location & signal futex during thread exit. happens in mm_release (linux/kernel/fork.c) invoked right in middle of do_exit, before of task accounting structures updated. suspect traversing procfs after pthread_join completes can race rest of process teardown.

a dissatisfying answer in terms of problem you're trying solve, hope helps.


Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -