Segmentation fault

Segmentation fault
« kdy: 09. 03. 2020, 08:19:08 »
Ahoj chtěl bych se zeptat na problém se kterým si nevím rady. Napsal jsem si TCP server v Cčku. Občas se mi stane a je to čistě náhodný proces, že mi server spadne. Někdy se to nestane týdny a někdy se to děje několikrát denně. Nebyl jsem schopen dostat z návratové chyby víc než "Segmentation fault" tak jsem zpusil použít GDB. Díky němu mám lepší výpis toho co se tam děje:
Kód: [Vybrat]
Thread 2 "main" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff49e8700 (LWP 30711)]
_int_malloc (av=av@entry=0x7ffff0000020, bytes=bytes@entry=128)
    at malloc.c:3779
3779    malloc.c: No such file or directory.

Z tohodle také moc moudrej nejsem, protože osobně se funkci malloc vyhejbám. Používám jí velice zřídka a snažím se co nejdůsledněji kontrolovat její použití. Kód dokonce spadne v momentě, kdy ani nejsem v bloku jejího volání. Napadá mě tedy jediné a to je, že to způsobuje nějaká knihovna třetí strany. Používám pro řízení filedescriptorů epool což mi zde na fóru někdo poradil a také SQLlite.

Neřešil jste někdo něco podobného nebo nemáte nápad jak se tohoto problému zbavit?
Dík.



Re:Segmentation fault
« Odpověď #1 kdy: 09. 03. 2020, 09:53:49 »
Neporadim ti ako (spytaj sa google, mam pocit ze w ako where) ale potrebujes call stack, cize kto volal malloc.
Mozno to nebude ta funkcia co priamo volala malloc, ale niekolko nad tym. Z call stacku by si mohol vidiet, co je to za thread, a cez ake kniznice to islo. Ked sa nebudes vediet pohnut, napis sem cely call stack.

Re:Segmentation fault
« Odpověď #2 kdy: 09. 03. 2020, 10:14:29 »
Užitečná rada: Zkus si to pustit ve Valgrindu, mohl by ti ukázat, kde špatně zacházíš s pamětí nebo máš nějaké race conditions.
Neužitečná rada: Přepiš to do Rustu :-)

Re:Segmentation fault
« Odpověď #3 kdy: 09. 03. 2020, 10:22:23 »
nedošla paměť? když malloc teda selhal...

další možnosti řešení:

pusť v tom shellu, kde to pouštíš

Kód: [Vybrat]
ulimit -c unlimited
pak by to místo

Kód: [Vybrat]
Segmentation fault
mělo napsat

Kód: [Vybrat]
Segmentation fault (core dumped)
objeví se ti tam soubor "core" a ty můžeš pustit

Kód: [Vybrat]
gdb název_programu core
abys viděl, v jakém stavu to spadlo

tecka

  • ***
  • 145
    • Zobrazit profil
    • E-mail
Re:Segmentation fault
« Odpověď #4 kdy: 09. 03. 2020, 10:24:08 »
Malloc nepadá sám o sobě, ale když pracuje s pamětí, kterou rozvrtal jiný kód. Může to být poblíž, ale i někde úplně jinde.

Můžeš to zkusit zkompilovat s ASAN nebo spustit ve Valgrindu. To by mělo (mohlo) detekovat problém hned, když k němu dojde.

Z toho, jak jsi měl potřebu zmínit svoji opatrnost, úplně čiší, že s pamětí pracovat neumíš. Tak nepiš v Céčku.


Re:Segmentation fault
« Odpověď #5 kdy: 09. 03. 2020, 11:13:28 »
Z toho, jak jsi měl potřebu zmínit svoji opatrnost, úplně čiší, že s pamětí pracovat neumíš. Tak nepiš v Céčku.

Můžu se autora zeptat z čeho v mém dotazu vyplývá to, že neumím pracovat z pamětí?

Za komentáře díky. Zkusím rady aplikovat. Co se týče toho komentu
Citace
nedošla paměť? když malloc teda selhal...
tím si nejsem úplně jistej. Mám vyzkoušeno, že pokud dojde paměť, tak se zhroutí celej systém a dojde k jeho restartu. To se mi nikdy nestalo.

Jinak ten server mi běží už pár let a nikdy se mi to nestávalo. Nedávno jsem ale změnil princip řízení filedescriptorů ze select na epoll. To byl poměrně velký zásah a od té doby jsem začal mít tyto problémy. Furt mě to tak trochu směřuje tam.

Doufám, že Vám to všem jde líp než mě :-)

Re:Segmentation fault
« Odpověď #6 kdy: 09. 03. 2020, 12:18:12 »
Pokud malloc() selže kvůli nedostatku paměti, tak nezpůsobí segfault, ale zdvořile vrátí chybový návratový kód.

Říkáte, že to běhalo pár let - na jakém to běží hardwaru? Jestli třeba nevadne hardware. S tou změnou ze select() na epoll() to může být jenom nešťastná náhodná shoda v čase.

Google mi našel dvě žertovná povídání, ale myslím, že to Váš problém neřeší.

Ono způsobů jak někde sáhnout mimo alokovaný kus paměti je spousta - a v mém případě bývá problém obvykle v mém vlastním kódu :-(

Re:Segmentation fault
« Odpověď #7 kdy: 09. 03. 2020, 13:15:06 »
1. Call Stack, at vidite, jestli segmentation fault zpusobil vas kod, nebo nejaka knihovna, a zda k segfaultu vedla nejaka prima pricina. Samozrejme na segfault mohlo byt zadelano uz davno pred tim, napr. zapisem spatneho pointeru, nezadoucim prepisem obsahu jiz alokovane a pouzite pameti, dealokace a nasledne pouziti pameti, nebo dokonce poskozeni servisnich informaci buketu mallocu atd. atd. Proto je potreba i
2. Mrknout, co je na malloc.c:3779, a co mohlo byt pricinou toho, ze to tam spadlo.

m1x

Re:Segmentation fault
« Odpověď #8 kdy: 10. 03. 2020, 00:56:28 »
Podívat se na ten malloc.c:3779, jen pro hrubou představu. Moc se v tom nešťourat.

Pak pustit pod Valgrindem.


Nejspíš někdo zapsal něco do paměťového místa které mu nepatřilo. Třeba: použití pointeru nebo objektu po uvolnění paměti, zápis za konec pole nebo za konec alokované paměti, použití neinicializované proměnné, použití čehokoliv ve více vláknech naráz bez uzamčení, interní cache nějakého pointeru v nějaké knihovně, globální proměnná ve vícevláknovém kódu, knihovna která není multithread-safe, ... cokoliv. Fantazii se meze nekladou. Typicky něco nevinného ale nešikovně použitého. Vznikne chyba, která se třeba nikdy neprojeví. Pak někdo program drobně upraví a chyba která byla spoustu let neviditelná najednou začne prudit. Naprosto nahodile a nereprodukovatelně.

Takovéhle chyby se obvykle projevují mnohem později a úplně jinde než kde byla příčina. Calkstack tedy nemusí dát relevantní informaci. Valgrind by měl najít všechny nedostatky  :P

_Jenda

  • *****
  • 1 591
    • Zobrazit profil
    • https://jenda.hrach.eu/
    • E-mail
Re:Segmentation fault
« Odpověď #9 kdy: 10. 03. 2020, 01:25:34 »
Případně jako alternativu k Valgrindu můžeš zkompilovat s -fsanitize=address (možná na starších překladačích ještě -lasan). Výhoda: je to _řádově_ rychlejší. Nevýhoda: Odhalí to jiné chyby než Valgrind a může se stát, že tomu nějaká chyba unikne (ale na to se musíš hodně snažit nebo mít fakt smůlu).

A samozřejmě bych kompiloval s -g -Og aby tam bylo v gdb dobře vidět věci.

_Jenda

  • *****
  • 1 591
    • Zobrazit profil
    • https://jenda.hrach.eu/
    • E-mail
Re:Segmentation fault
« Odpověď #10 kdy: 10. 03. 2020, 01:28:16 »
nedošla paměť? když malloc teda selhal...
Podle mě při dojití paměti malloc vrátí NULL a uvidíš jeho dereferenci při prvním použití (pokud to nekontroluješ). Btw. neumí malloc selhat nějak „hezky“ (zavolá abort, vypíše barevné hlášky…)? Já když jsem tohle řešil, tak jsem si napsal funkci xalloc, což zavolalo malloc a zkontrolovalo na NULL. A totéž realloc. Je to nesystémové a opruz.

alex6bbc

  • *****
  • 1 544
    • Zobrazit profil
    • E-mail
Re:Segmentation fault
« Odpověď #11 kdy: 10. 03. 2020, 07:13:21 »
nebo pokud je promenna vytvorena v main tak malloc nahrad normalni promennou na stacku
a kdyz to padne tak to neni mallocem.

iko

  • ***
  • 148
    • Zobrazit profil
    • E-mail
Re:Segmentation fault
« Odpověď #12 kdy: 10. 03. 2020, 07:58:33 »
mozno keby si sem dal zdrojovy kod tak pozreme a vidime chybu

Re:Segmentation fault
« Odpověď #13 kdy: 21. 03. 2020, 09:40:32 »
Chyba práce s pamětí může znamenat, že zapisujete do místa, na které zapisovat nemáte. Pokud máte štěští, nikdo jiný to míšto v paměti nepoužívá a bude to fungovat. Pokud máte smůlu, místo v paměti může používat i někdo jiný. To ale může vést ke kolizím, které nastanou poněkud později a v jiné části kódu, než kde je chyba. A na chování mohou mít vliv i víceméně nesouvisející změny, jako změna ze select na epoll – začne se používat jiný kus paměti, a najednou začne docházet ke kolizi třeba i ve funkci, která je na tom nevinně.

Valgrind toho umí najít spoustu, i když úplně neprůstřelný není. Ale takovéto nástroje jsou dobrým začátkem. Umí detekovat chyby často mnohem dříve, než by se reálně projevily. Často přímo na místě chyby.

Opatrnost na malloc – zase se to nesmí přehnat. Viděl jsem i kód, který slokoval data na stacku a předal pointer na ně. Pokud se ten předaný pointer používá i po návratu z funkce, která ho předala, je to problém. Bylo by věštěním z křišťálové koule, jestli je to Váš případ, ale může být.

Re:Segmentation fault
« Odpověď #14 kdy: 21. 03. 2020, 11:34:12 »
Pokud máte smůlu, místo v paměti může používat i někdo jiný.

To je spíš štěstí, protože se na to přijde. Ale jinak souhlas.