proba.c, malloc(), memset(), "Killed" ...

23 отговора 711 прегледа
#1

proba.c, malloc(), memset(), "Killed" ...

мдаа

пускам си аз един цикъл, в който се маллоц()ва памет и вместо маллоц() да ми върне НУЛЛ и да разбера, че памет нема - програмката мре със съобщение (от киллъра й, подозирам) Killed! и толкоз! нема лабаво! защо умря не се разбира от тва Killed.

като задам малко по-малко да маллоц()не, колкото да успее, същата дивотия (т.е. Killed) се получава по някое време докато мемсет()вам успешно маллоц()натата памет (предполагах, че ще стане така, ама реших да се уверя).

=>
1. що така?
2. и като е така кво да праа, а (освен да го духам, примерно)?

Satan`s Defloration Incorporated
Отговор
в отговор на ЛУД ПPЪЧ #2

Бях чувал по едно време

че начинът да разбереш колко памет имаш не е с malloc докато ти върне NULL. Доколкото си спомням, Linux има агресивна стратегия за раздаване на памет и не ти гарантира 100%, че наистина malloc() ще ти върне фрагмент, който можеш да използваш _веднага_.

И точно в такава ситуация попадаш ти. Killed се случва, защото ядрото ти праща сигнал, който обаче ти не прехващаш; нещо като exception, който означава, че нещо не е съвсем в ред - в случая паметта. Не знам кой точно е сигнала, но можеш лесно да го разбереш, като си пуснеш програмата в ddd, например - той ще ти каже killed with signal колкото-е-там.

А ти защо искаш да разбереш колко памет имаш? Това при всички случаи е непостоянна информация - дори да установиш, че в момента имаш да кажем 100mb, точно преди да ги заемеш може да стане превключване към друг процес, който да хапне 10 от тях ...

Понякога седя и си мисля, а понякога само си седя ...
Отговор
в отговор на Masklin #3

аз пък съм ***чел*** едно време

в една книга за програмиране в unix (за линукс не стана дума изобщо), че маллоц() не е това, което е - т.е. 1:1 на това, което ти спомена. това обаче не означава, че поведението на кърнъла трябва да е ЧАК ТОЛКОВА непочтително към юзърска програма.

целта да направя подобна проба беше съвсем друга. това, което се научих е чисто страничен ефект, при това неприятен:

1. хич не ми дреме колко памет имам - ако няма => маллоц() трябва да е == НУЛЛ !!!
(за справка - ман маллоц)
НУКЪДЕ в мана не се казва, че програмата ще умре ако няма памет! НОРМАЛНОТО е да отговори с НУЛЛ и аз да му бера грижа как да се оправя без допълнителната памет, която съм заявил. Щото в някои случаи и с по-малко памет ще се свърши работата, ако не те изхвърлят с ритници.

2. ако маллоц() успее => при опит за работа с тази памет аз ТРЯБВА да успея, макар и с некаф блоцкинг примерно.


в случая същността на питането ми е:
* КАК да си заявя памет, така че да няма Killed, а да има НУЛЛ и да бъде възможно нормално продължение ИЛИ нормално приключване на работата, което трябва да избера АЗ, а не кърнълна или който и да е друг, защото не може друг да знае дали мога или не да работя и без тази памет, която съм заявил.


в случая сигналите не ме устройват твърде. имах преди време проблеми със СИГ11 и така никой не можа да ми отговори как да разбера в кой от тхреадовете ми е проблема...



??????

Satan`s Defloration Incorporated
Отговор
в отговор на ЛУД ПPЪЧ #4

Набарах го

Точно в man malloc:

# echo 2 > /proc/sys/vm/overcommit_memory

И си готов.

Ето ти го и целия коментар:
BUGS

By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. This is a really bad bug. In case it turns out that the system is out of memory, one or more processes will be killed by the infamous OOM killer. In case Linux is employed under circumstances where it would be less desirable to suddenly lose some randomly picked processes, and moreover the kernel version is sufficiently recent, one can switch off this overcommitting behavior using a command like
# echo 2 > /proc/sys/vm/overcommit_memory
See also the kernel Documentation directory, files vm/overcommit-accounting and sysctl/vm.txt.

Понякога седя и си мисля, а понякога само си седя ...
Отговор
в отговор на Masklin #5

danke!!!

мерси много! ще го пробвам довечера.

Satan`s Defloration Incorporated
Отговор
в отговор на Masklin #6

Re: Набарах го

"In case Linux is employed under circumstances where it would be less desirable to suddenly lose some randomly picked processes"

Еее, това кефи :))) Интересно, кога би било 'more desirable' да умре случайно избран процес :)

Отговор
в отговор на Paдo #7

Примерно

в ситуация, в която е невероятно (разбирай много малко вероятно) да ти свърши паметта и предпочиташ производителност. Да кажем - офис десктоп.

Освен това, не е задължително процесът да бъде убит с брадвата - той може да разбере какво се е случило по сигнала и да се спре по що-годе културен начин.

Наистина, не изглежда красиво, но досега на мен никога не ми се е случвало да ми свърши паметта, така че рискът наистина е малък. А човек така или иначе трябва да се оправя със сигналите и спокойно може да се приеме, че свършването на паметта е равносилно на SIGTERM. Достатъчно е да направиш така, че при умирането да не искаш памет и готово.

Понякога седя и си мисля, а понякога само си седя ...
Отговор
в отговор на Paдo #8

Re: overcommit_memory хич не е случайно .

Не знам за вас ама на мен през годините многократно ми се е случвало да се разправям със сървъри на които нещо е изяло всичката памет (разбирай целия RAM плюс Swap)

И в такива случаи утрепването на процеси е МНОГО по-добрия вориант!

Защото без този OOM трепач, който се появи в 2.4 ядрата положението е значително по-плачевно.

Когато паметта се свърши машината просто увисва в небитието. Ако имаш късмет може да видиш безумни стойности на load average от порядъка на 70-90 и то "по принцип" всичко си работи само дето е безкрайно бавно.

Връщането на един PING пакет примерно може да отнеме към 20 минути.

Та без overcommit_memory изходът е САМО ЕДИН а именно да дръпнеш щепсела от контакта .... следва рестартиране, проверка на дискове, оправяне на купища проблеми и т.н.

Определено утрепването на един или повече сървъри е МНОГО по-добрият вариант. В най-лошия случай губиш нещата на този само сървър, но спасяваш машината като цяло

salle.online.bg/sig
Отговор
в отговор на Masklin #9

Re: Примерно

Хм, не ми се вижда културно. Много бих се объркал, ако програма в която не заделям явно памет (примерно използвам std::vector) гърми мистериозно. Поне да ме замери с bad_alloc. А това, че ситуацията е почти невероятна само прави бъга по-трудно откриваем.

Отговор
в отговор на salle #10

Re: overcommit_memory хич не е случайно .

Едно нещо не разбрах - искам памет - ОС-а казва - на, пък после ме утрепва.
Не може ли просто да каже - няма?

Отговор
в отговор на Masklin #11

Re: Примерно

Има само една малка подробност -- в общия случай ООМ killer-a изпраща SIGKILL, а не SIGTERM. SIGKILL не можеш да игнорираш.

Справка: mm/oom_kill.c (__oom_kill_task).

Отговор
в отговор на Masklin #12

проблем 2 сякаш изчезна, но Killed си е Killed...

Значи, флага влияе само върху това заделената памет да си бъде наистина заделена. Ако обаче паметта свърши - нанайци. Killed.

На всичкото отгоре самия стринг Killed така и не го намирам къде е! Търсих в цялото дърво на 2.4.26 и на 2.6.7. В oom_kill.c има друго:


void oom_kill_task(struct task_struct *p)
{
printk(KERN_ERR "Out of Memory: Killed process %d (%s).\n", p->pid, p->comm);

...
...


a не простичкото "Killed".


Другата тайна и загадка, която се появи е, че в .config # CONFIG_OOM_KILLER is not set, и въпреки това не процеса си мре.


Наистина ли няма начин malloc() да връща НУЛЛ???????? Все пак една от линукските идеи беше, че човек трябва да може да си настрои нещоситам както си иска.

Satan`s Defloration Incorporated
Отговор
в отговор на ЛУД ПPЪЧ #13

killed...

според мен го изтърсва bash или който там ти е пуснал програмчето.

А дали малок може да върне 0 - ако се позадълбаеш в него, ще видиш.

remember, there is no fork()
Отговор
в отговор на ЛУД ПPЪЧ #14

Re: проблем 2 сякаш изчезна, но Killed си е Killed...

При мен malloc работи правилно при vm.overcommit_memory=2. С коя версия на ядрото тестваш?

Отговор
в отговор на Яceн #15

Re: killed...

abe сега съм се задълбочил над миене на бебешки задник и прочее...

Satan`s Defloration Incorporated
Отговор
в отговор на l #16

Re: проблем 2 сякаш изчезна, но Killed си е Killed

2.4.26 => Killed независимо дали е 0 или каквото и да е там
2.6.7 => Segmentation fault при достигане на заветните 50%

бтв, от каквото пише доковете се оказва, че поведението на 2.4 трябва да е различно от на 2.6 при 0, 1, 2.

Satan`s Defloration Incorporated
Отговор
в отговор на salle #17

Re: overcommit_memory хич не е случайно .

в случая става дума за компютърчето вкъщи и за момента освен мен няма кой да псува ако започне да се мотае от недостиг на памет.

Satan`s Defloration Incorporated
Отговор
в отговор на ЛУД ПPЪЧ #18

Re: проблем 2 сякаш изчезна, но Killed си е Killed

При мен на 2.6.5 следната програмка:


int main() {
while (1) {
void *p = malloc(10 * 1024 * 1024);
if (!p) {
printf("null\n");
return 0;
}
printf(".");
fflush(stdout);
memset(p, 0, 10 * 1024 * 1024);
}
}


отпечатва 30-ина точки и накрая null без никакви segfaults.

Отговор
в отговор на l #19

Re: проблем 2 сякаш изчезна, но Killed си е Killed

При мен на 2.6.7
..............................................................Killed
а при
# echo 2 > /proc/sys/vm/overcommit_memory

.................................................null

Отговор
в отговор на ЛУД ПPЪЧ #20

Re: проблем 2 сякаш изчезна, но Killed си е Killed

# CONFIG_OOM_KILLER

не изключва "трепача" напълно само му променя навиците.

"This option selects the kernel behaviour during total out of memory condition. The default behaviour is to, as soon as no freeable memory and no swap space are available, kill the task which tries to allocate memory. The default behaviour is very reliable. If you select this option, as soon as no freeable memory is available, the kernel will try to select the 'best' task to be killed."


т.е. без тази опция се трепе последния процес, който иска памет а със нея "най-добрия" за целта. По моите наблюдения това е този, който е захапал най-много памет.

salle.online.bg/sig
Отговор