Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Základy vývoje v prostředí GNU/Linux Tématicky zaměřený vývoj aplikací v jazyce C skupina Systémové programování – Linux Martin Drašar, Martin Husák, Petr Velan Fakulta informatiky Masarykova univerzita drasar|husakm|velan@ics.muni.cz Brno, 5. říjen 2015 Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 1 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Představení RNDr. Martin Husák výzkumný pracovník Bezpečnostního oddělení Ústavu výpočetní techniky, zabývám se síťovými pastmi (honeypoty) a zpracováním vysokorychlostního síťového provozu. kontakt email husakm@ics.muni.cz kancelář FI, budova C, C316 Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 2 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Zvyklosti vývoje v prostředí GNU/Linux zvyklosti v chování aplikací, interakce aplikací s okolím Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 3 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Adresářová struktura GNU/Linux /bin/ obecné systémové binárky pro všechny uživatele /boot/ soubory potřebné pro zavaděč, jádro /dev/ soubory zařízení (disky, usb, porty, . . . ) /etc/ konfigurační soubory /lib/ sdílené systémové knihovny modules/ moduly jádra /proc/ speciální virtuální filesystém obsahující informace o jádře /sbin/ obecné systémové binárky pro privilegované uživatele /tmp/ dočasné soubory /usr/ soubory potřebné pro běžnou práci bin/ binárky programů doc/ dokumentace aplikací include/ hlavičkové soubory lib/ další sdílené knihovny local/ aplikace, knihovny, . . . instalované ze zdrojových souborů man/ manuálové stránky sbin/ další systémové binárky share/ konfigurační soubory a další nastavení aplikací /var/ pracovní (měnící se) soubory pro běžící programy a služby Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 4 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Parametry příkazové řádky Základní způsob předávání vstupních informací programu. Pravidla popsána v rámci normy POSIX → GNU Standards. Používejte standardní názvy parametrů a standardní chování. Obvyklá syntax přepínačů: - - -- -- -- --= info "(standards)User Interfaces" Využívejte standardní funkce: getopt – zpracovává krátké parametry getopt_long – zpracovává dlouhé parametry, není součástí POSIX (GNU rozšíření) Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 5 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Proměnné prostředí Slouží k nastavení chování aplikace. Z příkazové řádky: export MYVAR=ahoj echo $MYVAR Z aplikace: getenv() – vrátí hodnotu proměnné putenv(), setenv() – nastaví hodnotu proměnné Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 6 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Proměnné prostředí Slouží k nastavení chování aplikace. Z příkazové řádky: export MYVAR=ahoj echo $MYVAR Z aplikace: getenv() – vrátí hodnotu proměnné putenv(), setenv() – nastaví hodnotu proměnné Užitečné proměnné prostředí $LD_LIBRARY_PATH $PATH $RANDOM Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 6 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Proměnné prostředí – bezpečnost Nespoléhejte se na proměnné prostředí (PATH, IFS, HOME, . . . ). extern char** environ; Dezinfekce sady proměnných prostředí vytvoření vlastního pole environ nastavení proměnných prostředí na bezpečné hodnoty převzetí vybraných původních hodnot Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 7 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt úkol Napište si vlastní verzi aplikace printenv(1) Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 8 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Konfigurační soubory Obvyklé umístění v /etc/, ale také /usr/share/. Neexistuje jednotný formát konfiguračních souborů. proměnná hodnota (sshd) vlastní syntax (Apache) XML (D-Bus) YAML JSON (REST) Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 9 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Konfigurační soubory Obvyklé umístění v /etc/, ale také /usr/share/. Neexistuje jednotný formát konfiguračních souborů. proměnná hodnota (sshd) vlastní syntax (Apache) XML (D-Bus) YAML JSON (REST) → Snažte se dodržovat obvyklé konvence pro typ aplikace, kterou vytváříte. Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 9 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Opravy kódu Standardní utility diff a patch Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 10 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Opravy kódu Standardní utility diff a patch Postup vytvoření a aplikace patche vytvořte kopii originálu (celou adresářovou strukturu, konkrétní soubor) upravte kód diff -ur file.orig file > file.patch patch -p0 -i file.patch Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 10 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt úkol Ve studijních materiálech je soubor param.c Najděte v kódu chybu a připravte patch. Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 11 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Dynamicky linkované objekty dynamické knihovny, kód přidávaný za běhu (pluginy) Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 12 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt API vs. ABI (I) API – Application Programming Interface (vysokoúrovňové) rozhraní mezi zdrojovým kódem a knihovnami – zdrojový kód lze zkompilovat ABI – Application Binary Interface (nízkoúrovňový) popis toho, jak jsou data uložena v paměti, tento popis používá compiler např. při referenci proměnných, umožňuje již zkompilovanému kódu běžet v prostředí s kompatibilním ABI API i ABI měňte co nejméně často (raději funkce přidávejte). Rozhodně rozumně verzujte při změnách! Změny v ABI jsou nebezpečnější – nemusí být hned vidět a přijdete na ně až když něco nefunguje. Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 13 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt API vs. ABI (II) Příklady reimplementace funkce – Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 14 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt API vs. ABI (II) Příklady reimplementace funkce – API, ABI kompatibilní změna hodnoty položky enumu – Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 14 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt API vs. ABI (II) Příklady reimplementace funkce – API, ABI kompatibilní změna hodnoty položky enumu – API kompatibilní, ABI nekompatibilní změna pořadí položek struktury – Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 14 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt API vs. ABI (II) Příklady reimplementace funkce – API, ABI kompatibilní změna hodnoty položky enumu – API kompatibilní, ABI nekompatibilní změna pořadí položek struktury – API kompatibilní, ABI nekompatibilní odstranění funkce – Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 14 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt API vs. ABI (II) Příklady reimplementace funkce – API, ABI kompatibilní změna hodnoty položky enumu – API kompatibilní, ABI nekompatibilní změna pořadí položek struktury – API kompatibilní, ABI nekompatibilní odstranění funkce – API nekompatibilní přidání nové funkce – Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 14 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt API vs. ABI (II) Příklady reimplementace funkce – API, ABI kompatibilní změna hodnoty položky enumu – API kompatibilní, ABI nekompatibilní změna pořadí položek struktury – API kompatibilní, ABI nekompatibilní odstranění funkce – API nekompatibilní přidání nové funkce – API zpětně kompatibilní Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 14 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt API vs. ABI (II) Příklady reimplementace funkce – API, ABI kompatibilní změna hodnoty položky enumu – API kompatibilní, ABI nekompatibilní změna pořadí položek struktury – API kompatibilní, ABI nekompatibilní odstranění funkce – API nekompatibilní přidání nové funkce – API zpětně kompatibilní nekompatibilní API – aplikaci je třeba upravit nekompatibilní ABI – aplikaci je třeba pouze překompilovat Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 14 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Dynamické (sdílené) knihovny kolekce kódů dynamicky připojitelných k aplikaci za běhu připojitelných i k několika aplikacím najednou způsob jak předcházet duplikaci kódu šetří diskové místo :) snadná aktualizace a oprava chyb program je pak ale závislý na požadovaných knihovnách Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 15 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Dynamické knihovny v Linuxu I ldconfig(8) vytvoří symbolické odkazy na instalované knihovny – linker většinou použije právě tyto symlinky vytvoří cache instalovaných knihoven pro dynamický linker potřebné soubory včetně informace o umístění knihoven jsou v /etc/ld.so.* obvyklé umístění knihoven je /lib/,/lib64/,/usr/lib/,/usr/lib64/, . . . proměnné prostředí LD_LIBRARY_PATH – umístění knihoven (před standardními cestami) LD_PRELOAD – knihovna, která má být přilinkována jako první LD_DEBUG – LD_DEBUG=libs date Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 16 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Dynamické knihovny v Linuxu II soname: ’lib’ + jméno + ’.so.’ + verze /lib/ld-linux.so.X – run-time linker (loader) ldd(1) – zjistí závislosti dynamických objektů objdump(1) – vypíše informace o objektových souborech Vytváření dynamické knihovny vytvořte objekty s kódem nezávislým na pozici (PIC) gcc -fPIC -c file.c z objektů vytvořte dynamickou knihovnu gcc -shared -Wl,-soname,libmyname.so.1 \ -o libmyname.so.1.0.0 file.o Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 17 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt úkol napište vlastní verzi funkce localtime() - je na vás, jaký čas bude vracet vyzkoušejte si LD_PRELOAD s vaší verzí localtime() na programu date Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 18 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Pluginy (dynamicky linkovaný kód) Otevření dynamického objektu za běhu aplikace. dlopen() dlsym() dlerror() dlclose() Při překladu (gcc) je nutné použít přepínač -ldl. Ukazatel na funkci: návratový_typ (*identifikátor)(seznam_typů_parametrů); Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 19 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Pluginy (dynamicky linkovaný kód) Otevření dynamického objektu za běhu aplikace. dlopen() dlsym() dlerror() dlclose() Při překladu (gcc) je nutné použít přepínač -ldl. Ukazatel na funkci: návratový_typ (*identifikátor)(seznam_typů_parametrů); void* (*funkce)(void* ukazatel, size_t velikost); Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 19 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Pluginy (dynamicky linkovaný kód) Otevření dynamického objektu za běhu aplikace. dlopen() dlsym() dlerror() dlclose() Při překladu (gcc) je nutné použít přepínač -ldl. Ukazatel na funkci: návratový_typ (*identifikátor)(seznam_typů_parametrů); void* (*funkce)(void* ukazatel, size_t velikost); http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 19 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Závěr domácí úkoly a zdroje Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 20 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Domácí úkol (rozšíření úkolu z hodiny) Využijte princip pluginu a napište 2 knihovny, které různě implementují podobnou funkcionalitu (např. tisknou různé zprávy) Vytvořte program, který volá jednotlivé funkce z různých knihoven – při startu programu podle parametru příkazové řádky. Nezapomeňte na srozumitelnou nápovědu a ošetření chyb (neexistující plugin, atd.)! Vše uložte do Git. Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 21 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Zdroje parametry příkazové řádky www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html www.gnu.org/prep/standards/standards.html#Command_002dLine-Interfaces www.gnu.org/prep/standards/standards.html#Option-Table dynamicky linkované objekty tldp.org/HOWTO/Program-Library-HOWTO/index.html www.gnu.org/prep/standards/standards.html#Command_002dLine-Interfaces www.gnu.org/prep/standards/standards.html#Option-Table ostatní www.di.uniovi.es/∼cernuda/noprog_ENG.html wezfurlong.org/blog/2006/dec/coding-for-coders-api-and-abi-considerations-in-an- evolving-code-base Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 22 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Projekt - Internet of Tanks (IoT) World Tank #1 Tank #N IPC IPC Config file CLI output Client Client Socket Socket Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 23 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Projekt World Čte konfiguraci Spouští a ukončuje tanky dle konfiugrace Komunikuje s tanky pomocí IPC Udržuje přehled o stavu světa Počítá pohyb a akce tanků Vypisuje stav světa přes CLI Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 24 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Projekt Tank Komunikuje se světem pomocí IPC Komunikuje s klientem (poslouchá na TCP portu) Předává příkazy klienta světu Klient se autentizuje heslem Při zničení tanku proces uzavírá komunikaci a končí Client Přihlašuje se k tanku Posílá příkazy tanku Informuje uživatele o potvrzení příkazů a zničení tanku Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 25 / 26 Zvyklosti vývoje Dynamicky linkované objekty Závěr Projekt Projekt Tým si určí jeden repozitář kde bude dále probíhat vývoj, vyřeší si přístupy Adresu repozitáře pro další vývoj sdělte mailem Zatím si můžete promyslet kdo co bude dělat Programování není mnoho, o to více se budeme věnovat funkčnosti kódu Komunikace client-tank, tank-world budou testovány i mezi týmy Drašar, Husák, Velan 2 – Základy vývoje v prostředí GNU/Linux 5. 10. 2015, Brno 26 / 26