Czytanie komentarzy do tej odpowiedzi , w szczególności:
To, że nie możesz napisać testu, nie oznacza, że nie jest zepsuty. Niezdefiniowane zachowanie, które zwykle działa zgodnie z oczekiwaniami (C i C ++ są tego pełne), warunki wyścigu, potencjalne zmiany kolejności z powodu słabego modelu pamięci ... - CodesInChaos 7 godzin temu
@CodesInChaos, jeśli nie można go odtworzyć, nie można przetestować kodu napisanego w „fix”. A moim zdaniem wprowadzenie nie przetestowanego kodu jest gorszym przestępstwem - RhysW 5 godzin temu
... zastanawia mnie, czy istnieją jakieś dobre ogólne sposoby konsekwentnego uruchamiania bardzo rzadko występujących problemów produkcyjnych spowodowanych warunkami wyścigowymi w przypadku testowym.
testing
multithreading
Dan Neely
źródło
źródło
Odpowiedzi:
Po tym, jak działałem w tym szalonym biznesie od około 1978 r., Spędziłem prawie cały ten czas na wbudowanych komputerach w czasie rzeczywistym, pracując w wielozadaniowości, wielowątkowych, wielorakich systemach, czasem z wieloma procesorami fizycznymi, ścigając więcej niż moją uczciwą część rasy Warunki, uważam, że odpowiedź na twoje pytanie jest dość prosta.
Nie.
Nie ma dobrego ogólnego sposobu na wywołanie warunków wyścigu w testach.
Waszą jedyną nadzieją jest zaprojektowanie ich całkowicie poza systemem.
Kiedy i jeśli okaże się, że ktoś go włożył, powinieneś postawić mu mrowisko, a następnie przeprojektować, aby go wyeliminować. Po zaprojektowaniu jego faux pas (wymawiane f *** up) ze swojego systemu, możesz uwolnić go od mrówek. (Jeśli mrówki już go pochłonęły, pozostawiając tylko kości, postaw znak: „To dzieje się z ludźmi, którzy stawiają warunki rasowe w projekcie XYZ!” I ZOSTAWIĄ GO TAM).
źródło
Jeśli jesteś w łańcuchu narzędzi MS. Ms Research stworzyło narzędzie, które wymusi nowe przeszkody dla każdego przebiegu i może odtworzyć nieudane przebiegi, zwane szachami .
tutaj jest wideo pokazujące to w użyciu.
źródło
Najlepszym narzędziem znanym z tego rodzaju problemów jest rozszerzenie Valgrind o nazwie Helgrind .
Zasadniczo Valgrind symuluje procesor wirtualny i uruchamia na nim Twój plik binarny (niezmodyfikowany), dzięki czemu może sprawdzać każdy dostęp do pamięci. Korzystając z tej struktury, system monitorowania Helgrind wywołuje wnioski, gdy dostęp do zmiennej dzielonej nie jest odpowiednio chroniony przez mechanizm wzajemnego wykluczania. W ten sposób może wykryć teoretyczny warunek wyścigu, nawet jeśli tak się nie stało.
Intel sprzedaje bardzo podobne narzędzie o nazwie Intel Inspector .
Narzędzia te dają świetne wyniki, ale Twój program będzie znacznie wolniejszy podczas analizy.
źródło
Ujawnienie błędu wielowątkowości wymaga zmuszenia różnych wątków wykonania do wykonania ich kroków w określonej kolejności z przeplotem. Zwykle jest to trudne bez ręcznego debugowania lub manipulowania kodem w celu uzyskania jakiegoś „uchwytu” kontrolującego to przeplatanie. Ale zmiana kodu, który zachowuje się nieprzewidywalnie, często wpłynie na tę nieprzewidywalność, więc trudno to zautomatyzować.
Niezłą sztuczkę opisuje Jaroslav Tulach w praktycznym projekcie interfejsu API : jeśli masz instrukcje rejestrowania w omawianym kodzie, manipuluj konsumentem tych instrukcji rejestrowania (np. Wstrzykiwany pseudo-terminal), aby akceptował poszczególne komunikaty dziennika w określonym kolejność na podstawie ich zawartości. Pozwala to kontrolować przeplatanie kroków w różnych wątkach bez konieczności dodawania czegokolwiek do kodu produkcyjnego, którego jeszcze nie ma.
źródło
Nie ma absolutnej pewności, że różne rodzaje nieokreślonych zachowań (w szczególności warunki wyścigowe) nie istnieją.
Istnieje jednak szereg narzędzi, które pokazują dużą liczbę takich sytuacji. Być może możesz udowodnić, że istnieje problem z takimi narzędziami, nawet jeśli nie możesz udowodnić, że poprawka jest poprawna.
Kilka interesujących narzędzi do tego celu:
Valgrind to narzędzie do sprawdzania pamięci. Znajduje wycieki pamięci, odczytuje niezainicjowaną pamięć, wykorzystuje zwisające wskaźniki i dostęp poza granicami.
Helgrind to narzędzie do sprawdzania bezpieczeństwa wątków. Znajduje warunki wyścigu.
Oba działają za pomocą dynamicznej instrumentacji, tzn. Biorą twój program w niezmienionej postaci i uruchamiają go w zwirtualizowanym środowisku. To sprawia, że są nieinwazyjne, ale powolne.
UBSan to niezdefiniowany moduł sprawdzania zachowania. Znajduje różne przypadki nieokreślonego zachowania C i C ++, takie jak przepełnienie liczb całkowitych, przesunięcia poza zasięgiem i podobne rzeczy.
MSan to kontroler pamięci. Ma podobne cele jak Valgrind.
TSan to narzędzie do sprawdzania bezpieczeństwa wątków. Ma podobne cele jak Helgrind.
Te trzy są wbudowane w kompilator Clanga i generują kod w czasie kompilacji. Oznacza to, że musisz zintegrować je z procesem kompilacji (w szczególności musisz skompilować z Clangiem), co znacznie utrudnia ich początkową konfigurację niż * grind, ale z drugiej strony mają znacznie niższy czas działania.
Wszystkie wymienione przeze mnie narzędzia działają w systemie Linux, a niektóre w systemie MacOS. Nie sądzę, aby jakakolwiek praca w systemie Windows była jeszcze niezawodna.
źródło
Wydaje się, że większość odpowiedzi tutaj myli to pytanie jako „jak automatycznie wykryć warunki wyścigu?” kiedy pytanie brzmi „jak odtworzyć warunki wyścigu podczas testów, gdy je znajdę?”
Można to zrobić, wprowadzając synchronizację w kodzie używanym wyłącznie do testowania. Na przykład, jeśli wyścig wystąpi, gdy zdarzenie X nastąpi między zdarzeniem A a zdarzeniem B, wówczas w celu przetestowania aplikacji napisz kod, który czeka na zdarzenie X po zdarzeniu A. Prawdopodobnie będziesz potrzebować sposobu, aby testy porozmawiały z Twoją aplikacją, aby to powiedzieć („hej, testuję to, więc poczekaj na to wydarzenie w tej lokalizacji”).
Używam node.js i mongo, gdzie niektóre działania wymagają tworzenia spójnych danych w wielu kolekcjach. W takich przypadkach moje testy jednostkowe wywołają aplikację, aby powiedzieć jej „skonfiguruj oczekiwanie na zdarzenie X”, a po skonfigurowaniu aplikacji zostanie uruchomiony test dla zdarzenia X, a następnie testy pokażą aplikacja („skończyłem z oczekiwaniem na zdarzenie X”), więc pozostałe testy będą działać normalnie.
Odpowiedź tutaj wyjaśnia szczegółowo tego rodzaju rzeczy w kontekście pythona: https://stackoverflow.com/questions/19602535/how-can-i-reprrive-the-race-conditions-in-this-python-code- niezawodnie
źródło