Jak zlokalizować kod źródłowy, który zaimplementował określoną funkcję? [Zamknięte]

14

Zastanawiałem się, jakie są techniki zlokalizowania, który kod implementuje określoną funkcję w aplikacji komputerowej.

Jestem młodszym programistą, z profesjonalnym doświadczeniem w programowaniu internetowym. W Internecie łatwiej to zrobić. Na przykład „przeglądasz” przycisk za pomocą narzędzi przeglądarki i możesz zobaczyć, co się dzieje po jego kliknięciu. A następnie, zakładając, że masz pełny kod źródłowy, możesz pogłębić hierarchię wywołań.

Ale jak to zrobić w aplikacjach komputerowych? Przynajmniej bez konieczności nurkowania w pełnej bazie kodu?

py_script
źródło
6
Zamiast czytać kod, możesz czasem użyć debuggera. To, jak to działa (i jak przyjazny dla użytkownika jest dla Ciebie), zależy od używanego języka, debugera i interfejsu debuggera. W każdym razie korzystanie z debugera jest sztuką, której należy się nauczyć - ale kiedy się ją nauczy, jest to bardzo potężne narzędzie. Powinienem kiedyś nauczyć się używać jednego z nich.
amon
I gdzie powinienem ustawić punkty przerwania?
py_script
Konfiguracja punktu przerwania zależy całkowicie od aplikacji i sposobu jej organizacji.
2
W rzeczywistości może być trochę trudno „sprawdzić” i zobaczyć, gdzie i jak powstały interfejsy sieciowe, dzięki nowym systemom obiektowym, takim jak Backbone.js i szablony, które stają się coraz bardziej popularne.
NoBugs
1
@ jeffo Kiedy na przykład robisz File-> Open w aplikacji (powiedzmy LibreOffice's Writer), jak możesz znaleźć sekwencję wywołań?
py_script

Odpowiedzi:

21

Śledzenie pleców

Śledzenie wsteczne polega na zlokalizowaniu punktu końcowego zdarzenia powiązanego z funkcją (patrz poniżej). Tam znajduje się punkt przerwania w debuggerze. Ta funkcja jest uruchamiana i zatrzymuje się debuger. Stos wywołań jest sprawdzany pod kątem wstecznego śledzenia ścieżki wywoływania. Idąc w górę stosu wywołań, możesz robić notatki na temat stanów zmiennych lub umieszczać nowe punkty przerwania, aby ponownie sprawdzić zdarzenie.

Ta funkcja jest ponownie wyzwalana, a debuger zatrzymuje się w nowych punktach przerwania. Następnie możesz powtarzać śledzenie wstecz lub wykonywać śledzenie do przodu, aż do znalezienia celu.

Za I przeciw

  • Zawsze łatwiej jest wejść na stos wywołań i zobaczyć, jak się gdzieś dostałeś.
  • Mogą istnieć miliony warunków, które muszą być spełnione przed osiągnięciem punktu końcowego. Jeśli znasz już punkt końcowy, zaoszczędziłeś sobie dużo pracy.
  • Jeśli funkcja jest zepsuta. Możesz nigdy nie dotrzeć do punktu końcowego, a czas może zostać zmarnowany, próbując dowiedzieć się, dlaczego.

Endpoint Discovery

Aby debugować funkcję, musisz wiedzieć, gdzie w kodzie źródłowym osiągnięty jest ostateczny cel. Tylko od tego momentu możesz śledzić wstecz, aby zobaczyć, jak kod się tam dostał. Przykład; Aby zrozumieć, jak wykonuje się cofanie. Wiesz, gdzie w kodzie rzeczy się cofają, ale nie wiesz, jak się tam sprawy mają . Byłby to kandydat do śledzenia wstecznego, aby dowiedzieć się, jak działa ta funkcja.

Śledzenie do przodu

Śledzenie do przodu polega na zlokalizowaniu punktu początkowego zdarzenia związanego z funkcją (patrz poniżej). Tam wiadomości logowania są wstawiane do kodu źródłowego lub ustawiane są punkty przerwania. Proces ten powtarza się w miarę oddalania się od punktu początkowego, aż odkryjesz cel funkcji.

Za I przeciw

  • To najłatwiejszy punkt wyjścia do znalezienia funkcji.
  • Złożoność kodu zmniejsza skuteczność śledzenia do przodu. Im więcej warunków w kodzie, tym większa szansa, że ​​pójdziesz w złym kierunku.
  • Śledzenie w przód często powoduje ustawienie punktów przerwania, które będą wyzwalane przez niepowiązane zdarzenia. Przerywanie procesu debugowania i zakłócanie wyszukiwania.

Rozpocznij odkrywanie punktów

Możesz użyć słów kluczowych, identyfikatorów interfejsu użytkownika (identyfikatory przycisków, nazwy okien) lub łatwo znaleźć detektory zdarzeń powiązane z funkcją. Na przykład możesz zacząć od przycisku służącego do uruchamiania funkcji cofania .

Proces eliminacji

Możesz myśleć o tym jako o punkcie środkowym w porównaniu do pozycji punktu początkowego i końcowego . Proces eliminacji wykonuje się, gdy wiadomo, że w kodzie użyto fragmentu kodu , ale nie jest to ani początek, ani koniec funkcji.

Kierunek, który wybierzesz od punktu środkowego, zależy od liczby wejść i wyjść. Jeśli fragment kodu jest używany w wielu miejscach, śledzenie wstecz z tej pozycji może być bardzo czasochłonne, ponieważ wszystkie muszą zostać sprawdzone. Następnie stosuje się proces eliminacji, aby zmniejszyć tę listę. Alternatywnie, możesz wykonać śledzenie do przodu od tego miejsca, ale ponownie, jeśli fragment kodu rozgałęzia się do wielu miejsc, może to również stanowić problem.

Musisz zredukować kierunki pozycji, nie podążając ścieżkami, które najwyraźniej nie zostałyby wykonane dla operacji. Przechodzenie obok tego kodu i umieszczanie punktów przerwania tylko tam, gdzie jest to prawdopodobnie związane z funkcją.

Debugowanie w punkcie środkowym często wymaga bardziej zaawansowanych funkcji IDE. Możliwość zobaczenia hierarchii kodu i zależności. Bez tych narzędzi trudno to zrobić.

Za I przeciw

  • Punkty środkowe są często pierwszym kawałkiem kodu, który pojawia się w twojej głowie, gdy myślisz o tej funkcji. Mówicie sobie: „Ach, do pracy trzeba użyć XXXX”.
  • Punkty środkowe mogą najłatwiej ujawnić punkty początkowe .
  • Punkty środkowe mogą być łatwym sposobem na wybranie ścieżki do obiektu, gdy zostanie utracony przez synchronizację lub zmiany wątków.
  • Punkty środkowe mogą zabrać Cię do kodu, którego nie znasz. Poświęcenie czasu na nauczenie się, co się dzieje.
Reactgular
źródło
Dzięki Matthew, świetne podejście. Ale jak znaleźć punkt początkowy (przepraszam, jeśli jest to oczywiste dla wszystkich oprócz mnie)?
py_script
@py_script Z jakim językiem programowania masz problemy?
Reactgular
Nie chodzi o konkretny problem, który mam, ale moim głównym językiem programowania pulpitu jest Java, więc chodźmy z nim
py_script 10.03.2014
11

Zakładając, że ta funkcja jest powiązana z jakimś interfejsem użytkownika, takim jak przycisk lub menu, zwykle robię to (bardzo żmudne, ale działa). Jest to pominie kodu źródłowego, a nie za pomocą debuggera .

  1. Wyszukaj (na szczęście charakterystyczny) tekst na przycisku, np. „Super Feature X3”.
  2. Prawdopodobnie jest to plik z pewną stałą, np SUPER_BUTTON_3 = "Super Feature X3" . Do przyszłego wykorzystania zapamiętaj tę nazwę pliku.
  3. Może istnieć kolejna warstwa (nawet dwie) abstrakcji, szukaj dalej, aby uzyskać „prawdziwy” ciąg znaków, który zostanie wykorzystany przez Przycisk. Zwróć uwagę, jak to się robi w przyszłości.
  4. Teraz wyszukaj tę stałą. Mam nadzieję, że znalazłeś przycisk. Może właśnie tam łączą ActionListener. (Biorę tutaj Java-ese, YMMV, ale koncepcja nadal obowiązuje)
  5. Jeśli to konieczne, wyszukaj ten przycisk, a w końcu dowiesz się, gdzie łączy się on ze słuchaczem.
  6. Być może ten słuchacz naprawdę przekierowuje do innych słuchaczy („prawdziwa” funkcjonalność) na podstawie stałej, jeśli tak, postępuj zgodnie z instrukcją if / else lub case. UWAGA : Jeśli istnieje centralna dyspozytorska kwestia, jest to świetne miejsce do ustawienia punktów przerwania .
  7. Wreszcie powinieneś znaleźć się przy rzeczywistym kodzie.

Jak zauważył @amon, czasami debugger jest prostszy ...

użytkownik949300
źródło
Ciekawe ... na szczęście takie nazwy są zwykle zakodowane na stałe w kodzie :)
py_script
3
  • Jeśli możesz w ogóle znaleźć pokrewny kod, możesz użyć oprogramowania do kontroli źródła, aby pokazać całe zatwierdzenie lub pobliskie zatwierdzenia, które go dodały. To powinno pokazać ci wszystko, co było wymagane do wdrożenia tej funkcji.

  • Jednym z łatwych sposobów znalezienia punktu wyjścia do przeszukania byłoby przeszukanie bazy kodu w poszukiwaniu tekstu na przycisku.

  • Często ludzie umieszczają identyfikator problemu ze swojego modułu do śledzenia problemów w swoich komunikatach zatwierdzania. Jeśli możesz znaleźć problem opisujący żądanie funkcji, możesz wyszukać zatwierdzenia z tym identyfikatorem problemu.

Michael Burge
źródło
To inteligentne podejście, ale myślę, że działa tylko w środowiskach korporacyjnych. Co jeśli masz tylko tarball?
py_script