======================================== Zadanie 4: Powrót Kalkulatora Wyborczego ======================================== Data ogłoszenia: 06.06.2019 Termin oddania: 05.09.2019 (brak możliwości spóźnienia) Materiały dodatkowe =================== - :download:`parse.py`: narzędzie do wyświetlania danych z ulepszonych plików ``core`` - :download:`z4-test.tar.gz`: testy do zadania Wprowadzenie ============ Niestety, nie wszystkie rozwiązania pierwszego zadania spełniły nasze oczekiwania -- w niektórych okręgach wyborczych, Kalkulator Wyborczy zakończył działanie śmiertelnym sygnałem ``SIGSEGV``. Ze względów bezpieczeństwa, nie możemy używać debuggera na maszynach liczących głosy -- dostaliśmy jedynie zrzuty ``core`` wytworzone przez nasz Kalkulator. Przy analizie tych zrzutów pojawił się poważny problem: przyczyna błędów leży najprawdopodobniej w kodzie obsługi plików, a zrzuty ``core`` nie zawierają żadnych informacji o otwartych plikach w momencie awarii programu. Zadanie ======= Dopisać do kodu tworzącego pliki ``core`` w jądrze kod zrzucający tablicę otwartych plików w momencie śmierci procesu, pozwalając nam na zdebugowanie kodu przed jesiennymi wyborami. Szczegóły ========= Ponieważ jeden plik ``core`` może zawierać wiele wątków z różnymi tablicami deskryptorów (przypadek ``CLONE_VM`` bez ``CLONE_FILES``), plik powinien zawierać osobny zrzut tablicy deskryptorów dla każdego wątku (analogicznie do zrzutów rejestrów). Każdy z tych zrzutów powinien być jedną strukturą ``ElfXX_Note`` o nazwie ``LINUX`` i nowo zdefiniowanym typie ``NT_FDS`` (numeryczna wartość ``0x4f4453``). Struktura ta powinna być umieszczona bezpośrednio po wszystkich strukturach opisujących stan rejestrów danego wątku. Zawartość (pole ``desc``) tej struktury powinna być następująca: - ``uint32_t num_fds``: liczba otwartych deskryptorów - dla każdego deskryptora, po kolei: - ``uint32_t fd``: numer deskryptora, - ``uint32_t flags``: flagi pliku (pole ``f_flags`` w ``struct file``), - ``uint64_t pos`` (niekoniecznie wyrównane): pozycja w pliku (pole ``f_pos``), - ``uint32_t mode``: tryb otwarcia pliku (pole ``f_mode``), - ``uint32_t domain``: jeżeli plik jest socketem, domena socketu (czyli stała ``AF_*``), w przeciwnym wypadku ``-1``, - ``uint32_t type``: jeżeli plik jest socketem, typ socketu (czyli stała ``SOCK_*``), w przeciwnym wypadku ``-1``, - ``uint16_t local_addr_len`` jeżeli plik jest socketem i ma lokalny adres, rozmiar lokalnego adresu w bajtach, w przeciwnym wypadku 0, - ``uint16_t remote_addr_len`` jeżeli plik jest socketem i ma zdalny adres, rozmiar zdalnego adresu w bajtach, w przeciwnym wypadku 0, - ``uint8_t local_addr[local_addr_len]``: jeżeli plik jest socketem, lokalny adres (czyli to, co zwróciłoby ``getsockname``), - ``uint8_t remote_addr[remote_addr_len]``: jeżeli plik jest socketem, zdalny adres (czyli to, co zwróciłoby ``getpeername``), - ``char path[]``: ścieżka do pliku, zakończona bajtem zerowym. W przypadku plików specjalnych (socket, pipe, ...), należy użyć tej samej sztucznej nazwy, co system plików ``proc``, - ``uint8_t _pad[]``: tyle bajtów zerowych, ile potrzeba, by wyrównać pozycję do 4 bajtów. Do weryfikacji, że dane są zrzucane w poprawnym formacie, dostarczamy skrypt :download:`parse.py`. Zasady oceniania ================ Za zadanie można uzyskać do 10 punktów. Na ocenę zadania składają się dwie części: - funkcjonalność rozwiązania: - brak specjalnej obsługi socketów -- wypełnienie pól ``domain``/``type``/``*_addr`` stałymi wartościami (0 punktów) - pełne rozwiązanie z obsługą socketów (2 punkty) - wynik testów (od 0 do 8 punktów) - ocena kodu rozwiązania (od 0 do -10 punktów) Punktacja --------- Testy weryfikujące działanie socketów były warte 2 pkt., a pozostałe testy - 8pkt. Punkty z oceny kodu: 1. Niepoprawna postać rozwiązania / nienakładający patch (-2.0) 2. Brak README (-0.1) 3. Copy-paste kodu (wiele funkcji zamiast makra) (-0.0) 4. Wyciek pamięci (-0.5) 5. Nadmiarowy diff (zmiany dot. wyłącnie białych znaków) (-0.0) 6. Dodawanie stałej (małej) liczby bajtów local_addr / remote_addr do core (-0.5, tylko jeśli przechodzą testy) 7. Użycie polskiego nazewnictwa (-0.2) 8. Definicja typu NT_FDS w niestandardowym miejscu / brak definicji (-0.0) 9. Race condition – możliwoć wystąpienia zmiany stanu między obliczaniem potrzebnej pamięci a momentem kopiowania (-0.5) Forma rozwiązania ================= Jako rozwiązanie należy wysłać paczkę zawierającą: - patcha na jądro w wersji 4.20.8, w jednym z następujących formatów: - patch wygenerowaniy przez diffa z opcjami ``-uprN`` nakładający się przez ``patch -p1`` - ``git format-patch`` - krótki opis rozwiązania Rozwiązania prosimy nadsyłać na adres ``p.zuk@mimuw.edu.pl`` z kopią do ``mwk@mimuw.edu.pl``.