이 답변에 대한 의견을 읽으십시오 .
테스트를 작성할 수 없다고해서 테스트가 중단되지 않았다는 의미는 아닙니다. 일반적으로 예상대로 작동하는 정의되지 않은 동작 (C 및 C ++에는이 기능이 가득 함), 경쟁 조건, 메모리 모델이 약하여 잠재적 인 순서 변경 … – CodeInChaos 7 시간 전
@CodesInChaos 만약 그것이 재현 될 수 없다면 ‘fix’에 쓰여진 코드도 테스트 될 수 없습니다. 그리고 테스트되지 않은 코드를 라이브에 넣는 것은 제 생각에 더 나쁜 범죄입니다 – RhysW 5 시간 전
… 테스트 케이스의 경쟁 조건으로 인해 발생하는 생산 문제에서 매우 드물게 발생하는 일반적인 방법이 있는지 궁금합니다.
답변
1978 년 이래로이 미친 사업에 종사 한 후 임베드 된 실시간 컴퓨팅, 멀티 태스킹, 멀티 스레드, 다중 시스템, 때로는 여러 물리적 프로세서로 작업하면서 거의 모든 시간을 레이스에서 경쟁했습니다. 조건, 내가 생각하는 의견은 귀하의 질문에 대한 답변이 매우 간단하다는 것입니다.
아니.
테스트에서 경쟁 조건을 유발할 수있는 일반적인 방법은 없습니다.
유일한 희망은 시스템에서 완전히 설계하는 것입니다.
다른 사람이 들어간 것을 발견하면 개미집 밖으로 내 던져서 제거하도록 재 설계해야합니다. 시스템에서 그의 가짜 pas (f *** up로 발음)를 디자인 한 후에는 개미에서 그를 풀어 놓을 수 있습니다. (개미가 이미 뼈를 남기고 이미 소비했다면 “이것은 경쟁 조건을 XYZ 프로젝트에 넣는 사람들에게 일어난 일입니다!”라는 표시를 남기고 그대로 두십시오.)
답변
답변
이러한 종류의 문제에 대해 내가 아는 가장 좋은 도구는 Helgrind 라는 Valgrind의 확장입니다 .
기본적으로 Valgrind는 가상 프로세서를 시뮬레이션하고 그 위에서 바이너리 (수정되지 않은)를 실행하므로 메모리에 대한 모든 단일 액세스를 확인할 수 있습니다. 이 프레임 워크를 사용하여 Helgrind watch 시스템은 공유 변수에 대한 액세스가 상호 배제 메커니즘에 의해 제대로 보호되지 않을 때 추론하도록 요청합니다. 그렇게하면 실제로 발생하지 않았더라도 이론적 경쟁 조건을 감지 할 수 있습니다.
인텔은 인텔 인스펙터 라는 매우 유사한 도구를 판매합니다 .
이러한 도구는 훌륭한 결과를 제공하지만 분석하는 동안 프로그램 속도가 상당히 느려집니다.
답변
멀티 스레딩 버그를 노출하려면 서로 다른 실행 스레드가 특정 인터리브 순서로 단계를 수행해야합니다. 일반적으로이 인터리빙을 제어하기 위해 일종의 “핸들”을 얻기 위해 수동 디버깅이나 코드 조작 없이는 수행하기가 어렵습니다. 그러나 예측 불가능하게 작동하는 코드를 변경하면 예측 불가능성에 종종 영향을 미치므로 자동화하기가 어렵습니다.
Jaroslav Tulach는 실용적인 API 디자인 에서 유용한 트릭을 설명합니다 . 문제가되는 코드에 로깅 문이있는 경우 해당 로깅 문 소비자 (예 : 주입 된 의사 터미널)를 조작하여 특정 로그 메시지를 특정하게 받도록합니다. 그들의 내용에 따라 주문하십시오. 이를 통해 아직 존재하지 않는 프로덕션 코드에 아무것도 추가하지 않고도 다른 스레드에서 단계의 인터리빙을 제어 할 수 있습니다.
답변
다양한 종류의 정의되지 않은 동작 (특히 경쟁 조건)이 존재하지 않는다는 것을 절대 확신 할 수있는 방법이 없습니다.
그러나 그러한 상황을 잘 보여주는 여러 가지 도구가 있습니다. 수정 사항이 유효하다는 것을 증명할 수는 없지만 현재 이러한 도구에 문제가 있음을 증명할 수 있습니다.
이 목적을위한 몇 가지 흥미로운 도구 :
Valgrind는 메모리 검사기입니다. 메모리 누수, 초기화되지 않은 메모리 읽기, 매달려있는 포인터 사용 및 범위를 벗어난 액세스를 찾습니다.
Helgrind는 스레드 안전 검사기입니다. 경쟁 조건을 찾습니다.
둘 다 동적 계측에 의해 작동합니다. 즉, 프로그램을있는 그대로 가져와 가상화 된 환경에서 실행합니다. 이렇게하면 방해가되지 않지만 느려집니다.
UBSan은 정의되지 않은 동작 검사기입니다. 정수 오버플로, 범위를 벗어난 시프트 및 유사한 것들과 같은 다양한 C 및 C ++ 정의되지 않은 동작을 찾습니다.
MSan은 메모리 검사기입니다. Valgrind와 비슷한 목표를 가지고 있습니다.
TSan은 스레드 안전 검사기입니다. Helgrind와 비슷한 목표를 가지고 있습니다.
이 세 가지는 Clang 컴파일러에 내장되어 있으며 컴파일시 코드를 생성합니다. 즉, 빌드 프로세스에 통합해야하며 (특히 Clang으로 컴파일해야 함) 초기에 * grind보다 설정하기가 훨씬 어렵지만 반면에 런타임 오버 헤드는 훨씬 낮습니다.
내가 나열한 모든 도구는 Linux에서 작동하고 일부는 MacOS에서 작동합니다. 아직 Windows에서 안정적으로 작동하지 않는다고 생각합니다.
답변
여기에있는 대부분의 답변은이 질문을 “경쟁 조건을 자동으로 어떻게 감지합니까?”라고 잘못 생각하는 것 같습니다. 문제는 “테스트에서 레이스 조건을 찾을 때 어떻게 테스트합니까?”
이를 수행하는 방법은 테스트에만 사용되는 코드에 동기화를 도입하는 것입니다. 예를 들어, 이벤트 X가 이벤트 A와 이벤트 B 사이에있을 때 경쟁 조건이 발생하면 응용 프로그램을 테스트하기 위해 이벤트 A가 발생한 후 이벤트 X가 발생할 때까지 기다리는 코드를 작성하십시오. 테스트를 위해 애플리케이션과 대화 할 수있는 방법이 필요할 것입니다 ( “이것은 테스트 중이므로이 위치에서이 이벤트를 기다립니다”).
node.js와 mongo를 사용하고 있는데 일부 작업에는 여러 컬렉션에서 일관된 데이터를 만드는 것이 포함됩니다. 이 경우, 단위 테스트는 응용 프로그램을 호출하여 “이벤트 X에 대한 대기 설정”을 알리고 응용 프로그램이 설정 한 후에는 이벤트 X에 대한 테스트를 실행 한 후 테스트에 지시합니다. 응용 프로그램 ( “이벤트 X 대기 중입니다”)으로 나머지 테스트가 정상적으로 실행됩니다.
여기에 대한 답변은 파이썬의 맥락 에서이 유형의 것을 자세히 설명합니다 : https : //.com/questions/19602535/how-can-i-reproduce-the-race-conditions-in-this-python-code- 확실하게