Czy uzasadnione jest naleganie na odtworzenie każdej usterki przed jej zdiagnozowaniem i naprawieniem?

70

Pracuję dla firmy produkującej oprogramowanie. Mamy dużych klientów korporacyjnych, którzy wdrażają nasz produkt i zapewniamy im wsparcie. Na przykład, jeśli występuje wada, zapewniamy łatki itp. Innymi słowy, jest to dość typowa konfiguracja.

Niedawno wydano i przypisano mi bilet dotyczący wyjątku znalezionego przez klienta w pliku dziennika, który ma związek z równoczesnym dostępem do bazy danych w klastrowej implementacji naszego produktu. Tak więc konkretna konfiguracja tego klienta może mieć kluczowe znaczenie w przypadku wystąpienia tego błędu. Od klienta dostaliśmy tylko plik dziennika.

Podejście, które zaproponowałem mojemu zespołowi, polegało na próbie odtworzenia błędu w konfiguracji podobnej do konfiguracji klienta i uzyskania porównywalnego dziennika. Nie zgadzają się jednak z moim podejściem, mówiącym, że nie muszę odtwarzać błędu, ponieważ jest to zbyt czasochłonne i będzie wymagało symulacji klastra serwerów na maszynach wirtualnych. Mój zespół sugeruje, że po prostu „podążam za kodem”, aby zobaczyć, gdzie znajduje się kod niebezpieczny dla wątków i / lub transakcji, i wprowadzam zmiany w wyniku prostego rozwoju lokalnego, który nie jest implementacją klastra, taką jak środowisko, z którego wystąpienie błąd pochodzi.

Dla mnie opracowanie abstrakcyjnego planu (kodu programu) zamiast namacalnej, widocznej manifestacji (odtwarzanie w czasie wykonywania) wydaje się trudne, dlatego chciałem zadać ogólne pytanie:

Czy uzasadnione jest naleganie na odtworzenie każdej usterki i debugowanie jej przed zdiagnozowaniem i naprawieniem?

Lub:

Jeśli jestem starszym programistą, czy powinienem być w stanie odczytać kod wielowątkowy i stworzyć w pamięci obraz tego, co robi we wszystkich scenariuszach przypadków użycia, zamiast wymagać uruchamiania aplikacji, testowania różnych scenariuszy przypadków użycia i przejścia przez kod po linii? A może jestem kiepskim deweloperem wymagającym tego rodzaju środowiska pracy?

Czy debugowanie dla maminsynek?

Moim zdaniem każda poprawka przesłana w odpowiedzi na zgłoszenie zdarzenia powinna zostać przetestowana w środowisku symulowanym tak, aby znajdowała się jak najbliżej pierwotnego środowiska. Skąd jeszcze możesz wiedzieć, że to naprawi problem? To jak wypuszczenie nowego modelu pojazdu bez testowania zderzeniowego z manekinem, aby wykazać, że poduszki powietrzne rzeczywiście działają.

Wreszcie, jeśli się ze mną zgadzasz:

Jak mam porozmawiać z moim zespołem, aby przekonać ich, że moje podejście jest rozsądne, konserwatywne i bardziej kuloodporne?

amfibia
źródło
7
czasami nie ma sensu nalegać na odtwarzanie, gdy masz dziennik ze śledzeniem stosu. Niektóre błędy współbieżności w Javie są właśnie takie, w rzeczywistości najłatwiejsze, gdy otrzymujesz dziennik z NPE i śledzenie stosu wskazujące na linię, która „najwyraźniej” używa obiektu utworzonego za pomocą new. I te błędy nie są gwarantowane w sposób niezawodny, zgodnie ze specyfikacją Java Memory Model
gnat
5
Czy chcesz uzyskać „poprawną” odpowiedź - musisz odtworzyć każdy błąd, abyś wiedział, że jest naprawiony, lub odpowiedź „utrzymuj, że klient płaci nam $$” - czasami nie masz czasu i zasobów, aby to zrobić, i Twój szef oczekuje, że wykorzystasz swoją wiedzę specjalistyczną, aby mimo wszystko spróbować go naprawić?
KutuluMike,
20
Zaskoczony, że społeczność tutaj jest z tobą zgodna. Szczerze mówiąc, całkowicie zgadzam się z twoimi kolegami z drużyny. Czasami, szczególnie jeśli chodzi o błędy w warunkach wyścigowych, ma to o wiele większy sens i jest o wiele bardziej efektywne po prostu podążanie za kodem niż poświęcanie dużej ilości czasu na stworzenie środowiska testowego, które może nawet nie ujawnić problemu . Jeśli nie możesz znaleźć niczego przez śledzenie kodu, upewnij się, czy sensowne jest poświęcenie wysiłku na stworzenie środowiska testowego, ale rozpoczęcie tworzenia środowiska testowego jest złe .
Ben Lee
5
Nie możesz udowodnić, że rozwiązałeś problem, nie będąc w stanie go odtworzyć. Czasami sensowne może być odgadnięcie ograniczeń zasobów, ale chciałbym, aby był to wyjątek, a nie reguła. Chociaż, jeśli naprawdę tak trudno jest odtworzyć problemy, być może istnieje coś innego, na przykład projekt lub architektura.
dietbuddha

Odpowiedzi:

72

Czy uzasadnione jest naleganie na odtworzenie każdej usterki i debugowanie jej przed zdiagnozowaniem i naprawieniem?

Powinieneś dać z siebie wszystko. Wiem, że czasami istnieją warunki i środowiska, które są tak złożone, że nie można ich dokładnie odtworzyć , ale na pewno powinieneś spróbować, jeśli możesz.

Jeśli nigdy nie odtworzyłeś błędu i nie widziałeś go sam, jak możesz być w 100% pewien, że naprawiłeś go? Być może proponowana poprawka wprowadza jakiś inny subtelny błąd, który nie pojawi się, chyba że spróbujesz odtworzyć oryginalną wadę.

Jeśli jestem starszym programistą, czy powinienem być w stanie odczytać (wielowątkowy) kod i stworzyć mentalny obraz tego, co robi we wszystkich scenariuszach przypadków użycia zamiast wymagać uruchamiania aplikacji, przetestować różne scenariusze przypadków użycia i przejść krok po kroku kod wiersz po wierszu? A może jestem kiepskim deweloperem wymagającym tego rodzaju środowiska pracy? Czy debugowanie dla maminsynek?

Nie ufałbym komuś, kto uruchamia kod „w głowie”, jeśli to jest ich jedyne podejście. To dobre miejsce na początek . Odtworzenie błędu, naprawienie go, a następnie wykazanie, że rozwiązanie zapobiega ponownemu pojawieniu się błędu - w tym miejscu powinno się zakończyć .

Jak mam porozmawiać z moim zespołem, aby przekonać ich, że moje podejście jest rozsądne, konserwatywne i bardziej kuloodporne?

Ponieważ jeśli nigdy nie odtworzyli błędu, nie mogą wiedzieć na pewno, że został on naprawiony. A jeśli klient wróci i narzeka, że ​​błąd nadal występuje, to nie jest dobra rzecz. W końcu płacą ci duże $$$ (zakładam) za rozwiązanie tego problemu.

Jeśli nie uda się prawidłowo rozwiązać problemu, doszło do zerwania z klientem (do pewnego stopnia), a jeśli na rynku istnieją konkurenci, mogą oni nie pozostać twoim klientem.

FrustratedWithFormsDesigner
źródło
3
„Odtworzenie błędu, naprawienie go, a następnie wykazanie, że rozwiązanie zapobiega ponownemu pojawieniu się błędu - w tym miejscu powinno się zakończyć”. - dokładnie o to mi chodzi
amfibia
2
„Ponieważ jeśli nigdy nie odtworzyli błędu, nie mogą mieć pewności, że został on naprawiony”. Amen ...
Marjan Venema,
11
Chciałbym również dodać do tej odpowiedzi, ponieważ ponieważ nie masz takiej konfiguracji, Twoja firma powinna dowiedzieć się, czy jest to nawet obsługiwana konfiguracja. Jeśli Twoja firma zamierza formalnie wspierać takie konfiguracje, naprawdę powinieneś mieć podobnie skonfigurowane środowisko, aby wykonywać swoją pracę w zakresie kontroli jakości. To z pewnością zwiększy koszty i dlatego firma powinna zdecydować, jakie konfiguracje swojego produktu będzie obsługiwać.
Andy,
W tym miejscu powinien istnieć argument kosztów / korzyści. Jeśli rozmnażanie zajmie tygodnie, wartość reprodukcji jest prawdopodobnie niska z powodu braku rozwiązania innych problemów. Jeśli odtworzenie zajmuje kilka sekund, wartość reprodukcji jest prawdopodobnie wysoka, ze względu na pewność poprawki. Decyzja powinna próbować to zrównoważyć, ogólne stwierdzenie „powinien” lub „nie powinien” jest bezcelowe.
orip
1
@orip: Analiza kosztów / korzyści musi również uwzględniać klienta: Czy koszt zignorowania klienta wiąże się z możliwym ryzykiem utraty konta (i ewentualnie utraty innych klientów z powodu tego, co słyszą od tego oryginalnego klienta, lub jeśli masz również błąd, ale jeszcze go oficjalnie nie zgłosiłem) przeważają koszty czasu programisty poświęconego na odtworzenie i naprawienie błędu?
FrustratedWithFormsDesigner
35

Jak zamierzają sprawdzić, czy dany błąd został naprawiony? Czy chcą wysłać nie przetestowany kod do użytkownika i pozwolić mu go rozgryźć? Nie można polegać na żadnej konfiguracji testowej, która nigdy nie pokazywała błędu w celu odtworzenia błędu. Z pewnością nie musisz odtwarzać całego środowiska klienta, ale potrzebujesz wystarczająco dużo, aby odtworzyć błąd.

Nie sądzę, aby próba odtworzenia każdego błędu przed naprawą była nierozsądna. Jeśli jednak spróbujesz go odtworzyć i nie będziesz w stanie tego zrobić, stanie się bardziej decyzją biznesową dotyczącą tego, czy ślepe łaty są dobrym pomysłem.

kamieniste
źródło
2
Zgadzam się, jednak jeśli błąd zostanie wykryty w wyniku przeglądu, może dostarczyć krytycznych informacji niezbędnych do jego odtworzenia. Następnie możesz go odtworzyć i udowodnić, że poprawka jest poprawna ...
mattnz,
3
Jeśli jesteś w stanie znaleźć wielowątkowy warunek wyścigu poprzez kontrolę kodu, powinieneś być w stanie konsekwentnie go odtworzyć, modyfikując kod za pomocą dodatkowych instrukcji blokujących, które zmuszają wątki do uruchomienia / zatrzymania w sekwencji, która go wyzwala. ex Thread1-Uruchomienie i pauza, Thread2-Uruchomienie i pauza, 1-rozpoczęcie za pomocą współdzielonego obiektu i pauza, 2-modyfikacja współdzielonego obiektu i pauza, 1-próba za pomocą współdzielonego obiektu i barf. Największym problemem związanym z tego rodzaju podejściem jest to, że chociaż jest to coś, co można zademonstrować w debuggerze, nie nadaje się do dodawania do zautomatyzowanego zestawu testów. BTDT-GTTS.
Dan Neely,
2
@DanNeely: Jeśli jeden wątek zapisuje wartość do tablicy, a następnie przechowuje odwołanie w polu, a inny wątek czyta to pole i uzyskuje dostęp do odpowiedniego elementu tablicy, w jaki sposób można odtworzyć błędy, które mogą wystąpić, jeśli JIT przeniesie referencję zapisu operacja przed elementem zapisu?
supercat
27

Najlepiej, jeśli chcesz móc odtworzyć każdy błąd, aby przynajmniej przetestować, czy został naprawiony.

Ale ... To nie zawsze może być wykonalne, a nawet fizycznie możliwe. Zwłaszcza z oprogramowaniem typu „Enterprise”, w którym każda instalacja jest unikalna. Istnieje również ocena kosztów / korzyści. Kilka godzin na zapoznanie się z kodem i kilka wyuczonych domysłów na temat niekrytycznego problemu może kosztować znacznie mniej niż fakt, że zespół pomocy technicznej spędził tygodnie próbując skonfigurować i zduplikować środowisko klienta dokładnie w nadziei, że będzie w stanie powielić problem. Kiedy pracowałem w świecie „Enterprise”, często po prostu wyrzucaliśmy programistów i naprawiali błędy na miejscu, ponieważ nie było sposobu, aby powielić konfigurację klienta.

Powielaj, kiedy możesz, ale jeśli nie możesz, wykorzystaj swoją wiedzę o systemie i spróbuj zidentyfikować winowajcę w kodzie.

Grandmaster B.
źródło
11

Nie sądzę, że powinieneś powielać błąd jako warunek spojrzenia na błąd. Jak już wspomniałeś, istnieje kilka sposobów debugowania problemu - i powinieneś użyć ich wszystkich. Powinieneś liczyć, że masz szczęście, że udało ci się dostarczyć plik dziennika! Jeśli Ty lub ktoś z Twojej firmy jest w stanie odtworzyć błąd, to świetnie! Jeśli nie, nadal powinieneś spróbować przeanalizować dzienniki i znaleźć okoliczności, w których wystąpił błąd. Jak sugerowali koledzy, może być możliwe przeczytanie kodu, ustalenie warunków, w których może wystąpić błąd, a następnie próba samodzielnego odtworzenia scenariusza.

Nie wypuszczaj jednak prawdziwej poprawki niesprawdzonej. Wszelkie zmiany, które wprowadzisz, powinny przejść standardowe procedury testowania deweloperów, kontroli jakości i testów integracji. Testowanie może okazać się trudne - wspomniałeś o kodzie wielowątkowym, który jest bardzo trudny do debugowania. W tym miejscu zgadzam się z twoim podejściem do tworzenia konfiguracji testowej lub środowiska. Jeśli znalazłeś problem w kodzie, tworzenie środowiska, odtworzenie problemu i przetestowanie poprawki powinno być znacznie prostsze.

Dla mnie jest to mniej problem z debugowaniem, a bardziej problem obsługi klienta. Otrzymałeś raport o błędzie od klienta; masz obowiązek dołożyć należytej staranności, aby znaleźć ich problem i go naprawić.

Michael K.
źródło
5
„Jednak nie wypuszczaj prawdziwej poprawki niesprawdzonej.” Jak? Jeśli nie jest w stanie odtworzyć warunków, które spowodowały błąd, w jaki sposób je odtworzy w celu przetestowania poprawki? Nie przypuszczam też, że OP nie dołożył wszelkich starań.
Tulains Córdova
„Jeśli znalazłeś problem w kodzie, tworzenie środowiska, odtworzenie problemu i przetestowanie poprawki powinno być o wiele prostsze”. Przeczytałem pytanie OP: „Czy powinienem wymagać, aby wszystkie zgłoszenia błędów zawierały przypadek repro, zanim spróbuję zdiagnozować problem?” Nie powinieneś.
Michael K,
Spodziewałbym się, że większość testów to testy regresji istniejących funkcji.
Michael Durrant
4
@MichaelK: Twoja odpowiedź wydaje się być sprzeczna z samym sobą. Jeśli nie określisz, jakie kroki należy wykonać, aby odtworzyć błąd, skąd będziesz wiedzieć, jakie powinny być twoje przypadki testowe? Nie zawsze możesz potrzebować samodzielnie odtworzyć błędy, ale większość z tych przypadków ma miejsce, gdy kroki związane z odtwarzaniem są już znane. Jeśli masz tylko plik dziennika bez znanych kroków, nie masz żadnych przypadków testowych do kontroli jakości.
Ellesedil
8
Myślę, że on mówi, że niekoniecznie musisz odtworzyć problem, aby zbadać jego rozwiązanie. Zakładając, że wyśledzisz to i znajdziesz poprawkę, będziesz wiedział, jakie warunki należy skonfigurować na serwerze testowym do odtwarzania. W tym momencie będziesz nawet wiedział, jak skonfigurować poprzedni kod - skonfiguruj go, sprawdź, czy jest odtwarzalny, wdróż poprawkę, sprawdź, czy została naprawiona.
GalacticCowboy
9

Moim zdaniem ... jako decydent, musisz być w stanie uzasadnić swoje stanowisko. Jeśli celem działu wsparcia trzeciej linii jest usunięcie błędów w jak najkrótszym czasie przy akceptowalnym wysiłku klienta, wówczas każde podejście musi być zgodne z tym celem. Co więcej, jeśli można udowodnić, że takie podejście daje najszybsze oczekiwane wyniki, nie powinno być problemu z przekonaniem zespołu.

Pracując przy wsparciu, zawsze słusznie spodziewałem się, że klient będzie w stanie podać „skrypt” działań, które wykonali w celu konsekwentnego odtworzenia błędu, a jeśli nie konsekwentnie, to kandydatów na przykłady, które go spowodowały.

Gdybym był nowy w systemie i nie miał żadnego tła z kodem, moje pierwsze kroki to próba zidentyfikowania możliwych źródeł błędu. Być może rejestrowanie jest niewystarczające do zidentyfikowania kodu kandydata. W zależności od klienta, mogę być skłonny dać im wersję debugowania, aby mogli dać ci z powrotem pliki dziennika, które dostarczają dalszych wskazówek co do pozycji szkodliwego kodu.

Jeśli jestem w stanie szybko zidentyfikować blok kodu, wizualne odwzorowanie przepływu może wystarczyć do wykrycia kodu. Jeśli nie, może wystarczyć symulacja oparta na testach jednostkowych. Może się zdarzyć, że skonfigurowanie środowiska replikacji klienta zajmie mniej czasu, zwłaszcza jeśli problem jest bardzo duży.

Myślę, że może się okazać, że twoje podejście powinno być kombinacją proponowanych rozwiązań i że wiedza o tym, kiedy wyjść z jednego i przejść do następnego, jest kluczem do skutecznego wykonania pracy.

Jestem pewien, że zespół poprze pogląd, że jeśli istnieje szansa, że ​​jego rozwiązanie szybciej wykryje błąd, to dadzą mu odpowiedni czas na udowodnienie, że nie wpłynie to zbytnio na czas potrzebny do usunięcia błędu trasa, którą wybierasz.

stevemarvell
źródło
8

Czy uzasadnione jest naleganie na odtworzenie każdej usterki i debugowanie jej przed zdiagnozowaniem i naprawieniem?

Mówię tak, z pewnymi zastrzeżeniami.

  • Myślę, że dobrze jest przeczytać kod i spróbować znaleźć miejsca, które wyglądają na problematyczne. Utwórz poprawkę i wyślij ją do klienta, aby sprawdzić, czy to rozwiąże problem. Jeśli to podejście nadal nie powiedzie się, może być konieczne sprawdzenie innych opcji. Wystarczy pamiętać, że choć może być zajęcie się błąd, to nie może być błąd, który został zgłoszony.
  • Jeśli nie możesz go odtworzyć w rozsądnym zakresie i nie możesz znaleźć żadnych czerwonych flag w kodzie, może to wymagać ściślejszej koordynacji z klientem. Wyleciałem do stron klientów przed debugowaniem na stronie. Nie jest to najlepsze środowisko programistyczne, ale czasami jeśli problem dotyczy środowiska, wówczas znalezienie dokładnej przyczyny będzie najłatwiejsze, gdy będziesz w stanie konsekwentnie go odtworzyć.

W tym scenariuszu byłem po stronie klienta. Pracowałem w amerykańskim biurze rządowym, który korzystał z niewiarygodnie dużego klastra bazy danych Oracle (kilka terabajtów danych i przetwarzając miliony rekordów dziennie).

Napotkaliśmy dziwny problem, który bardzo łatwo było nam odtworzyć. Zgłosiliśmy błąd do Oracle i przez kilka tygodni jeździliśmy tam iz powrotem, wysyłając im logi. Powiedzieli, że nie byli w stanie odtworzyć problemu, ale przesłali nam kilka poprawek, które mogą rozwiązać problem. Żadne z nich tego nie zrobiło.

W końcu polecili do naszej lokalizacji kilku programistów, aby rozwiązać problem na miejscu. I wtedy znaleziono podstawową przyczynę błędu, a późniejsza łata poprawnie rozwiązała problem.

M. Scott Ford
źródło
6

Jeśli nie jesteś pozytywny na temat problemu, nie możesz być pozytywny na temat rozwiązania. Umiejętność niezawodnego odtworzenia problemu w co najmniej jednej sytuacji testowej pozwala udowodnić, że wiesz, jak spowodować błąd, a zatem pozwala również udowodnić, że problem został rozwiązany, z powodu późniejszego braku błędu w tym samym przypadku testowym po zastosowaniu poprawki.

To powiedziawszy, warunki wyścigu, problemy z współbieżnością i inne błędy „niedeterministyczne” należą do najtrudniejszych do określenia przez programistę w ten sposób, ponieważ występują one rzadko w systemie o większym obciążeniu i większej złożoności niż jakakolwiek kopia programu program i znikają, gdy zadanie zostanie ponownie uruchomione w tym samym systemie w późniejszym czasie.

Częściej niż nie, to, co pierwotnie wygląda na przypadkowy błąd, ostatecznie ma deterministyczną przyczynę, która powoduje, że błąd jest deterministycznie odtwarzalny, gdy wiesz, jak to zrobić. Ci, którzy się temu sprzeciwiają, prawdziwe błędy Heisenbugs (pozornie przypadkowe błędy, które znikają podczas próby przetestowania ich w sterylnym, monitorowanym środowisku), mają 99,9% czasu i po zrozumieniu tego, twoja droga staje się bardziej wyraźna; skanuj w poszukiwaniu rzeczy, które mogą się nie powieść, jeśli podczas wykonywania kodu coś innego nie wejdzie w błąd, a kiedy znajdziesz taką lukę, spróbuj wykorzystać ją w teście, aby sprawdzić, czy wykazuje zachowanie, które próbujesz odtworzyć.

W takich sytuacjach zwykle wymagana jest znaczna ilość szczegółowej kontroli kodu; musisz spojrzeć na kod, porzucając wszelkie z góry przyjęte wyobrażenia o tym, jak kod ma się zachowywać, i wyobrazić sobie scenariusze, w których może on zawieść w sposób, w jaki obserwował go twój klient. Dla każdego scenariusza spróbuj opracować test, który mógłby zostać skutecznie uruchomiony w bieżącym zautomatyzowanym środowisku testowym (tj. Bez potrzeby stosowania nowego stosu maszyny wirtualnej tylko do tego jednego testu), który potwierdziłby lub obaliłby, że kod zachowuje się zgodnie z oczekiwaniami ( które, w zależności od oczekiwań, udowodnią lub obalą, że ten kod jest możliwą przyczyną problemów klientów). Jest to metoda naukowa dla inżynierów oprogramowania; obserwuj, hipotezuj, testuj, zastanawiaj się, powtarzaj.

KeithS
źródło
4

Czy uzasadnione jest naleganie na odtworzenie każdej usterki i debugowanie jej przed zdiagnozowaniem i naprawieniem?

Nie, to zdecydowanie nie jest. To byłaby głupia polityka.

Problem, który widzę w twoim pytaniu i twojej propozycji, polega na tym, że nie dokonują rozróżnienia

  • zgłaszanie błędów
  • awarie ( błędy )
  • błędy (zwane także czasami błędami )

Raport o błędzie jest komunikacja na temat błędu. Mówi ci, że ktoś myśli, że coś jest nie tak. Może być, ale nie musi, konkretny, co powinno być złe.

Raport o błędzie jest dowodem niepowodzenia.

Awaria jest incydent coś idzie źle. Konkretna awaria, ale niekoniecznie żadna wskazówka, co mogło ją spowodować.

Błąd może być spowodowany błędem.

Bug jest przyczyną niepowodzeń; coś, co można (co do zasady) zmienić, aby zapobiec powstającym awariom w przyszłości.

Czasami po zgłoszeniu błędu przyczyna jest natychmiastowa. W takim przypadku odtworzenie błędu byłoby nonsensowne. Innym razem przyczyna nie jest wcale jasna: raport o błędzie nie opisuje żadnej konkretnej awarii lub tak się dzieje, ale awaria jest taka, że ​​nie daje wskazówek co do przyczyny. W takich przypadkach uważam, że twoja rada jest uzasadniona - ale nie zawsze: nikt nie nalega na rozbicie drugiej rakiety kosmicznej o wartości 370 milionów dolarów, zanim zgodzi się zbadać, co spowodowało awarię pierwszej (szczególny błąd w oprogramowaniu sterującym).

Istnieją też różnego rodzaju przypadki pośrednie; na przykład, jeśli raport o błędzie nie dowodzi, a jedynie sugeruje, że potencjalny problem, o którym już wiedziałeś, może odegrać pewną rolę, może to być wystarczająca zachęta, aby przyjrzeć się mu bliżej.

Tak więc, choć naleganie na powtarzalność jest rozsądne w trudniejszych przypadkach, nierozsądne jest egzekwowanie go jako surowej polityki.

reinierpost
źródło
4
Jeśli odtworzenie błędu nie jest rozsądne, skąd wiesz, że naprawiłeś błąd? Niezależnie od tego, jak skomplikowany jest sposób odtworzenia błędu.
BЈовић
Wiesz, że naprawiłeś błąd, gdy tak łatwo go odtworzyć, że nie musisz.
reinierpost
Celem nie jest naprawianie błędów, celem jest mieć dobry produkt. Dokonujesz zmiany kodu, która poprawia kod, i Twoim zdaniem, i opinia recenzenta, może naprawić błąd. Następnie produkt zostanie ponownie przetestowany. Prawdopodobnie przez mimowolnych testerów, czyli użytkowników końcowych.
gnasher729,
Zgadzam się, że ponowne testowanie musi być zawsze wykonywane, gdy jest to możliwe, ale to nie ma sensu. Pytanie brzmi, czy uzasadnione jest, aby zawsze nalegać, aby problem był powtarzalny.
reinierpost
3

Podobnie jak w przypadku wszystkich innych elementów związanych z tworzeniem oprogramowania, prawidłowa odpowiedź to kompromis.

Teoretycznie nigdy nie powinieneś próbować naprawiać błędu, jeśli nie możesz udowodnić, że istnieje. Może to spowodować niepotrzebne zmiany w kodzie, które ostatecznie niczego nie rozwiążą. Udowodnienie tego oznacza najpierw jego odtworzenie, a następnie utworzenie i zastosowanie poprawki, a następnie wykazanie, że to się już nie zdarza. Twoja odwaga prowadzi cię w dobrym kierunku - jeśli chcesz mieć pewność, że rozwiązałeś problem swojego klienta, musisz przede wszystkim wiedzieć, co go spowodowało.

W praktyce nie zawsze jest to możliwe. Być może błąd występuje tylko w dużych klastrach z dziesiątkami użytkowników jednocześnie uzyskujących dostęp do Twojego kodu. Być może istnieje określona kombinacja operacji na danych na określonych zestawach danych, która powoduje błąd i nie masz pojęcia, co to jest. Być może Twój klient uruchomił program interaktywnie non-stop przez 100 godzin przed pojawieniem się błędu.

W każdym z tych przypadków istnieje duża szansa, że ​​Twój dział nie będzie miał czasu ani pieniędzy na odtworzenie błędu przed rozpoczęciem pracy. W wielu przypadkach o wiele bardziej oczywiste dla ciebie, programisty, jest błąd w kodzie, który wskazuje prawidłową sytuację. Po zdiagnozowaniu problemu możesz wrócić i odtworzyć go. Nie jest to idealne, ale jednocześnie częścią pracy jako starszego programisty jest umiejętność czytania i interpretowania kodu, częściowo w celu zlokalizowania tego rodzaju ukrytych błędów.

Moim zdaniem koncentrujesz się na niewłaściwej części pytania. Co zrobić, jeśli ostatecznie nie możesz odtworzyć tego błędu? Nic nie jest bardziej frustrujące dla klienta niż usłyszenie „tak, wiemy, że zawiesiłeś program, ale nie możemy go odtworzyć, więc nie jest to błąd”. Kiedy twój klient to słyszy, interpretuje to jako „wiemy, że nasze oprogramowanie jest wadliwe, ale nie możemy zadać sobie trudu, aby naprawić i naprawić błędy, więc po prostu trzymajcie kciuki”. Czy lepiej zamknąć zgłaszany błąd jako „nie do odtworzenia”, czy też zamknąć go jako „nie do odtworzenia, ale wprowadziliśmy kilka rozsądnych zmian w celu poprawy stabilności”?

KutuluMike
źródło
3

O ile błąd nie jest oczywisty, oczywisty i trywialny, z bardzo konkretnym komunikatem o błędzie itp., Często bardzo trudno jest naprawić błąd, jeśli użytkownik lub opiekun nie jest w stanie go odtworzyć.

W jaki sposób udowodnisz im, że błąd został naprawiony, jeśli nie możesz powtórzyć kroków?

Problem z twoją sprawą polega na tym, że użytkownik nie wie, jak wystąpił błąd, to znaczy na jakim ekranie wykonywania jakiej operacji. Po prostu mają dziennik.

Myślę, że twój punkt widzenia jest rozsądny. Gdybyś miał moce psychiczne , prawdopodobnie nie pracowałbyś za pensję.

Myślę, że powinieneś powiedzieć swoim szefom, że bez możliwości odtworzenia błędu zajęłoby to niezbyt dużo czasu, aby go znaleźć, i nie ma żadnej gwarancji, że to zrobisz.

Problem pojawi się, gdy któryś z twoich współpracowników znajdzie błąd nieszczęścia i naprawi go.

Tulains Córdova
źródło
3

Przejdźmy do skrajności i załóżmy, że błąd został znaleziony znacznie wcześniej: w kodzie, tak jak go pisałeś. Wtedy nie miałbyś żadnych skrupułów, aby naprawić to tutaj - widzisz logiczną wadę w właśnie napisanym kodzie, nie robi tego, co chciałeś. Nie czułbyś potrzeby konfigurowania całego środowiska, aby pokazać, że to w rzeczywistości błąd.

Teraz pojawia się raport o błędzie. Możesz zrobić kilka rzeczy. Jednym z nich jest powrót do kodu i ponowne przeczytanie go. Załóżmy teraz, że w drugim czytaniu od razu znajdziesz błąd w kodzie - po prostu nie robi tego, co zamierzałeś, i nie zauważyłeś, kiedy go napisałeś. I doskonale wyjaśnia błąd, który właśnie się pojawił! Naprawiasz. Zajęło ci to dwadzieścia minut.

Czy to naprawiło błąd, który spowodował zgłoszenie błędu? Nie możesz być w 100% pewien (mogły być dwa błędy powodujące to samo), ale prawdopodobnie tak było.

Inną rzeczą, którą możesz zrobić, to odtworzyć konfigurację klienta tak dobrze, jak możesz (kilka dni pracy), i ostatecznie odtworzyć błąd. W wielu przypadkach występują problemy z synchronizacją i współbieżnością, co oznacza, że ​​nie można odtworzyć błędu, ale można próbować dużo czasu i czasem zobaczyć, jak to się dzieje. Teraz zaczynasz debugować, znajdujesz błąd w kodzie, umieszczasz go w środowisku i próbujesz wiele razy ponownie. Nie widać już występującego błędu.

Czy to naprawiło błąd, który spowodował zgłoszenie błędu? Nadal nie możesz być w 100% pewien - po pierwsze, być może widziałeś zupełnie inny błąd niż klient, dwa, może nie próbowałeś wystarczająco często, a trzy, może konfiguracja jest nieco inna i jest naprawione w tym systemie, ale nie w systemie klienta.

W każdym razie nie można uzyskać pewności. Ale pierwsza metoda jest o wiele szybsza (możesz też szybciej dać klientowi łatkę), jest o wiele tańsza, a jeśli znajdziesz wyraźny błąd w kodzie, który wyjaśnia ten objaw, jest bardziej prawdopodobne, że również znajdzie problem.

Więc to zależy. Jeśli skonfigurowanie środowiska testowego jest tanie (lub lepiej: automatyczny test pokazujący problem), zrób to. Ale jeśli jest to kosztowne i / lub okoliczności, w których pokazywanie błędów jest nieprzewidywalne, zawsze lepiej jest spróbować znaleźć błąd, najpierw czytając kod.

RemcoGerlich
źródło
zakładasz, że kod był mój od samego początku?
amfibia
Z mojego doświadczenia wynika, że ​​raporty o błędach często kończą się facetem, który napisał kod, ale to nie jest ważne dla mojej odpowiedzi. Możesz także czytać kod innych osób i widzieć w nim błędy.
RemcoGerlich,
1

Czytając pytanie, nie widzę żadnej zasadniczej opozycji między twoją pozycją a pozycją twojego zespołu.

  • Tak, należy dołożyć wszelkich starań, aby odtworzyć problem występujący w ustawieniach klienta. Ale najlepszy wysiłek oznacza, że ​​powinieneś zdefiniować jakieś okno czasowe i w dzienniku może nie być wystarczającej ilości danych, aby odtworzyć problem.

    Jeśli tak, wszystko zależy od relacji z tym klientem. Może przejść od ciebie, że nie będziesz mieć nic od niego, możesz wysłać programistę na miejscu z narzędziami diagnostycznymi i możliwością uruchomienia ich w wadliwym systemie. Zwykle jesteśmy gdzieś pośrodku i jeśli początkowe dane nie są wystarczające, istnieją sposoby, aby uzyskać więcej.

  • Tak, starszy programista powinien być w stanie odczytać kod i prawdopodobnie znajdzie przyczynę problemu po treści dziennika. Naprawdę często jest możliwe napisanie testu jednostkowego, który wykazuje problem po uważnym przeczytaniu kodu.

    Pisanie takich testów jednostkowych jest prawie tak dobre, jak odtworzenie przełomowego środowiska funkcjonalnego. Oczywiście ta metoda również nie gwarantuje, że znajdziesz coś. Zrozumienie dokładnej sekwencji zdarzeń prowadzących do awarii w oprogramowaniu wielowątkowym może być bardzo trudne do znalezienia po prostu przez odczytanie kodu, a zdolność do debugowania na żywo prawdopodobnie stanie się krytyczna.

Podsumowując, spróbowałbym obu podejść jednocześnie i poprosiłbym o system na żywo wykazujący problem (i wykazujący, że problem został rozwiązany później) lub o pewne przerwanie testu jednostkowego zerwania problemu (a także pokazanie, że problem został rozwiązany po poprawce).

Próba naprawienia kodu i wysłania go w środowisku naturalnym wydaje się bardzo ryzykowna. W niektórych podobnych przypadkach, które mi się przydarzyły (w których nie udało się odtworzyć usterki wewnętrznie), wyjaśniłem, że jeśli poprawka zniknie i nie uda się rozwiązać problemu z klientem lub będzie miała inne nieoczekiwane negatywne konsekwencje, facet, który zaproponował musiałoby to pomóc zespołowi wsparcia znaleźć rzeczywisty problem. W tym w razie potrzeby kontakt z klientem.

Kriss
źródło
1

Wydaje mi się, że potrzebujesz bardziej szczegółowego logowania.

Dodanie większej ilości rejestrowania nie może zagwarantować, że nie będziesz musiał debugować (lub, w tym przypadku, odtworzyć sytuację), ale da ci o wiele lepszy wgląd w to, co poszło nie tak.

Zwłaszcza w skomplikowanych / wątkowych sytuacjach lub cokolwiek, w którym nie można użyć debugera, powrót do „debugowania przez printf ()” może być twoim jedynym wyjściem. W takim przypadku zaloguj jak najwięcej (więcej niż się spodziewasz) i przygotuj dobre narzędzia do filtrowania pszenicy z plew.

Mawg
źródło
1

Czy uzasadnione jest naleganie na odtworzenie każdej usterki i debugowanie jej przed zdiagnozowaniem i naprawieniem?

Ponieważ nikt jeszcze nie powiedział tego jasno: Absolutnie nie!

Jak wszystko inne w tworzeniu oprogramowania, usuwanie błędów oznacza pamiętanie o czasie, ryzyku i kosztach. Znalezienie równowagi między nimi to połowa opisu pracy programisty.

Niektóre błędy nie są wystarczająco ważne, aby spędzić 2 dni, ale wystarczająco ważne, aby poświęcić 10 minut na ich naprawienie. Inne błędy są niedeterministyczne i już wiesz, że środowisko testowe nie może udowodnić, że zostały naprawione. Jeśli skonfigurowanie środowiska testowego zajmuje 2 dni, nie robisz tego w przypadku tych błędów. Zamiast tego spędzasz czas na inteligentniejszych rzeczach, takich jak znalezienie sposobu na skonfigurowanie środowiska testowego w 5 minut zamiast 2 dni.

I oczywiście są błędy, w których jeśli się pomylicie, klient straci ponad 100 000 $. Oraz błędy, w których klient traci 100 000 $ + za każdą godzinę błędu nie został naprawiony. Musisz spojrzeć na błąd i podjąć decyzję. Instrukcje kocowe do traktowania wszystkich błędów tak samo nie działają.

Piotr
źródło
0

Bardzo dobre pytanie! Moim zdaniem, jeśli nie możesz odtworzyć problemu, nie możesz w 100% powiedzieć, że dokonana poprawka nie spowoduje:

a) faktycznie rozwiązać problem. b) stworzyć kolejny błąd

Czasami pojawia się błąd i naprawiam go i nie zawracam sobie głowy testowaniem. Wiem w 100% na pewno, że to działa. Ale dopóki nasz dział kontroli jakości nie powie, że to działa, uważam, że nadal istnieje możliwość, że nadal występuje błąd ... lub nowy błąd utworzony na podstawie poprawki.

Jeśli nie możesz odtworzyć błędu, a następnie zainstalować nową wersję i potwierdzić, że została ona naprawiona, nie możesz, ze 100% pewnością, powiedzieć, że błąd zniknął.

Próbowałem przez kilka minut wymyślić analogię, która pomogłaby ci wyjaśnić innym, ale tak naprawdę nic nie przyszło mi do głowy. Wazektomia jest zabawnym przykładem, ale nie jest to ta sama sytuacja :-)

Jaydel Gluckie
źródło
Załóżmy np., Że otrzymano raport, że program czasami nieprawidłowo formatuje niektóre liczby w formacie dziesiętnym po zainstalowaniu na francuskiej wersji systemu Windows; poszukiwanie kodu ustawiania kultury ujawnia, że ​​odkrywa się metody, które zapisują bieżącą kulturę wątków i ustawiają ją InvariantCulturew CompareExchangepętli, ale resetują ją później [tak, że jeśli CompareExchangezawiedzie za pierwszym razem, „zapisana” zmienna kultury zostanie nadpisana] . Odtworzenie okoliczności awarii byłoby trudne, ale kod jest wyraźnie niepoprawny i może powodować wskazany problem.
supercat
W takim przypadku konieczne byłoby odtworzenie awarii lub fakt, że dany kod byłby wyraźnie zdolny do powodowania awarii takich jak wskazany, byłby wystarczający, gdyby sprawdzono kod w innych miejscach, w których podobne tryby awarii mogłyby pojawić się?
supercat
Cóż, to wszystko, „zależy” od argumentu sytuacyjnego. Jeśli był to krytyczny system życia lub śmierci, a klient oczekiwał tego rodzaju testów, to tak, postaraj się odtworzyć problem i przetestować go. Musiałem pobrać kod na komputer klienta, aby móc debugować, ponieważ nie mogliśmy odtworzyć problemu na naszych serwerach testowych. To był problem bezpieczeństwa systemu Windows. Utworzono poprawkę i wszyscy są zadowoleni. Jest to trudne, jeśli skonfigurowanie środowiska testowego jest trudniejsze niż naprawienie błędu. Następnie możesz zapytać klienta. W większości przypadków sami testują.
Jaydel Gluckie
W przypadku podejrzeń o problemy z wątkami, nawet jeśli uda się zepsuć rzeczy w taki sposób, aby zmusić je do wystąpienia dokładnie w „niewłaściwym” czasie, czy istnieje sposób, aby naprawdę wiedzieć, czy problem, który odtworzyłeś, jest tym samym, co zaobserwowany przez klient? Jeśli kod ma taką wadę, że rzeczy dziejące się w określonym czasie spowodowałyby awarię, i jest to przynajmniej teoretycznie możliwy taki czas, pomyślałem, że kod powinien zostać naprawiony, czy można przetestować środowisko testowe, czy nie wymagane czasy występują. W wielu takich sytuacjach ...
supercat
... środowiska testowe i produkcyjne mają wystarczające różnice czasowe, więc ocena, czy rzeczywiście mogą wystąpić określone złe czasy, może być niezwykle trudna i niezbyt pouczająca. Ważne jest zbadanie miejsc, które mogą być potencjalnie wrażliwe na taktowanie, aby upewnić się, że tak nie jest, ponieważ testy wrażliwości na czas są podatne na wiele fałszywych negatywów.
supercat
0

[błąd związany z] równoczesnym dostępem do bazy danych, implementacja klastrowa, wielowątkowy

Czy uzasadnione jest naleganie na odtworzenie każdej usterki i debugowanie jej przed zdiagnozowaniem i naprawieniem?

Nie spędzałbym zbyt wiele czasu próbując go odtworzyć. Wygląda to na problem z synchronizacją i częściej można je znaleźć na podstawie rozumowania (zaczynając od dzienników takich jak ten, w którym należy wskazać podsystem, w którym występuje problem), niż poprzez znalezienie sposobu na odtworzenie go i zaatakowanie go za pomocą debugera . Z mojego doświadczenia wynika, że ​​obniżenie poziomu optymalizacji kodu, a czasem nawet aktywacja dodatkowego oprzyrządowania może wystarczyć, aby dodać wystarczające opóźnienie lub brak prymitywnej synchronizacji, aby zapobiec pojawieniu się błędu.

Tak, jeśli nie masz możliwości odtworzenia błędu, nie będziesz mieć pewności, że go naprawisz. Ale jeśli twój klient nie daje ci możliwości jego odtworzenia, możesz także szukać czegoś podobnego z tą samą konsekwencją, ale inną pierwotną przyczyną.

AProgrammer
źródło
0

Oba działania (przegląd kodu i testowanie) są konieczne, żadne nie jest wystarczające.

Mógłbyś spędzać miesiące konstruując eksperymenty, próbując naprawić błąd, i nigdy nie dotrzesz, jeśli nie spojrzysz na kod i nie sformułujesz hipotezy, aby zawęzić obszar wyszukiwania. Możesz spieszyć miesiące, wpatrując się w twój pępek, próbując wyobrazić sobie błąd w kodzie, możesz nawet pomyśleć, że znalazłeś go raz, dwa, trzy razy, tylko po to, aby coraz bardziej niecierpliwy klient powiedział: „Nie, błąd wciąż istnieje. „

Niektórzy programiści są relatywnie lepsi w jednym działaniu (przegląd kodu vs konstruowanie testów) niż w drugim. Idealny menedżer waży te mocne strony przy przypisywaniu błędów. Podejście zespołowe może być jeszcze bardziej owocne.

Ostatecznie może nie być wystarczającej ilości informacji, aby naprawić błąd, i musisz pozwolić mu marynować się przez pewien czas, mając nadzieję, że inny klient znajdzie podobny problem, dając ci lepszy wgląd w problem z konfiguracją. Jeśli klient, który widział błąd, naprawdę chce go naprawić, będzie współpracować z Tobą, aby zebrać więcej informacji. Jeśli ten problem pojawił się tylko raz, prawdopodobnie nie jest to błąd o wysokim priorytecie, nawet jeśli klient jest ważny. Czasami niedziałanie błędu jest mądrzejsze niż wymachiwanie roboczogodzinami, szukając naprawdę niejasnej wady z niewystarczającą ilością informacji.

SeattleCplusplus
źródło