멀티 스레딩 문제를 감지하고 디버깅하는 방법은 무엇입니까?
이것은 이 질문에 대한 후속 조치이며이 점에 대한 의견을 얻지 못했습니다. 다음은 간단한 질문입니다.
다중 스레드 코드에서 발생하는 문제를 감지하고 디버깅 할 수 있습니까?
종종 고객에게 다음과 같이 말해야합니다. "여기에서 문제를 재현 할 수 없으므로 해결할 수 없습니다. 문제를 재현하는 단계를 알려 주시면 해결하겠습니다." 멀티 스레딩 문제라는 것을 안다면 다소 불쾌한 대답이지만 대부분은 그렇지 않습니다. 문제가 멀티 스레딩 문제라는 것을 어떻게 알 수 있으며 디버깅 방법은 무엇입니까?
특별한 로깅 프레임 워크, 디버깅 기술, 코드 검사기 또는 이러한 문제를 해결하는 데 도움이되는 다른 것이 있는지 알고 싶습니다. 일반적인 접근 방식을 환영합니다. 답변이 언어와 관련된 것이면 .NET 및 Java에 보관하십시오.
스레딩 / 동시성 문제 는 복제하기 어려운 것으로 악명이 높으며, 이는 가능성을 피하거나 최소한 최소화하도록 설계해야하는 이유 중 하나입니다. 이것이 불변 객체가 매우 가치있는 이유입니다. 변경 가능한 객체를 단일 스레드로 분리 한 다음 스레드 간의 변경 가능한 객체 교환을 신중하게 제어합니다. "공유"개체가 아닌 개체 전달 디자인으로 프로그래밍을 시도합니다. 후자의 경우 완전히 동기화 된 제어 개체를 사용하고 (추론하기 더 쉬움) 동기화 된 개체가 동기화되어야하는 다른 개체를 사용하지 않도록하십시오. 즉, 독립적으로 유지하려고합니다. 최선의 방어는 좋은 디자인입니다.
교착 상태 일 때 스택 추적을 얻을 수 있다면 교착 상태 는 디버그하기 가장 쉽습니다. 대부분이 교착 상태 감지를 수행하는 추적이 주어지면 이유를 정확히 찾아낸 다음 코드에 대해 이유와 수정 방법을 추론하기가 쉽습니다. 교착 상태에서는 항상 다른 순서로 동일한 잠금을 획득하는 데 문제가됩니다.
라이브 잠금 은 더 어렵습니다. 오류 상태에서 시스템을 관찰 할 수있는 것이 최선의 방법입니다.
경쟁 조건 은 복제하기가 극도로 어렵고 수동 코드 검토에서 식별하기 훨씬 더 어렵습니다. 이것으로, 내가 일반적으로 취하는 경로는 복제 할 광범위한 테스트 외에 가능성에 대해 추론하고 이론을 증명하거나 반증하기 위해 정보를 기록하는 것입니다. 국가 부패의 직접적인 증거가있는 경우 부패를 기반으로 가능한 원인에 대해 추론 할 수 있습니다.
시스템이 복잡할수록 동시성 오류를 찾고 그 동작에 대해 추론하기가 더 어려워집니다. JVisualVM 및 원격 연결 프로파일 러와 같은 도구를 사용하십시오. 오류 상태의 시스템에 연결하고 스레드와 개체를 검사 할 수 있다면 생명을 구할 수 있습니다.
또한 CPU 코어 수, 파이프 라인, 버스 대역폭 등에 따라 가능한 동작의 차이에 유의하십시오. 하드웨어 변경은 문제를 복제하는 능력에 영향을 미칠 수 있습니다. 일부 문제는 단일 코어 CPU에서만 표시되고 다른 문제는 멀티 코어에서만 표시됩니다.
마지막으로 시스템 라이브러리와 함께 배포 된 동시성 객체를 사용 java.util.concurrent
하십시오. 예를 들어 Java 에서는 친구가됩니다. 자신의 동시성 제어 개체를 작성하는 것은 어렵고 위험합니다. 선택권이 있다면 전문가에게 맡기십시오.
나는 생각 대답은 당신이 당신에 도착 다른 질문은 꽤 좋은했다. 하지만이 점을 강조하겠습니다.
중요한 섹션의 공유 상태 만 수정 (상호 제외)
설정된 순서대로 잠금을 획득하고 반대 순서로 해제합니다.
가능할 때마다 미리 빌드 된 추상화를 사용합니다 (예 : java.util.concurrent)
또한 일부 분석 도구는 잠재적 인 문제를 감지 할 수 있습니다. 예를 들어, FindBugs 는 Java 프로그램에서 일부 스레딩 문제를 찾을 수 있습니다. 이러한 도구는 모든 문제를 찾을 수는 없지만 (실버 총알이 아닙니다) 도움을 줄 수 있습니다.
으로 vanslly은 매우 유용하지만, 조심 수의 절묘한 로깅 출력을 공부하고이 답변에 코멘트에 지적 Heisenbugs (불확정성 버그) .
재현하기 어려운 문제에 대한 보고서가 있다고 가정하면 항상 코드를 읽고, 쌍 코드 읽기를 통해 이러한 문제를 발견하므로 스레딩 의미 / 잠금 요구 사항을 논의 할 수 있습니다. 보고 된 문제를 기반으로이 작업을 수행하면 항상 하나 이상의 문제를 상당히 빠르게 해결합니다. 어려운 문제를 해결하는데도 상당히 저렴한 기술이라고 생각합니다.
ctrl + shift + f13을 누르라고 말할 수 없어서 죄송합니다.하지만 그런 기능을 사용할 수없는 것 같습니다. 그러나 단지 생각 무엇을 보고 받았던 문제가 실제로 있다 당신이 주에서 시작 할 필요가 없습니다) (보통 코드의 방향의 매우 강한 감각을 준다.
이미받은 다른 좋은 답변 외에도 : 항상 고객이 사용하는 프로세서 / 프로세서 코어 수만큼 또는 프로그램에 활성 스레드가있는 시스템에서 테스트하십시오. 그렇지 않으면 일부 멀티 스레딩 버그를 재현하는 것이 불가능할 수 있습니다.
크래시 덤프와는 별도로 기술은 광범위한 런타임 로깅입니다. 여기서 각 스레드는 수행중인 작업을 기록합니다.
오류가보고 될 때 첫 번째 질문은 "로그 파일이 어디에 있습니까?"일 수 있습니다.
때때로 로그 파일에서 문제를 볼 수 있습니다. "이 스레드는 여기에서 불법 / 예기치 않은 상태를 감지하고 있습니다.이 스레드는이 작업 직전 및 / 또는 직후에 다른 스레드가이를 수행했습니다."
로그 파일에 무슨 일이 일어나고 있는지 알려주지 않으면 고객에게 사과하고 코드에 충분히 많은 추가 로깅 문을 추가하고 고객에게 새 코드를 제공 한 다음 한 번 더 발생한 후에 수정하겠다고 말합니다. .
Java의 경우 javapathfinder 라는 검증 도구가 있는데,이 도구 는 코드의 잠재적 인 경쟁 조건 및 데스 락 버그에 대해 멀티 스레딩 애플리케이션을 디버그하고 검증하는 데 유용합니다.
Eclipse와 Netbean IDE 모두에서 잘 작동합니다.
[2019] github 저장소 https://github.com/javapathfinder
때로는 다중 스레드 솔루션을 피할 수 없습니다. 버그가 있으면 실시간으로 조사해야하는데, Visual Studio와 같은 대부분의 도구로는 거의 불가능합니다. 유일한 실용적인 해결책은 추적을 작성하는 것이지만 추적 자체는 다음을 수행해야합니다.
- 지연을 추가하지 마십시오
- 잠금을 사용하지 마십시오
- 멀티 스레딩 안전
- 정확한 순서로 무슨 일이 일어 났는지 추적하십시오.
이것은 불가능한 작업처럼 들리지만 추적을 메모리에 기록하면 쉽게 수행 할 수 있습니다. C #에서는 다음과 같습니다.
public const int MaxMessages = 0x100;
string[] messages = new string[MaxMessages];
int messagesIndex = -1;
public void Trace(string message) {
int thisIndex = Interlocked.Increment(ref messagesIndex);
messages[thisIndex] = message;
}
Trace () 메서드는 다중 스레딩 안전하고 차단되지 않으며 모든 스레드에서 호출 할 수 있습니다. 내 PC에서 실행하는 데 약 2 마이크로 초가 걸리며 충분히 빠릅니다.
무언가 잘못 될 수 있다고 생각되는 곳에 Trace () 명령을 추가하고 프로그램을 실행하고 오류가 발생할 때까지 기다린 다음 추적을 중지 한 다음 오류에 대한 추적을 조사하십시오.
스레드 및 타이밍 정보를 수집하고 버퍼를 재활용하며 추적을 멋지게 출력하는이 접근 방식에 대한 자세한 설명은 다음에서 찾을 수 있습니다. CodeProject : 실시간으로 다중 스레드 코드 디버깅 1
다중 스레드 코드를 디버깅 할 때 고려해야 할 몇 가지 디버깅 기술이 포함 된 작은 차트입니다. 차트가 커지고 있습니다. 추가 할 의견과 팁을 남겨주세요. ( 이 링크 에서 파일 업데이트 )
Visual Studio를 사용하면 각 스레드의 호출 스택을 검사하고 스레드간에 전환 할 수 있습니다. 모든 종류의 스레딩 문제를 추적하는 것으로는 충분하지 않지만 시작일뿐입니다. 다가오는 VS2010에는 다중 스레드 디버깅에 대한 많은 개선이 계획되어 있습니다.
.NET 코드의 스레딩 문제에 WinDbg + SoS를 사용했습니다. 잠금 (sync blokcs), 스레드 호출 스택 등을 검사 할 수 있습니다.
Tess Ferrandez's blog has good examples of using WinDbg to debug deadlocks in .NET.
assert() is your friend for detecting race-conditions. Whenever you enter a critical section, assert that the invariant associated with it is true (that's what CS's are for). Though, unfortunately, the check might be expensive and thus not suitable for use in production environment.
I implemented the tool vmlens to detect race conditions in java programs during runtime. It implements an algorithm called eraser.
Develop code the way that Princess recommended for your other question (Immutable objects, and Erlang-style message passing). It will be easier to detect multi-threading problems, because the interactions between threads will be well defined.
I faced a thread issue which was giving SAME wrong result and was not behaving un-predictably since each time other conditions(memory, scheduler, processing load) were more or less same.
From my experience, I can say that HARDEST PART is to recognize that it is a thread issue, and BEST SOLUTION is to review the multi-threaded code carefully. Just by looking carefully at the thread code you should try to figure out what can go wrong. Other ways (thread dump, profiler etc) will come second to it.
I'm using GNU and use simple script
$ more gdb_tracer
b func.cpp:2871
r
#c
while (1)
next
#step
end
The best thing I can think of is to stay away from multi-threaded code whenever possible. It seems there are very few programmers who can write bug free multi threaded applications and I would argue that there are no coders beeing able to write bug free large multi threaded applications.
참고URL : https://stackoverflow.com/questions/499634/how-to-detect-and-debug-multi-threading-problems
'Development Tip' 카테고리의 다른 글
.NET Core- "dotnet new sln"을 사용하는 경우 (0) | 2020.11.24 |
---|---|
Python에서 "global"문을 사용합니까? (0) | 2020.11.24 |
C #에서 한 번만 속성을 설정하는 방법이 있습니까? (0) | 2020.11.24 |
유형 안전성과 관련하여 Haskell 유형 대 newtype (0) | 2020.11.24 |
PostgreSQL에서 행이 업데이트 될 때 타임 스탬프 업데이트 (0) | 2020.11.24 |