如何在android jni中调试mutex死锁

时间:2017-01-20 07:00:44

标签: android android-ndk deadlock

我正在维护一个将在Android应用程序中使用的c ++库。 我发现它有时会像死锁一样悬挂。 代码架构非常复杂,我可以在这里大致描述一下。该库有两个线程T1和T2,它们都在while循环中运行。 (不断更新数据类型)

T1::Run() {
  while (1) {
    // Compute so many data type Obj1 and Obj2
    // So many for loop which will step by step to handle each Obj1   
    // and Obj2.
    std::cout << "T1++" << std::endl;
    for () { ... }
    for () { ... }
    std::cout << "T1--" << std::endl;
  }
}

T2::Run() {
  while (1) {
    // Compute so many data type Obj1 and Obj2
    // So many for loop which will step by step to handle each Obj1   
    // and Obj2.
    std::cout << "T2++" << std::endl;
    for () { ... }
    for () { ... }
    std::cout << "T2--" << std::endl;
  }
}

数据类型Obj1和Obj2都有几个互斥锁。并且他们将锁定多个成员函数中的互斥锁。

class Obj1 {
  std::mutex mutex1;
  std::mutex mutex2;
  std::mutex mutex3;
  void fun1() { unique_lock<mutex> lock(mutex1); }
  void fun2() { unique_lock<mutex> lock(mutex2);
                // Do something...
                // Another Obj1 instance : temp
                temp->fun3().
                // ... }
  void fun3() { unique_lock<mutex> lock(mutex1);
                unique_lock<mutex> lock(mutex3);
                // Do something...
                // Another Obj2 instance : temp
                temp->fun1().
                // ... }
}

class Obj2 {
  std::mutex mutex1;
  std::mutex mutex2;
  std::mutex mutex3;
  void fun1() { unique_lock<mutex> lock(mutex1); }
  void fun2() { unique_lock<mutex> lock(mutex2); }
  void fun3() { unique_lock<mutex> lock(mutex1);
                unique_lock<mutex> lock(mutex3); }
}

问题是我找不到一种有用的方法来验证它是否真的是一个死锁问题。 我试图打印日志,但我只能确保当库挂起时,打印日志“T1 ++”或“T2 ++”,但“T1--”和“T2--”没有。 如果我尝试在每个for循环中打印更多日志,那么日志将会太多,并且很难再现死锁。 (时间问题)

我认为Obj1 :: fun2()和Obj1 :: fun3的使用存在潜在的死锁问题。因为Obj1将首先锁定其互斥锁,然后调用另一个Obj1实例的成员函数(此成员函数也会锁定此实例互斥锁),因为T1和T2将同时调用Obj1 :: fun2()和fun3(),可能会触发死锁。我为这些类型的成员函数添加了一个新的全局互斥锁,但它没用。

我想询问是否有任何工具可以识别哪个线程被哪个互斥锁阻塞?或者针对这些情况的任何其他建议?

0 个答案:

没有答案