Program Tip

뮤텍스를 보유한 스레드를 확인할 수 있습니까?

programtip 2020. 11. 24. 19:24
반응형

뮤텍스를 보유한 스레드를 확인할 수 있습니까?


첫째, 멀티 스레딩 C 프로그램을 작성하기 위해 pthread 라이브러리를 사용합니다. 스레드는 항상 기다린 뮤텍스에 의해 중단됩니다. strace 유틸리티를 사용하여 스레드가 FUTEX_WAIT상태에 있음 을 찾을 때 당시 해당 뮤텍스를 보유하는 스레드를 알고 싶습니다. 하지만 어떻게 만들 수 있을지 모르겠습니다. 그렇게 할 수있는 유틸리티가 있습니까?

누군가 Java 가상 머신이 이것을 지원한다고 말했기 때문에 Linux가이 기능을 지원하는지 알고 싶습니다.


이를 위해 뮤텍스 내부에 대한 지식을 사용할 수 있습니다. 일반적으로 이것은별로 좋은 생각은 아니지만 디버깅에는 좋습니다.

pthreads의 NPTL 구현 (최신 glibc)을 사용하는 Linux __data.__owner에서는 pthread_mutex_t구조 구성원을 검사하여 현재 잠겨있는 스레드를 찾을 수 있습니다. 다음과 같이 프로세스에 연결 한 후 수행하는 방법입니다 gdb.

(gdb) thread 2
[Switching to thread 2 (Thread 0xb6d94b90 (LWP 22026))]#0  0xb771f424 in __kernel_vsyscall ()
(gdb) bt
#0  0xb771f424 in __kernel_vsyscall ()
#1  0xb76fec99 in __lll_lock_wait () from /lib/i686/cmov/libpthread.so.0
#2  0xb76fa0c4 in _L_lock_89 () from /lib/i686/cmov/libpthread.so.0
#3  0xb76f99f2 in pthread_mutex_lock () from /lib/i686/cmov/libpthread.so.0
#4  0x080484a6 in thread (x=0x0) at mutex_owner.c:8
#5  0xb76f84c0 in start_thread () from /lib/i686/cmov/libpthread.so.0
#6  0xb767784e in clone () from /lib/i686/cmov/libc.so.6
(gdb) up 4
#4  0x080484a6 in thread (x=0x0) at mutex_owner.c:8
8               pthread_mutex_lock(&mutex);
(gdb) print mutex.__data.__owner
$1 = 22025
(gdb)

(나는 중단 된 스레드로 전환하고, 고정 된 스레드를 찾기 위해 역 추적을 수행하고 pthread_mutex_lock(), 잠 그려는 뮤텍스의 이름을 찾기 위해 스택 프레임을 변경 한 다음 해당 뮤텍스의 소유자를 인쇄합니다). 이것은 LWP ID가 22025 인 스레드가 범인임을 알려줍니다.

그런 다음을 사용 thread find 22025하여 해당 gdb스레드 스레드 번호 를 찾아서 전환 할 수 있습니다.


나는 그러한 시설에 대해 알지 못하기 때문에 그렇게 쉽게 벗어날 수 없을 것이라고 생각합니다. 그리고 아마도 프로그램을 디버그하는 데 도움이 될 것이라고 생각하는 것만 큼 유익하지 않을 것입니다. 기술 수준이 낮은 것처럼 보이지만 로깅은 이러한 문제를 디버깅하는 데 도움이됩니다. 자신 만의 작은 로깅 기능 수집을 시작하십시오. 화려할 필요는 없으며 디버깅하는 동안 작업을 완료하면됩니다.

C ++ 죄송하지만 다음과 같습니다.

void logit(const bool aquired, const char* lockname, const int linenum)
{
    pthread_mutex_lock(&log_mutex);

    if (! aquired)
        logfile << pthread_self() << " tries lock " << lockname << " at " << linenum << endl;
    else
        logfile << pthread_self() << " has lock "   << lockname << " at " << linenum << endl;

    pthread_mutex_unlock(&log_mutex);
}


void someTask()
{
    logit(false, "some_mutex", __LINE__);

    pthread_mutex_lock(&some_mutex);

    logit(true, "some_mutex", __LINE__);

    // do stuff ...

    pthread_mutex_unlock(&some_mutex);
}

로깅은 완벽한 솔루션은 아니지만 아무것도 아닙니다. 일반적으로 알아야 할 정보를 얻을 수 있습니다.


Normally libc/platforms calls are abstracted by OS abstraction layer. The mutex dead locks can be tracked using a owner variable and pthread_mutex_timedlock. Whenever the thread locks it should update the variable with own tid(gettid() and can also have another variable for pthread id storage) . So when the other threads blocks and timed out on pthread_mutex_timedlock it can print the value of owner tid and pthread_id. this way you can easily find out the owner thread. please find the code snippet below, note that all the error conditions are not handled

pid_t ownerTid;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

class TimedMutex {
    public:
        TimedMutex()
        {
           struct timespec abs_time;

           while(1)
           {
               clock_gettime(CLOCK_MONOTONIC, &abs_time);
               abs_time.tv_sec += 10;
               if(pthread_mutex_timedlock(&mutex,&abs_time) == ETIMEDOUT)
               {
                   log("Lock held by thread=%d for more than 10 secs",ownerTid);
                   continue;
               }
               ownerTid = gettid();
           }
        }

        ~TimedMutex()
        {

             pthread_mutex_unlock(&mutex);  
        }
};

There are other ways to find out dead locks, maybe this link might help http://yusufonlinux.blogspot.in/2010/11/debugging-core-using-gdb.html.


Please read below link, This has a generic solution for finding the lock owner. It works even if lock in side a library and you don't have the source code.

https://en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/Deadlocks

참고URL : https://stackoverflow.com/questions/3483094/is-it-possible-to-determine-the-thread-holding-a-mutex

반응형