뮤텍스를 보유한 스레드를 확인할 수 있습니까?
첫째, 멀티 스레딩 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
'Program Tip' 카테고리의 다른 글
왜 SPARSE COLUMN을 사용해야합니까? (0) | 2020.11.24 |
---|---|
강력하고 "현대적인"Fortran 코드 작성 (0) | 2020.11.24 |
DEFAULT 값없이 null이 아닌 열을 추가 할 수 있습니까? (0) | 2020.11.24 |
여러 코어를 자동으로 사용하는 R 패키지? (0) | 2020.11.24 |
SVG에서 속이 빈 원 그리기 (0) | 2020.11.24 |