![]() |
|
Модераторы: xvr |
![]()
|
|
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
Проблема возникла не у меня, у моего коллеги... и конечно я посоветовал ему лучше отладить свой код... но он ни в какую...
Задача состоит в том, чтобы отловить segmentation fault и не вылетать из программы, а просто проигнорировать этот момент и продолжить со следующей итерации... Вчера познакомился с макросами setjmp и longjmp, но их работа по видимому осталась для меня загадкой... Приведу пример кода, над которым я ставлю эксперименты
Первая итерация отрабатывает, как надо... Но на второй, судя по дебагеру теряется адрес обработчика сигнала и программа вылетает на этапе генерации прерывания, а именно на строке *pTest = 123; Объясните пожалуйста, где моя ошибка... Судя по всему я просто не правильно понимаю работу этих макросов... Заранее благодарен всем откликнувшимся за помощь... |
|||
|
||||
| creatorcode |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 82 Регистрация: 12.6.2006 Где: Ленинград Репутация: нет Всего: 4 |
pTest - нулевой указатель, поэтому и вылетает с ошибкой. Вы должны сначала выделить память под указатель и только потом использовать его. Например так:
где size - размер выделяемой памяти. В вашем случае по всей видимости size=1. Хотя тогда непонятно с какой вообще целью используется указатель. |
||||
|
|||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
не вижу ошибки
у меня все сводится к бесконечному циклу, т. е как и должно быть Добавлено через 44 секунды creatorcode, вы не в теме, извините -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| creatorcode |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 82 Регистрация: 12.6.2006 Где: Ленинград Репутация: нет Всего: 4 |
Прошу прощения, не сразу въехал в вопрос. Попробую оправдаться
К тому же не вижу смысла использовать signal. Можно вполне обойтись и без него:
Это сообщение отредактировал(а) creatorcode - 19.3.2008, 20:14 |
||||
|
|||||
| null56 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
MAKCim,
Вы попробовали запускать этот код? Потому что у меня там ожидание стоит между циклами 5 секунд, а ошибка вылетает на ВТОРОЙ (!!!) итерации цикла? Приведу пример код с отладочной печатью...
Результатом работы будет:
|
||||
|
|||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
Аналогичная программа, использующая обычный метод не вылетает...
В чем хитрость... в какой области памяти создается функция, которая назначается методом signal? |
|||
|
||||
| MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
null56,
вообщем, все понятно сначала решение чтобы все заработало, нужно использовать sigsetjmp() и siglongjmp() теперь почему не работало следите за логикой 1. при формировании ядром сигнального фрейма, в стек записывается адрес возврата т. е когда выполняется код обработчика SIGSEGV на вершине стека лежит адрес возврата при вызове signal() мы не можем его явно указать, поэтому код libc, которому соответствует функция signal() устанавливает его за нас по-умолчанию адрес возврата, указываемый в libc, соответствует внутренней функции libc, которая осуществляет восстановление контекста процесса исходя из данных, которые ядро сохранило для нас в сигнальном фрейме 2. на первой итерации SIGSEGV успешно перехватывается и управление переходит на наш обработчик но вместо того, чтобы перейти по адресу, находящемуся на вершине стека, идет вызов longjmp(), который полностью восстанавливает контекст процесса важно отметить, что ядро перед вызовом обработчика сигнала блокирует этот сигнал поэтому после longjmp() мы оказываемся тут
и при этом SIGSEGV заблокирован 3. генерация сигнала для процесса в результате #PF осуществляется в функции ядра force_sig_info() вот ее код
ключевой момент зключается в том, что в ней идет проверка, не заблокирован ли генерируемый сигнал и если заблокирован (а в нашем случае он заблокирован, как я показал выше), то он разблокируется с восстановлением дефолтного состояния обработчика сигнала, которым является SIG_DFL для SIGSEGV дефолный обработчик приводит к завершению процесса поэтому на второй итерации идет завершение процесса, а не передача управления на наш обработчик sigsetjmp() сохраняет маску заблокированных к моменту вызова сигналов (на первой итерации SIGSEGV еще не заблокирован) siglongjmp() восстанавливает маску заблокированных сигналов а значит после siglongjmp() SIGSEGV не будет заблокирован и в функции force_sig_info() не произойдет сброс нашего обработчика Это сообщение отредактировал(а) MAKCim - 19.3.2008, 23:14 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
Огромное спасибо за помощь...
Я понял свою ошибку, она в большинстве своем все - таки была от незнания... Действительно, создавая непосредсвенный переход на свою точку в стеке, я теряю обратный ход событий, который подразумевал в libc вызов своих процедур, которые отвечали за разблокировку сигнала. Еще раз спасибо всем откликнувшимся... ЗЫ: MAKCim, я вопрос не по теме отправил вам в личку |
|||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 20 Всего: 223 |
Я бы еще добавил по поводу signal:
|
||||
|
|||||
![]()
|
| Правила форума "С/С++: Программирование под Unix/Linux" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |