?

Log in

[icon] Fixed - Segmentation fault
View:Свежие записи.
View:Архив.
View:Друзья.
View:Личная информация.

Tags:
Security:
Subject:Fixed
Time:05:25 pm
Проблема была вот в этом коде:

disable_interrupts();
dlist_add_tail((DLIST**)&handle->stream->write_waiters, (DLIST*)handle);
enable_interrupts();
kprocess_sleep(process, NULL, PROCESS_SYNC_STREAM, h);




Ошибка совсем детская. Но такое хрен отладишь потом. Повезло. Это в реализации stream - кто скажет, в чем ошибка? Не догадаетесь, можно в исходник заглянуть, там уже пофиксено.

Комментарии пока скрою.
comments: Оставить комментарий Previous Entry Поделиться Next Entry


balmerdx
Link:(Link)
Time:2017-02-03 08:32 am
Наверно надо было сначала подождать, не завершатся ли остальные еще не завершенные потоки на всякий случай, а потом уже добавлять в очередь. deadlock был?

Ну и кстати отличный пример, где C++ помог бы в коде. Можно было бы структуру write_waiters унаследовать от DLIST и избавиться от приведения типов. Чтобы ненароком не ошибиться. (Конечноже понимаю, что на С++ переходить не нужно по причинам удобства компиляции под разные платформы.)
(Ответить) (Thread)


mbr
Link:(Link)
Time:2017-02-03 04:28 pm
Они никогда не завершатся. Может прийти более высокое прерывание и начать параллельно в поток писать/читать. Синхронизация пользовательских действий происходит в контексте супервизора, ждать там нельзя. Да и вообще ждать это плохая стратегия.

Кресты помогут только дополнительную память съесть и тормозов добавить. В остальном от них пользы в микроконтроллерах нет. Конкретно в данном случае - процесс содержится в одном динамическом списке всех процессов и одновременно системный таймер процесса содержится в другом динамическом списке системных таймеров. А по срабатыванию таймера необходимо определить процесс, которому он принадлежит. На с++ это не реализуешь без сишных манипуляций. Любой иной способ, кроме как unsafe манипуляцию с памятью приводит к дополнительным тактам, дополнительному использовании памяти, поэтому неприемлил.

А раз все так обленились думать, правильного ответа не будет :)
(Ответить) (Parent) (Thread)


balmerdx
Link:(Link)
Time:2017-02-03 09:26 pm
У тебя просто есть контекст в голове, что к чему и почему. А стороннему человеку не так очевидно все. Посмотрел код.

Насколько понимаю этот фрагмент взят из kstream_write.

kprocess_sleep(process, NULL, PROCESS_SYNC_STREAM, h); помещает процесс в список спящих и ожидающих, что завершится процесс записи.

dlist_add_tail((DLIST**)&handle->stream->write_waiters, (DLIST*)handle); добавляет поток записи в список потоков, ожидающих flush. Так как все данные не влезли в буфер.

Видимо когда kprocess_sleep находится снизу, то может случиться ситуация, когда данные уже успели все записаться и процесс ожидает бесконечно долго, пока запишется нулевое количество данных.

Т.к. есть только одно ядро и из user прерываний насколько понял нельзя писать в stream, то это видимо решает проблему.

Про "Кресты помогут только дополнительную память съесть и тормозов добавить." Сам по себе С++ он про дополнительные restriction на этапе компиляции. Потому как каждый раз, когда пишется (DLIST**)&handle - можно ошибиться и привести к несовместимому типу. Пока проект маленький - это нестрашно.
(Ответить) (Parent) (Thread)


mbr
Link:(Link)
Time:2017-02-03 09:35 pm
Подсмотрел :) Но ответ правильный.

Писать может и из пользовательского контекста, и из супервизора (экзоядро) и из прерываний. Но блокирующие вызовы разрешены только из контекста процесса.

С++ настолько же дыряв в плане защиты. Поэтому вся от него польза - жрать оперативку, флеш и тормозить. Я как бы последний раз прошу перечитать верхний пост и более не возвращаться к этой глупости.
(Ответить) (Parent) (Thread)

[icon] Fixed - Segmentation fault
View:Свежие записи.
View:Архив.
View:Друзья.
View:Личная информация.