abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
dnes 10:22 | Pozvánky

Od 23. do 25. září bude probíhat online konference LibreOffice 2021. Během tří dnů je připraveno okolo padesáti přednášek, workshopů a komunitních setkání s tématy týkající se kancelářského balíku, komunity a open source. Program je k dispozici na stránce konference. Konference se bude konat na komunikační platformě Jitsi a je zdarma. Připravuje se také YouTube přenos. Registrace je dostupná na stránce konference.

Zdeněk Crhonek | Komentářů: 0
dnes 08:00 | Zajímavý software

Chafa (GitHub) je utilita a knihovna pro zobrazování libovolných obrázků v terminálu. Novinky v nejnovější verzi 1.8 v příspěvku na blogu.

Ladislav Hagara | Komentářů: 1
včera 12:11 | Nová verze

Společnost Jolla oznámila vydání verze 4.2.0 s kódovým názvem Verla mobilního operačního systému Sailfish OS (Wikipedie). Podrobný přehled novinek v poznámkách k vydání.

Ladislav Hagara | Komentářů: 0
18.9. 20:33 | Nová verze

Foreman (Wikipedie), nástroj pro kompletní správu životního cyklu fyzických i virtuálních serverů, byl vydán ve verzi 3.0. Přehled novinek v poznámkách k vydání.

Ladislav Hagara | Komentářů: 0
18.9. 14:11 | Nová verze

Byla vydána nová stabilní verze 2.10.28 svobodné aplikace pro úpravu a vytváření rastrové grafiky GIMP (GNU Image Manipulation Program). Verze 2.10.26 byla přeskočena. Přehled novinek v oznámení o vydání a v souboru NEWS na GitLabu. Vývojáři zdůrazňují opravu několika chyb ve verzi pro Windows. Nový GIMP je již k dispozici také na Flathubu.

Ladislav Hagara | Komentářů: 1
18.9. 13:55 | Nová verze

Český LibreOffice tým vydává překlad příručky LibreOffice Impress 7.0. Tato příručka je určena pro začátečníky i pokročilé uživatele aplikace Impress, prezentační komponenty v LibreOffice. S její pomocí můžete vytvářet snímky, které obsahují text, číslované a odrážkové seznamy, tabulky, grafy, videoklipy, kliparty a další objekty. Impress přichází s předdefinovanými textovými styly a předlohami snímků; můžete si také vytvořit vlastní. Příručka je ke stažení na stránce dokumentace. Tým nyní pracuje na překladu příruček Draw a Base.

Zdeněk Crhonek | Komentářů: 0
17.9. 20:00 | Nová verze

Bylo vydáno Ubuntu 18.04.6 LTS, tj. šesté opravné vydání Ubuntu 18.04 LTS s kódovým názvem Bionic Beaver (poznámky k vydání). Řešen je především problém s bootovaním předchozích instalačních obrazů se zapnutým Secure Bootem z důvodu revokace klíčů kvůli BootHole a dalším bezpečnostním chybám v zavaděči GRUB 2.

Ladislav Hagara | Komentářů: 2
17.9. 09:22 | Komunita

Vývojáři Ubuntu oznámili, že v Ubuntu Desktopu bude Firefox ve formátu deb nahrazen Firefoxem ve formátu snap vydávaným přímo Mozillou. Pravděpodobně již ve verzi 21.10.

Ladislav Hagara | Komentářů: 59
17.9. 08:00 | Nová verze

Deno (Wikipedie), běhové prostředí (runtime) pro JavaScript a TypeScript, bylo vydáno ve verzi 1.14. Přehled novinek v poznámkách k vydání.

Ladislav Hagara | Komentářů: 0
17.9. 07:00 | Komunita

Linux Mint má nové webové stránky. Pro porovnání stránky z minulého týdne.

Ladislav Hagara | Komentářů: 1
Dotykový displej na notebooku nebo desktopu
 (37%)
 (7%)
 (5%)
 (52%)
Celkem 447 hlasů
 Komentářů: 11, poslední 18.9. 18:45
Rozcestník

Programování v C: sanitizer, profilování

4.9. 16:34 | Přečteno: 1060× | Linux | Výběrový blog | poslední úprava: 4.9. 16:39

Ukážeme si dva nástroje pro efektivnější vývoj v C (a C++): Address Sanitizer a Perf.

Sanitizér

V C je snadné si něčeho nevšimnout a střelit se do nohy:

V nejlepším případě program s nějakou takovou chybou crashne hned (a tak to hned vidíte), v horším případě crashne až po dlouhé době při specifické konstelaci hvězd někde na produkci, a v nejhorším případě se tím vytvoří skrytá vzdáleně zneužitelná bezpečnostní díra.

Čtenáři zpráviček vědí, že správné řešení je přepsat všechno do Rustu, ale lidi, co to dělat neplánují, se můžou pokusit uvedené chyby nějakým asistovaným způsobem najít, i když se ještě nestihly projevit pádem programu. A k tomu právě slouží satanizéry.

Valgrind

Pro vysvětlení sanitizéru je potřeba udělat trochu odbočku. Mnohem starší projekt je Valgrind. Provádí binární instrumentaci existujícího kódu + nahradí některé knihovní funkce speciálními variantami: například malloc musí někam poznamenávat, jak dlouhý region je alokován (a detekuje se, jestli nepřistupujete mimo něj), a free musí poznamenávat, jaké adresy byly uvolněny, a držet je v karanténě (zatímco standardní malloc/free paměť ihned recykluje), aby se mohlo detekovat use-after-free.

(následující vysvětlení je podle toho co si pamatuju ze školy a možná to je blbě) Binární instrumentace funguje tak, že chceme přepsat kód (ve smyslu zkompilované binárky) programu tak, aby každý přístup do paměti nejdřív ověřil, že přistupuje do validního regionu - například se musí ověřit, že uvedená adresa byla alokována (mallocem nebo na stacku), že ještě nebyla uvolněna (use after free), a při čtení nás též může zajímat, že do ní bylo předtím zapsáno, tj. nejedná se o čtení neinicializované paměti. To se nedá udělat inplace, protože přidáním těchto kontrol se kód prodlouží, a my nevíme, jak zběsile můžou být někde jumpy kdo ví kam (třeba někde za chvíli bude computed jump, který bude chtít skočit doprostřed kódu, který jsme právě přepsali). Proto se program rozdělí na tzv. basic blocks, což je lineární sekvence instrukcí, které neobsahují jump, a končí jumpem. Taková sekvence se může bezpečně přepsat, někam uložit a spustit. Po jejím vykonání bude následovat jump někam, a my v cíli jumpu disassemblujeme kód až do dalšího jumpu, vyrobíme z toho další basic block (opatchovaný přidanými kontrolami) a spustíme ho. Takže na začátku vyrobíme basic block z main(), přidáme tam příslušnou instrumentaci (kontroly přístupů do paměti), a jakmile narazíme na jump, tak pokračujeme tam. Takhle při běhu programu postupně z celého spouštěného kódu vyrobíme basic blocky, mezi kterými se skáče, a samozřejmě pak se nám bude stále častěji dít, že budeme skákat na místa, která už známe, takže tu pomalou instrumentaci už nebudeme dělat znovu a použijeme již hotový basic block.

Výhoda Valgrindu je, že nepotřebuje program speciálně překompilovat (funguje s existující binárkou). Nevýhoda Valgrindu je, že vygenerované basic blocky a skákání mezi nimi je příšerně pomalé. Program se zpomalí třeba 30x. Je tak možné pod Valgrindem spustit nějaké malé automatizované testy nebo zreprodukovat konkrétní bug, ale většinou nejde program s Valgrindem normálně používat.

Sanitizers

Sanitizéry používají instrumentaci na úrovni zdrojového kódu (a vlastní malloc stejně jako Valgrind). Před kompilací se každý přístup do pole a každá dereference pointeru obalí kontrolou a následně se program zkompiluje. To znamená, že veškeré optimalizace, které kompilátor dělá, dělá s tímto, a například o většině kontrol dokáže, že jsou redundantní a odstraní je, a ty zbylé může díky znalosti původního zdrojáku dále optimalizovat. Velkou výhodou je, že výsledný program je mnohem rychlejší než produkt Valgrindu. Podle konkrétní věci co dělá je zpomalení buď úplně neznatelné (pokud většinu času tráví nějakým výpočtem, kde nedochází k přístupům na mnoho nových míst v paměti, a tedy kontroly nemusí probíhat) nebo zhruba 2-3x (to se stalo třeba mé implementaci splay stromu, kde je spousta operací s pointery, a tedy se musí pořád kontrolovat). Program zkompilovaný se sanitizérem tak jde normálně používat a dokonce nasadit do produkce.

Velká nevýhoda sanitizérů je nutnost rekompilace. To u našeho programu typicky nevadí (když program vyvíjím, tak si ho kompiluju, že), ale není hned zjevné, že se to týká i všech použitých knihoven: představte si, že ve svém programu blbě naalokujete paměť, nesáhnete na ni (takže se nevyvolá kontrola a nepřijde se na to), a pointer na tuto paměť předáte do nějaké cizí knihovny. Následná chyba vznikne v této knihovně, která ale se sanitizérem nebyla zkompilovaná a tak se na to nepřijde, a problém je na světě. Měli byste tedy jakoby se sanitizérem překompilovat celý runtime. Problém pak ještě může nastat, když nějaká knihovna se sanitizérem zkompilovat nejde. Například se mi zdá, že si každý druhý píše vlastní alokátor (například talloc), a tyhle custom alokátory si nemusí rozumět s výše zmíněnou speciální implementací malloc a free.

Alokace paměti na Linuxu z rychlíku

Informace o tom, jakou paměť má proces namapovanou, nalezneme v souboru /proc/PID/maps. Příklad programu, který se spustil, naalokoval 30MB pole a skončil (kráceno + ručně dopsané velikosti regionů):

55674aaf8000-55674aaf9000 r-xp 00001000 fd:02 11796707                   /tmp/mujprogram
7f05aec0e000-7f05aed59000 r-xp 00025000 fd:02 4456625                    /lib/x86_64-linux-gnu/libc-2.31.so
55674b395000-55674b3b6000 [132 KiB] rw-p 00000000 00:00 0                [heap]
7f05acf4c000-7f05aebe9000 [30 MB]   rw-p 00000000 00:00 0 
7ffcd47e2000-7ffcd4803000 [132 KiB] rw-p 00000000 00:00 0                [stack]
7ffcd4869000-7ffcd486b000 [8 KiB]   r-xp 00000000 00:00 0                [vdso]

Vidíme namapovaný kód programu a přilinkovaných knihoven (libc). Dále vidíme heap, anonymní alokaci, stack a VDSO.

Konečně ASan

Vytvořme tedy následující program, který alokuje zadané množství paměti a pak se pokusí číst jiné množství paměti:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
  // první parametr = kolik bajtů alokovat
  char * a = calloc(atoi(argv[1]), 1);

  // druhý parametr = kolik bajtů přečíst
  for(int i = 0; i<atoi(argv[2]); i++) {
    printf("%i : %02X\n", i, a[i]);
  }
}

$ gcc -g -Og asan3.c -o asan3
$ ./asan3 16 40
0 : 00
[...]
38 : 32
39 : 0A

Přečetli jsme tedy data, která nám nepatřila, a nikdo si toho nevšiml. Na mém systému mi program crashne až na 134496. bajtu (což odpovídá výše zmíněné defaultní velikosti haldy 132 KiB) - teprve pak se to dostane do nenamapované oblasti za brk, dojde k page faultu a kernel zjistí že v tomto místě nemáme co dělat. Sanitizér zapneme jednoduchým přidáním parametru gcc. V některých případech se pak musela výsledná binárka spouštět s LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/10/libasan.so.

$ gcc -g -Og asan3.c -o asan3 -fsanitize=address
$ ./asan3 16 40
[...]
15 : 00
=================================================================
==861648==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000020 at pc 0x5570bc26c26a bp 0x7ffe6f1cc7a0 sp 0x7ffe6f1cc798
READ of size 1 at 0x602000000020 thread T0
    #0 0x5570bc26c269 in main /home/jenda/tmp/smrst-2018/asan3.c:10
    #1 0x7f21239acd09 in __libc_start_main ../csu/libc-start.c:308
    #2 0x5570bc26c0f9 in _start (/home/jenda/tmp/smrst-2018/asan3+0x10f9)

0x602000000020 is located 0 bytes to the right of 16-byte region [0x602000000010,0x602000000020)
allocated by thread T0 here:
    #0 0x7f2123bf9987 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x5570bc26c1ef in main /home/jenda/tmp/smrst-2018/asan3.c:6
    #2 0x7ffe6f1cd276  ([stack]+0x20276)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/jenda/tmp/smrst-2018/asan3.c:10 in main
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==861648==ABORTING

Přístup hned na další bajt (po alokovaném 15.) byl okamžitě odhalen. A díky tomu, že máme debug symboly, to rovnou vypsalo, na jakém řádku se to stalo a kde byla závadná paměť alokována.

Pro zajímavost k tomu, jak to funguje a co znamenají ta fa fa fa. Pokud se podíváte třeba do htopu zatímco program s asanem běží, tak zjistíte, že má ve sloupečku VIRT 20 TB paměti. Ale to je v pohodě, tu má jenom namapovanou a fyzicky se nepoužívá -- nejspíš to používá Copy on Write, kdy všechno ukazuje na jednu stránku, a až v okamžiku, kdy je v ní potřeba něco změnit, se stránka zduplikuje a změna se udělá v tomto duplikátu. Funguje to tak, že se vytvoří takovéto velké pole, a každý bajt v něm odpovídá 8 bajtům paměti programu. Začíná se s tím, že je celé pole popsané FA, a když alokuji paměť, tak se příslušná místa v něm vynulují. A ty kontroly, o kterých jsem psal celou dobu výše, spočítají v tom, že se koukne do tohoto pole, jestli tam je nula - a to je samozřejmě velmi rychlá operace. A v tomto reportu když jsme crashli nám asan ukazuje, že jsme si sáhli na adresu, které v poli odpovídá FA.

Z uvedeného popisu je vidět, že to krásně odchytí přístupy pár bajtů mimo, ale pokud máte dva objekty za sebou a z toho prvního uděláte přístup o hodně dopředu tak, že se trefíte do toho druhého, tak to to neodchytí. Pravděpodobnost, že se tohle stane, to snižuje tím, že to mezi objekty vkládá padding, aby nebyly blízko za sebou.

Další tipy k používání sanitizeru:

Perf

Další užitečný nástroj je perf. Řekne nám, kde se v našem programu tráví nejvíce času. Funguje to tak, že to spustí program, nechá ho chvilku běžet, pak ho zastaví a podívá se, jaká instrukce se právě vykonává. Tohle udělá mnohokrát a pak se vypíše statistika, kde se program nacházel nejčastěji a tedy tyto kousky asi trvají nejdéle. Procesory naštěstí obsahují hardwarovou podporu pro performance counters, takže se to přerušování programu nedělá takhle nevhodně softwarově, ale procesor přímo někam ukládá tuto diagnostiku. Kromě základního „kde se program jak často nacházel“ různé procesory podporují i jiné statistiky (zadejte "perf list", vypíše schopnosti vašeho procesoru), například „kde docházelo k cache missům L1 cache“. Na některých low-endových procesorech se tomu musí občas trochu pomoct.

Základní použití perfu

Je potřeba mít program zkompilovaný s debug symboly (gcc ... -g). Pak pustíme perf record náš_program. Pokud to běží dlouho, můžeme to po chvíli killnout Ctrl+C, pro základní statistiku stačí třeba sekunda běhu. Toto vyrobí soubor perf.data. Obsah souboru zobrazíme pomocí perf report. Zobrazí se textové rozhraní, kde můžeme kód procházet, a zobrazuje se disassembly proložené zdrojákem a procenta kolik času se kde trávilo.

Udávané hotspoty můžou být o pár instrukcí špatně - z důvodu vykonávání více instrukcí současně a out-of-order execution v současných procesorech se může stát, že náročná instrukce je někde předtím a perf zobrazí až čekání na její výsledek. To stejné s čekáním na přístup do paměti.

Debug symboly systémových knihoven

Pokud budete profilovat program, který tráví většinu času v cizích knihovnách (v mém případě je teď například populární FFTW), tak pokud nemáte ke knihovnám nainstalované debug symboly, tak perf zobrazí jenom náhodné adresy. Například na Debianu je potřeba doinstalovat dbgsym balíčky ze speciálního repozitáře.

Misc.

Parametry gcc

Postupně jsem dokonvergoval k následujícím flagům gcc, které považuji za užitečné. Jsou to rozšířená varování a nějaké drobnosti. Najděte si v dokumentaci (dokumentace varování) co dělají, já už si to taky nepamatuju.

-fno-common
-fno-omit-frame-pointer
-std=gnu11
-Wall
-Wextra
-Wduplicated-cond
-Wduplicated-branches
-Wlogical-op
-Wrestrict
-Wnull-dereference
-Wjump-misses-init
-Wdouble-promotion
-Wshadow
-Wformat=2
-pedantic

Multithread a díra

Tady je zajímavý příklad nečekané díry způsobené race condition.

Bug v Go

Tady je krásný writeup o hledání občasného náhodného pádu Go.

Nezarovnaný přístup - problémy i na x86

Tady je ukázka, že podmínku zarovnaného přístupu není možné v C ignorovat ani na architekturách, kde to procesor hardwarově ošetří (byť za cenu zpomalení), protože se to stejně náhodně vysype.

NaCl

Výše jsme řešili, že nejde automaticky předělávat kód protože se (minimálně na x86) může skákat náhodně někam doprostřed a instrukce jsou různě dlouhé a nezačínají zarovnaně. Native Client je omezení na jumpy zarovnané na 32 bajtů, díky čemuž se pak kód dá automaticky skenovat na přítomnost zakázaných instrukcí. Používalo se to pro spouštění nativního kódu v javascriptových browserových aplikacích než přišel WebAssembly.

       

Hodnocení: 100 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Vložit další komentář

Člověk z Horní Dolní avatar 4.9. 17:57 Člověk z Horní Dolní | blog: blbeczhornidolni
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Měli byste tedy jakoby se sanitizérem překompilovat celý runtime.
Ha, teď jsi se prozradil, už vím kdo je Gréta.
Jendа avatar 4.9. 18:05 Jendа | skóre: 77 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Víte o tom, že losování Sportky je ve skutečnosti česká number station?
Člověk z Horní Dolní avatar 4.9. 19:06 Člověk z Horní Dolní | blog: blbeczhornidolni
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Haha :D
Gréta avatar 6.9. 12:27 Gréta | skóre: 32 | blog: Grétin blogísek | Stockholm
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování

jestli jako myslíš že tvuj vodhad je jakoby víc lepšejší než bystroušákovy statistický analízy komentů :D

bin ladin 👳🏾💣: 'bidena nezabíjejte je neschopnej'wie spát ist es?? 🛏 ⌚
Člověk z Horní Dolní avatar 6.9. 21:55 Člověk z Horní Dolní | blog: blbeczhornidolni
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Zas bych ty prekombinovane statisticke metody neprecenoval, selsky rozum ma casto lepsi vysledky :D
7.9. 17:07 _
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Jenda je Bluebear, Greta je Amiga.
xxxs avatar 7.9. 17:53 xxxs | skóre: 22 | blog: vetvicky
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
amiga je zaujimavy typek, ale ak sa mu podarilo opravit mozog natolko, aby mohol hrat gretu, tak ten recept bude mat hodnotu gdp eu.
8.9. 18:13 Petr
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Greta ma mozog? Vzdyt je uplne vymastena.
Člověk z Horní Dolní avatar 8.9. 23:21 Člověk z Horní Dolní | blog: blbeczhornidolni
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
V diskuzi o globalnim oteplovani se docela ztrapnila neznalosti te problematiky.
8.9. 23:31 Grétina zapařená pipina
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Považovat odlišný názor za neznalost je dost omezené.
Gréta avatar 10.9. 12:17 Gréta | skóre: 32 | blog: Grétin blogísek | Stockholm
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování

si myslim že to nemá smysl to s nim dál řešit protože už je jakoby rozhodnutej čemu chce věřit :D ho ale teda jako dorazim když mě takle provokuješ :D :D ;D ;D

bin ladin 👳🏾💣: 'bidena nezabíjejte je neschopnej'wie spát ist es?? 🛏 ⌚
7.9. 20:59 _
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Gréta je kučera, začalo to jako pravičácká agenda karikatury ekologického liberála, ale dlouho mu to nevydrželo, a už najednou hlásají totožné názory a řeší stejné věci - už nejen politiku, ale najednou i FOSS a licence. Hlavně na sebe nereagují a málokdy jsou ve stejném vlákně. A zejména - koho než frantíka zajímají ty jeho podělaný relační roury? Tohle se blbě mění když si někdo zapomene změnit účet ;-) Q.E.D.
Gréta avatar 10.9. 12:19 Gréta | skóre: 32 | blog: Grétin blogísek | Stockholm
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování

A zejména - koho než frantíka zajímají ty jeho podělaný relační roury

ttttsssss radar mě zajímá uplně stejně hele :O :O :D :D :D :D ;D ;D

bin ladin 👳🏾💣: 'bidena nezabíjejte je neschopnej'wie spát ist es?? 🛏 ⌚
6.9. 19:15 Jan Hus
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Gréta nepíše takovou czenglish jako s. Jenda.
4.9. 18:57 billgates | skóre: 25
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Zaujimave. Doteraz som pouzival -Wall -Wextra -Wshadow -fstack-protector-strong a na sanitizaciu -fsanitize=address -fsanitize=undefined -fsanitize=leak -fno-omit-frame-pointer. Tie niektore dalsie warningove parametre vyzeraju uzitocne.
4.9. 19:52 neprogramátor
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Když přijde soudný den budou počítače programovat nás, ne my je. A jako první budou na řadě programátoři.
4.9. 20:33 Eich
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Nastesti to bude az v dobe kdy bude dominovat vsude JavaScript.
4.9. 23:16 plostenka
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Osobně jsem ale tohle nikdy nepotřeboval řešit, defaultní malloc byl vždycky good enough. Setkali jste se někdy s případem, kdy by bylo potřeba alokátor ladit?
Presne kvuli zpomaleni kvuli (kontrolam na) race condition jsme museli naalokovat velkou pamet pro kazdy thread separatne a implementovat v asm vlastni alokator nad timhle vyhrazenym adresnim prostorem.
Heron avatar 5.9. 00:15 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Tady je krásný writeup o hledání občasného náhodného pádu Go.
Skvělý článek, díky.

Trochu mi to (v malém) připomíná moje začátky s golangem, kdy jsem skoro hned narazil na chybu při procházení adresářů na sambě, kdy to vracelo různý počet nalezených souborů při každém dalším volání. Golang všechny relevantní syscally posílá s SA_RESTART a nikdy by se neměl vracet EINTR. Jenže se vrací. Ovladač pro sambu prostě ignoruje SA_RESTART a nechá to udělat klienta (potom se zjistilo, že je to ještě navíc ovlivněno velikostí bufferu) a nakonec vydali nové verze knihovních funkcí, ale toto řešení se mi nelíbí, protože to zakrývá původní a stále existujicí chybu v sambě. (Nehledě na to, že workaround je poměrně snadný a podle mě je mnohem lepší v kódu když už tak použít workaround na místo knihovní funkce, která zakrývá nějaký problém na systémové vrstvě. -- Potom se každý drží knihovní funkce a nechce nic slyšet o tom, že pod tím je to ale stále špatně, takže je lepší toto místo explicitně označit.) Sice na kritických místech používám NFS, kde se to neděje, ale i tak mě překvapuje, že takto často používaný způsob sdílení má tyto problémy.
Heron avatar 5.9. 00:19 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Například se mi zdá, že si každý druhý píše vlastní alokátor
Jo, bavil jsem se s člověkem, který si běžně píše (C++) několik vlastních alokátorů v jednom programu pro různé účely, protože jinak to nejde a ten single thread program by jinak nezvládal zátěž (což je možná pravda, ale současně to extrémně zkomplikuje přepis na multithread nebo jiné rozsekání).
5.9. 15:55 jbv
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Obecne je problem v tom ze vetsina C/C++ progrmatoru jsou hodne spatni. Nejcasteji jsou to samouci, hlavne z 90tek. Dneska uz nastesti C/C++ neni sexy, tak z mladsi generace v nem programuji prkticky jen ti, ktere to opravdu zajima. Je to pekne videt i na nazoru hlavne C komunity na rust, protoze tihle programatori nejsou schopni napsat netrivialni rust kod, co se zkompiluje.
Člověk z Horní Dolní avatar 6.9. 22:35 Člověk z Horní Dolní | blog: blbeczhornidolni
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Jde taky o to, ze C++ je extremne slozity jazyk. Ja jsem driv C++ nesnasel, ale v poslednich asi 5 letech jsem si ho docela oblibil, i kdyz moc v nem nedelam, urcite nejsem zadny odbornik. Od C++11 ten jazyk udelal obrovsky pokrok v UX, s nadsazkou to je ted jako Python, ale rychlejsi. Tu rychlost a moznost low-level optimalizace miluju, je to takovy pocit svobody, ze me ten jazyk nijak neomezuje.
5.9. 02:54 kvr
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Pěkný článek. Ještě bych zmínil Electric Fence Malloc, který před nebo za alokovanou pamětí rezervoval nepřístupnou stránku, která při buffer overflow/underflow vedla k okamžitému pádu.
a pokud vlákna hodně alokují, tak je toto bottleneck. Alokátor tohle detekuje a rozdělí haldu na více částí, pro každé vlákno samostatně.

Osobně jsem ale tohle nikdy nepotřeboval řešit, defaultní malloc byl vždycky good enough. Setkali jste se někdy s případem, kdy by bylo potřeba alokátor ladit?
Kdysi dávno, tak před 15ti lety. Defakto webserver v C++, samozřejmě spousta requestů se zpracovávala paralelně a v té chvíli byl i na tehdy snad jenom čtyřjádru existující glibc malloc šílený bottleneck. Takže v té době jsem si i já napsal vlastní alokátor, kromě per-thread cache a rozdělení podle podobné velikosti bloků uměl i některé debug features popsané v článku, včetně detekce memory leaks, myslím, že i inaccessible stránky na začátku či na konci apod. Později s běžně dostupnými multicore procesory a multithreading se začaly používat podobné alokátory přes LD_PRELOAD a mám pocit, že i glibc má dnes něco podobného (nebo dokonce přímo převzali jemalloc?)...

Tady je ukázka, že podmínku zarovnaného přístupu není možné v C ignorovat ani na architekturách, kde to procesor hardwarově ošetří (byť za cenu zpomalení), protože se to stejně náhodně vysype.
Na tohle jsem taky narazil, když jsem experimentoval s AVX-512. Alignment __mm512 sice funguje v rámci struktury, ale stack je zarovnaný jenom 16-bytes. Takže SSE v pohodě jede (__mm128), ale AVX-2 a AVX-512 může mít základní adresu struktury nezarovnanou a tedy i prvky uvnitř. Nejsem si jistý, jak to má malloc bez options, myslím, že taky musí vracet 16-byte, ale jestli i výš, nevím.

Jinak, procesor x86_64 to právě hardwarově neošetří - na load/store se můžou použít instrukce, které vyžadují alignment (MOVAPD apod), pokud to kompilátor (mylně, viz výše) ví a to potom vede k pádům. Měly být původně rychlejší, ale myslím, že dneska je to skoro jedno...

Kromě toho bych řekl, že instrukce na unaligned load/store nebudou atomické (ne ve smyslu compare-and-swap, ale v jednoduchém smyslu konzistence, že se přepíše či nahraje celá hodnota najednou bez přerušení jiným CPU).
5.9. 16:08 jbv
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Vlastni akolator neni uplne casta vec, ale da se pro nej najit pomerne dost use casu. Obecne bych rekl, ze vsechny pouziti, kde je velky tlak na rychlost alokace/dealokace a zaroven je pomerne predvidatelne pouziti alokatoru. Typicky priklad jsou gc, transakce, databaze apod. Ale je pravda, ze to nejsou veci co lidi pisou denne.
xkucf03 avatar 5.9. 16:11 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Typicky priklad jsou gc
Existuje něco jiného než Boehm? Myslím veřejně dostupné.
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
xkucf03 avatar 5.9. 09:23 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování

Pěkný článek, díky.

Nejvíc používám ASan. Bez něj by programování v C/C++ byla procházka minovým polem. S ním je to relativně v pohodě a řeší velkou část nebezpečnosti těchto jazyků.

Ještě bych doporučil použití fuzzeru, který taky může odhalit nějaké ty chyby – krmí program náhodnými/chybnými daty a zjišťuje, zda program spadne, zacyklí se atd. Může odhalit např. chybu typu, že ve vstupních datech je uvedena délka následujícího pole (TLV), parser si pro tuto délku alokuje paměť, aniž by předem ověřil, že tolik dat na vstupu vůbec je (tzn. chybnými vstupními daty lze program donutit, aby si alokoval zbytečně gigabajty paměti a nebo spadl). Ale zrovna tohle je chyba, které jsem si byl vědom a fuzzerem jsem si ji jen potvrdil.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
5.9. 10:04 trekker.dk | skóre: 71
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
například přetečení intu, ale to lidi často řeší kompilací s -fwrapv
Pěkné, využil jsem. Ušetřilo mi to v programu asi tak 4 instrukce. :-)
Quando omni flunkus moritati
5.9. 12:27 mln
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Ma niekto tip na sanitiser (alebo podobne nastroje na buffer owerflow, memory leak, pretecenie premennych) ktory by fungoval na mikrokntroleroch ? SMT32, MSP430, TMS320 atd ? Na mikrokontroleroch sa C jazyku clovek nevyhne :/

Chcel by som sa dožiť dna ked bude C jazyk mat v kompilatore volbu ktora zapne kontroly na owerflow, memory leak, pretecenie premennych. Mikrokontrolery su uz dosť rychle, podme písať bezpečný program - tí ktorí o to maju zaujem (nikomu nevnucujem).
xkucf03 avatar 5.9. 14:15 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování

Nestačilo by ten kritický kód napsat jako knihovnu, kterou by šlo přeložit jak pro MCU, tak pro x86? (jasně, tam, kde pracuji s I/O to bude vázané na to MCU a musel bych si to nějak mockovat/simulovat, ale svoje vlastní algoritmy můžu klidně napsat jako .h soubor, který bude použitelný jako uvnitř firmwaru tak na desktopu).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
5.9. 23:06 dumblob | skóre: 10 | blog: dumblog
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Nezarovnaný přístup - problémy i na x86 Tady je ukázka, že podmínku zarovnaného přístupu není možné v C ignorovat ani na architekturách, kde to procesor hardwarově ošetří (byť za cenu zpomalení), protože se to stejně náhodně vysype.
Někdy ale zarovnaný přístup nechceme, protože nezarovnaný bývá více než 2x rychlejší.
Jendа avatar 6.9. 00:27 Jendа | skóre: 77 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
To vypadá jako příklad na omezenou asociativitu cache. Cacheline je 64B (možná na nejnovějších počítačích dokonce 128B), to je úplně něco jiného než o čem se píše v článku (nativní céčkové datové typy - což končí u 8B typů - zarovnané na svoji velikost).
Víte o tom, že losování Sportky je ve skutečnosti česká number station?
6.9. 09:40 dumblob | skóre: 10 | blog: dumblog
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování
Ano, špatně jsem to přečetl (kolikrát už jsem si říkal, že večer, kdy jsem na pokraji ztráty vědomí vlivem unavenosti, nesmím přispívat do diskuzí).

Alespoň někdo kdo hledá něco o zarovnání, najde i širší pojetí :-)
Gréta avatar 6.9. 12:23 Gréta | skóre: 32 | blog: Grétin blogísek | Stockholm
Rozbalit Rozbalit vše Re: Programování v C: sanitizer, profilování

supr satanizér :D ;D

bin ladin 👳🏾💣: 'bidena nezabíjejte je neschopnej'wie spát ist es?? 🛏 ⌚

Založit nové vláknoNahoru

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.