Системный вызов nanosleep () просыпается с ошибкой шины?

Я смотрю на дамп ядра из встроенного приложения 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, к сожалению, не был захвачен. Около 30 тем. Первоначально не было обработчика SIGBUS. Я добавил один для диагностики этой проблемы, и si_pid содержит то, что кажется адресом в .text программы (!). Есть ли сценарий, в котором это произойдет? Я провел некоторые эксперименты, и обычно si_pid правильно содержит pid процесса-отправителя или ноль, если он был сгенерирован этим процессом.   -  person gimmeamilk    schedule 27.09.2011


Ответы (1)


Если si_pid установлен на адрес, это означает, что ваш SIGBUS был поднят из-за ошибки в программе. Обычно это происходит, когда ядро ​​пытается просмотреть какой-либо текст программы, но сталкивается с ошибкой ввода-вывода. Переполнение стека также может вызвать это.

Вы видите, что 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 здесь; это может быть связано с неправильным потоком. Возможно, вы захотите изучить другие потоки вашего процесса, чтобы увидеть, не делают ли они что-нибудь странное. С другой стороны, вы могли столкнуться с ошибкой ввода-вывода при возврате из nanosleep и пейджинге на странице кода по адресу возврата.

person bdonlan    schedule 26.09.2011
comment
Блин, спасибо за это. Я еще раз изучу основной файл и доложу. Какие ошибки ввода-вывода могут возникнуть? Примечание. Это встроенная среда Linux с отключенным перераспределением памяти. И вы имеете в виду переполнение стека в пространстве пользователя или ядра? - person gimmeamilk; 27.09.2011
comment
Переполнение стека в пользовательском пространстве. Ошибки ввода-вывода могут означать практически все, что вызовет -EIO на read() - person bdonlan; 27.09.2011
comment
недавно у меня было приложение, которое получило SIGBUS, потому что жесткий диск вышел из строя, и ядро, по-видимому, не могло поменять местами некоторые области памяти этого процесса. - person thor; 19.12.2012