A thought of Linux deadlock detection "turn"

Source: Internet
Author: User
Tags mutex

Transferred from: http://www.cnblogs.com/mumuxinfei/p/4365697.html

Preface:
The previous blog post describes the use and principles of Pstack . Like Jstack, Pstack can get a thread stack snapshot of the process for easy inspection and performance evaluation. But the Jstack function is more powerful, it can be prompted for potential deadlock , and pstack only provide clues, need gdb further determination.
Under Linux, how to detect deadlocks , how to make the detection of deadlocks more intelligent and convenient? This is the core theme of this article, let us share the next idea.

General Practice:
Let's simulate a deadlock program and then use the usual way to determine if a deadlock has occurred, and what happens on those threads.
The following is a classic deadlock program:

Note: Thread A acquires lock 1, thread B acquires lock 2, and then thread A/b goes to get lock 2/1, both of whom do not let go, and not each other's, so Duang, Duang duang ...
Use Pstack to quickly scan the stack :
  
Found that there are two threads are waiting in lock, there is a suspect deadlock, the need for concrete confirmation after gdb.

  
Text interpretation: thread 10800 request Mutex_1(at this time by thread 10799 all), and thread 10799 request mutex_2(by thread 10800 all), so thread 10800 is waiting for the release of Thread 10799, and thread 10799 waits for thread 10800 to be released, so we can be sure that a deadlock has occurred.
But this approach requires developers to validate and exclude themselves, and complex cases are not easy.
In GdB, we can only see the thread that the mutex corresponds to, but cannot get back to the list of the mutex that the thread owns , if there is this information, like the jstack tool, get the decision of deadlock, just sweep down the stack information, will be able to determine the basic.

Detection model:
For deadlocks, the operating system course focuses on its regular model/detection algorithm/circumvention advice, which is no longer unfolding.
Word: The occurrence of deadlocks inevitably means that there is a link to the construction of a graph (dependency).
With regard to the detection model, we can assume that the lock is a forward edge , the thread A requesting the lock is the starting point , and the thread B that owns the lock is the end point. This forms a forward edge of thread A to thread B. The numerous locks (edges) and threads (points)constitute a graph .
Thus, a deadlock detection algorithm is transformed into a graph-based ring judgment problem . The problem can be easily realized by using the mature topological traversal algorithm .

1234567891011121314151617181920 //拓扑排序:可以测试一个有向图是否有环  voidGraph::topsort( )     Queue<Vertex> q;     intcounter = 0;     q.makeEmpty( );     foreach Vertex v         if( v.indegree == 0 )             q.enqueue( v );     while( !q.isEmpty( ) )             Vertex v = q.dequeue( );         counter++;        foreach Vertex w adjacent to v             if( --w.indegree == 0 )                 q.enqueue( w );         if( counter != NUM_VERTICES )         throwCycleFoundException( ); }

Solution:
The determination of the detection model makes the people enlightened. But how it landed is another stumbling block.
Let's start with the idea of retrieving the lock list owned by a thread in reverse. If we can intercept Lock/unlock operations like Java reflection, and add the ability to report thread-to-lock relationships, it's natural to build a graph. And then realize the automatic detection of deadlock.
However, C + + has no reflection, but it can be solved by adding the post code to all the Lock/unlock code. But this is intrusive to the user's code, can it be improved?
God always favors the diligent person, here we can use the macro extension ( the macro does not recursively expand, this is the key ) to skillfully implement this function.

123456789101112131415161718 #include <sys/syscall.h>#define gettid() syscall(__NR_gettid) // 拦截lock, 添加before, after操作, 记录锁与线程的关系#define pthread_mutex_lock(x)                                            \    do{                                                                 \        printf("before=>thread_id:%d apply mutex:%p\n", gettid(), x);    \        pthread_mutex_lock(x);                                           \        printf("after=>thread_id:%d acquire mutex:%p\n", gettid(), x);   \    while(false);// 拦截unlock, 添加after操作, 解除锁和线程的关系#define pthread_mutex_unlock(x)                                          \    do{                                                                 \        pthread_mutex_unlock(x);                                         \        printf("unlock=>thread_id: %d release mutex:%p\n", gettid(), x); \    while(false);

Note: The Gettid function is used to get the actual ID of the thread, with the name of the Pthread_mutex_lock/pthread_mutex_unlock macro, added to the before/after intercept call , and report the relationship between the lock and the thread .
We can do the actual diagram construction and detection for the before/after operation. And with this macro replacement, it's easy to solve the code intrusion problem.
Let us recall the use of jstack, guessing that Java is a reflection , easy to achieve a similar function, so that it can detect the deadlock situation.

Test results:
With the above theoretical basis and ideas, to try and expand.
Here's a simple library of testing tools, very simple to use.
In the code that needs to be instrumented, introduce the dead_lock_stub.h header file, and then add it at the beginning of the main function

1 DeadLockGraphic::getInstance().start_check();

The experimental results are as follows:
  
The network address of the sample code is as follows: Http://pan.baidu.com/s/1ntzHEeX

written at the end:
  
If you think this article is helpful to you, please give it a little reward. In fact, I would like to try to see if blogging can bring me a little bit of revenue. No matter how much, is a kind of sincere affirmation to the landlord.

  

A thought of Linux deadlock detection "turn"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.