nanosleep() syscall се събужда с грешка в шината?

Гледам дъмп на ядрото от вградено MIPS Linux приложение. GDB отчита SIGBUS и нишката, обработваща сигнала, изглежда се намира в системно повикване за nanosleep - кодът от по-високо ниво основно се нарича sleep(verylongtime); Ако приемем, че друг процес не е изпратил този сигнал до приложението, какво би причинило тази нишка да се събуди по този начин? Нещо вътре в ядрото генерирало ли е грешката на шината? Може ли да е причинено от друга нишка, която блокира такива сигнали? (моля, извинете за наивността тук, не съм много запознат със сигналите). Благодаря.


person gimmeamilk    schedule 26.09.2011    source източник
comment
Имаше ли нещо на dmesg? Имаше ли други теми, работещи по това време? Имаше ли инсталиран манипулатор на сигнала SIGBUS в тази нишка?   -  person bdonlan    schedule 26.09.2011
comment
dmesg log не беше заловен за съжаление. Около 30 нишки. Първоначално нямаше манипулатор на SIGBUS. Добавих такъв, за да диагностицирам този проблем, и si_pid съдържа нещо, което изглежда като адрес в .text на програмата (!). Има ли сценарий, при който това ще се случи? Направих някои експерименти и обикновено si_pid правилно държи pid на процеса на изпращане или нула, ако е генериран от този процес.   -  person gimmeamilk    schedule 27.09.2011


Отговори (1)


Ако si_pid е зададено на адрес, това означава, че вашият SIGBUS е повдигнат от грешка в програмата. Обикновено това се случва, когато ядрото се опита да премести някакъв програмен текст, но срещне IO грешка. Препълването на стека също може да предизвика това.

Виждате si_pid зададен на адрес, защото si_pid е част от обединение и е псевдоним с si_address. По-специално, si_pid е валидно само ако si_code == SI_USER. Може да получите повече информация от члена si_code:

   The following values can be placed in si_code for a SIGBUS signal:

       BUS_ADRALN     invalid address alignment

       BUS_ADRERR     nonexistent physical address

       BUS_OBJERR     object-specific hardware error

       BUS_MCEERR_AR (since Linux 2.6.32)
                      Hardware memory error consumed on a machine check; action required.

       BUS_MCEERR_AO (since Linux 2.6.32)
                      Hardware memory error detected in process but not consumed; action optional.

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

Подозирам, че вашият дебъгер може да е малко объркан относно произхода на сигнала SIGBUS тук; може да го приписва на грешната нишка. Може да искате да прегледате другите нишки на вашия процес, за да видите дали правят нещо странно. Като алтернатива може да сте срещнали IO грешка при връщане от nanosleep и пейджинг в страницата с код на адреса за връщане.

person bdonlan    schedule 26.09.2011
comment
Брилянтно, благодаря за това. Ще прегледам отново основния файл и ще докладвам. Какъв вид IO грешки могат да възникнат? Забележка: това е вградена среда на Linux с деактивирано прекомерно ангажиране на паметта. И имате предвид препълване на стека в пространството на потребителя или ядрото? - person gimmeamilk; 27.09.2011
comment
Препълване на стека в потребителското пространство. IO грешки могат да означават почти всичко, което ще задейства -EIO на read() - person bdonlan; 27.09.2011
comment
наскоро имах приложение, което получи SIGBUS, защото твърдият диск се повреди и ядрото очевидно не можа да размени някои от регионите на паметта на този процес. - person thor; 19.12.2012