Board.KolibriOS.org

Official KolibriOS board
It is currently Fri Nov 22, 2019 12:24 am

All times are UTC+03:00




Post new topic  Reply to topic  [ 34 posts ]  Go to page 1 2 3 Next
Author Message
PostPosted: Sat Apr 11, 2009 12:43 pm 
Offline

Joined: Fri Nov 21, 2008 8:16 am
Posts: 180
Ну во-первых, интересует отношение как разработчиков ядра, так и приложений - к необходимости такой фишки: Structured Exception Handler

Сегодня прикладной программист имет лишь возможность перехватить исключения по FPU и SSE.
Ну слабовато, вообще-то...
И по другим исключениям можно совершать в приложении более осмысленные действия, чем "Process - forced terminate"

Мои соображения:
1) Без этого механизма как-то не очень и солидно...
2) Работа делится на две части: ядро занимается обработкой исключений и возвращает управление некому хуку, который заказало приложение, в месте с 32-х битной маской для исключений
3) Этот хук, в отличие от уже имеющихся для FPU и SSE, должен как-то получать номер исключения, да и некий TLS (Thread Local Storage) тоже иметь бы неплохо. А может - и крайне необходимо...
4) А вот коды этого хука могли бы содержаться в некой системной библиотеке (или в приложении, если таковая библиотека - это библиотека макросов), и именно эти коды могли бы определять стратегию раскрутки исключения... Однопроходную, двух, и т.п..

Ту часть, что в ядре - могу взять на себя. Пока все это свежо в памяти
Просто как-то надо решить, как это сделать интерфейсно...
Чтобы это не конфликтовало с сегодня имеющимися хуками.
Где располагать этот TLS, чтобы код потока не дергал ядро по всякой ерунде, когда надо узнать в каком контексте он работает. Собственно, это не только в SEH может понадобиться...

В общем, обсудить это надо...


Top
   
PostPosted: Sun Apr 12, 2009 8:02 pm 
Offline
Kernel Developer
User avatar

Joined: Mon Mar 20, 2006 10:44 am
Posts: 557
Засыпаю, посему обрывки мыслей:

ИМХО то как Sexual Exception Handler сделан в Win (FS:0) - не лучший способ. Для меня предпочтительнее интерфейс UNIX (POSIX) сигналов. Так же нужно подумать о возможности вложенных обработчиков (очередь обратоки, не обработал крайний - передается предыдущему, и т.д. вплоть до системного - просто прикрывающего процесс, как сейчас ). Ещё нужно не забыть дать возможность установки выделенного стека для обработчика, простой пример: исключение ESP - на границе памяти, pop *... Ну и раз уж мы отдаем обработку исключений приложению, и система у нас мультизадачная, то и двойного исключения при ошибке в пользовательском обработчике (например затирание кода...), аппаратно возникать не будет, это надо отслеживать программно (новое состояние процесса?). Кроме того с сигналами можно сделать и человеческий таймер, и как ни как это IPC.


Top
   
PostPosted: Sun Apr 12, 2009 9:18 pm 
Offline

Joined: Fri Nov 21, 2008 8:16 am
Posts: 180
Дык время-то еще детское (было) :D
Ну ты главное проснувшись - продолжи :)

1) Про FS:0 спорить не буду. Да, как-то и не принято, как мне показалось, в KoApi, чтобы ядро само аллоцировало память, и хитро возвращало ее потоку... Даже стек при создании потока - проблемы пользователя. Ну так и пущай, к примеру, при создании потока в аргументах идет не только адрес вершины стека, но и его дна. А там и будет располагаться TLS. В котором одним из значений и будет номер исключения...

2) Ну если не FS:0, то может быть некий фиксированный адрес в адресном пространстве потока??? Точнее, одно из полей хедера. Что сразу приводит к следующей версии хедера, а в этом поле исходно (design-time) и будет прошиваться адрес TLS стартового потока приложения. Ну а do_change_task тупо, но честно, будет писать туда адрес текущего - не супер и работа-то...
Offtopic: Кстати говоря, у меня давно было желание про следующую версию хедера, чтобы одним из полей был адрес таблицы импорта....

3) Про POSIX - должной эрудицией не обладаю... Но мне пока кажется: мухи - отдельно, котлеты отдельно. Способы раскрута, и место сохранения информации для этих раскрутов - это дело третьего кольца. Про системную библиотеку говорить можно бесконечно... Где-то уже говорил, что это должно получиться (имхо) вовсе не виндячие user32, а наоборот - больше похожее на некую визуальную библиотеку + некую системную некого языка. Чтобы для запуска пустой формы было достаточно двух операций: создания некого апплета, и запуска его метода Run :wink:
А попробуй такое сделать - сразу же упрешься в ограничения KoApi
И seh - один из таких вопросов, где сразу упираешься. Ну вот, я со стороны ядра и пытаюсь потихоньку чистить ситуацию...

4) Как-то меня не очень напрягают повторные исключения... В том смысле, что делай некий супер стек, не делай его - все равно пользователь сумеет уронить приложение. А зачем платить больше, если нет разницы :)
Но, согласен. Некий флаг работы в исключении - заводить в APPDATA будет нужно. Ну типа, в основном режиме работает фильтр перехвата, а перехвативши - он как бы и "нулевой", и любое исключение, это "Process - forced terminate" (ну или debug_notification)

5) Про таймеры... Ну опиши конкретно свое видение интерфейса. Вплоть до номеров ф-й/подф-й...
Возьму да сделаю... Обсудивши коротенько
Типа, я уже самый большой специалист по "правильным ожиданиям" :lol:


Top
   
PostPosted: Mon Apr 13, 2009 12:56 am 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Если tls не очень большой можно сделать персональную страницу для каждого потока и мапить её при переключении контекста.


Top
   
PostPosted: Mon Apr 13, 2009 5:33 am 
Offline

Joined: Fri Nov 21, 2008 8:16 am
Posts: 180
Serge, Вы имеете в виду фиксированные адреса в приложении для всех потоков ???
Тогда какие....
В смысле, как бы это могло выглядеть со стороны пользователя :?:

Хотя, если напихаем туды барахла на 4К это уже больше на винду будет похоже, чем на Kolibri :)
Мне пока понятнее наоборот - значительно меньше, чем 4К


Top
   
PostPosted: Mon Apr 13, 2009 7:13 am 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Приложение определяет адрес и размер tls (можно и через заголовок) а ядро для каждого потока создаст персональную страницу и будет мапить её на этот адрес. В этом случае доступ к данным tls будет для программиста таким же простым как и к обычным данным, без разных ухищрений.

для fasm
Code:

tls          dd tls_begin       
tls_size   dd tls_end-tls_begin

align 4096
tls_begin:

var1 dd ?
var2 dd ?
var3 dd ?

align 4
tls_end:
для gcc
int local_data __attribute__ ((section (".tls))) = 0;

Большинство компиляторов яву умеют размещать данные в именованых секциях. В крайнем случае данные можно объявить extern а tls секцию сделать на асме.


Top
   
PostPosted: Mon Apr 13, 2009 11:33 am 
Offline

Joined: Fri Nov 21, 2008 8:16 am
Posts: 180
Угу, согласен. Доступ будет проще на одну косвенность...
В том варианте, что я думал, программисту очень просто добраться до переменной, которая лишь указывает на TLS (зато ядру практически ничего делать не надо)

Чего смущает: мы скидываем на пользователя выравнивание этого блока (как по адресу, так и по размеру) на пользователя
Ошибется разок, захватив 4К-блоком по настоящему глобальные переменные - вот намучается-то коллега :)
Подумать надо......


Такой вопрос: а насколько мы связаны в своих фантазиях проблемами совместимости :?:
В смысле, использовал ли кто уже имеющиеся хуки на FPU и SSE :?:
Думаю себе... Ну предположим, в калькуляторе (или еще где) мы решили посчитать логорифм отрицательного числа...
Оказываемся в хуке, и чего мы там должны делать ???
Простой ret, это повторение пройденного. Следовательно, надо делать что-то типа ljmp (играться со стеком, в общем) в то место, где эти неправильные данные формировались, и чего-то каким-то макаром исправлять
Даже интересно посмотреть бы...


Top
   
PostPosted: Mon Apr 13, 2009 12:24 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
На работу ядра ошибка не повлияет, это главное. А страховать программиста от всех возможных ошибок ядро не обязано.

Обработка исключений FPU есть в Open Watcom. Всё работает и протестировано. fpeinth.asm - пример обработчика.


Top
   
PostPosted: Mon Apr 13, 2009 12:50 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Кстати там эмулируются сигналы POSIX. Библиотека устанавливает свой первичный обработчик. Он производит анализ исключения FPU. Потом из таблицы обработчиков сигналов вызывается пользовательский обработчик если он установлен.
Code:
void __sigfpe_handler( int fpe_type )
{
    __sig_func  func;
   
    func = SignalTable[ SIGFPE ];
    if( func != SIG_IGN  &&  func != SIG_DFL  &&  func != SIG_ERR ) {
        SignalTable[ SIGFPE ] = SIG_DFL;      /* 09-nov-87 FWC */
        (*(__sigfpe_func)func)( SIGFPE, fpe_type );        /* so we can pass 2'nd parm */
    }
}


Top
   
PostPosted: Mon Apr 13, 2009 2:14 pm 
Offline

Joined: Fri Nov 21, 2008 8:16 am
Posts: 180
Уточню вопрос :)
Реально ли сделать изменения в системной библиотеке Open Watcom, чтобы она не пользовалась f68:15/18, но предоставляла те же (вообще-то - большие) возможности прикладному программисту :?:
Грубо говоря, чтобы он ничего незаметил...
Естественно, после того, как мы закончим нашу постановочную часть.

Откуда ноги растут
Эти хуки сегодня локализованы в строках 135-141 файла sys32.inc. Теперь же просто в глаза бросается, что вместо этого надо лепить один универсальный.
Можно конечно пытаться оставить и то, и другое... Но не факт, что это получится полноценно и без костылей. Да и смотреться будет типа: "здесь играть, здесь не играть, а здесь рыбу заворачивали..."
Вопрос исключений при делении на 0, и программистам на Open Watcom - тоже не безынтересен должен быть...

Вот еще....
Поясните, если можно, Ваши магические слова про POSIX, и егойные "сигналы". На 100% не надо, скажем так - "тремя фразами", но чтобы хоть базовое понимание осталось...
Уровень моей образованности примерно таков: с nix-ами сроду дело не имел. Сделать любого типа перехваты исключений в винде через winApi - да без проблем (как это делается конкретно на VC - тоже знаю).
А вот чтобы поднять это на ЯВУ - мегабайты кодов же перелопатить надо :(
Фиг поймешь, где там чего начинается, и где заканчивается...
На ассемблере оно как-то "по-настоящему" и поэтому значительно более понятно.

Serge wrote:
А страховать программиста от всех возможных ошибок ядро не обязано
Дык собственно, я не о страховке говорил...
Добавлю даже, что и бесполезно.
Просто смотрю, есть два варианта... Оба вроде должны быть работоспособны.
Какие есть факторы: а) насколько это вызывает суету в ядре при переключениях б) насколько это вредоносно, или наоборот - удобно пользователю.
Вот и все :)
Для себя - я еще и сам не понял окончательно. Может и еще какие факторы есть, кроме вышепречисленного, и более приоритетные
Будем спешить не торопясь...


Top
   
PostPosted: Mon Apr 13, 2009 2:39 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Не уверен что нужен именно один универсальный. #gpf, #pf это одно, а исключение fpu или sse совсем другое. Валить всё в одну кучу - только усложнять код. Фактически получится что сначала ядро сгребает все исключения вместе чтобы вызвать одну единственную функцию, а потом функция должна снова разобрать эти исключения и вызвать для каждого свой обработчик. Ненужная двойная работа.

Исключения POSIX подробно описаны в gnu libc manual


Top
   
PostPosted: Mon Apr 13, 2009 3:12 pm 
Offline

Joined: Fri Nov 21, 2008 8:16 am
Posts: 180
Serge, дык ты возьми и сравни.

Это раньше была двойная работа. Можно даже сказать, что очень много двойной работы. Да и не всегда одинаково эта, одна и та же работа, в разных местах выполнялась...
А #pf и так возвращался в основной обработчик - это вовсе не мои же фантазиию. И нет ничего плохого в возможности перехвата #pf, от которого отказался основной обработчик
Честное слово - ничего плохого :)

Как бы я пытался сохранить функциональную эквивалентность.
А вот except7 (не помню его фамилию) - вроде ДА, ты прав, не чего ему в этой кухне вариться
Дык я его и не "втаскивал"...

В общем, насчет усложнения - не соглашусь. Пол-Кб на этой ерунде скинулось...
А по мне, так и понятнее все стало в три раза...
Вот же ж оно все перед глазами, на одной страничке, а не в пяти разных файлах :)


Top
   
PostPosted: Mon Apr 13, 2009 4:34 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Quote:
А по мне, так и понятнее все стало в три раза...

А по мне нет. Это я вполне серьёзно.
Ассемблер не самый читабельный язык, а заоптимизированность делает код совсем непонятным. Т.е. то что хорошо для микроконтроллеров не обязательно хорошо для Колибри. У программиста не должно пропадать желание разбираться в исходниках после первого взгляда на них. Потому что это система не для одной железяки ( запустили в космос и все - пусть себе летает. Для следующей железяки сделаем совершенно новую систему, лет через двадцать).

Кстати макрос proc coздаёт кадр стека push ebp/mov ebp, esp
Мне кажется что этот код теперь работает не так как раньше
Code:
proc except_16       ;fpu native exceptions handler
        test    byte [esp+8+2], 2
        jnz     v86_except_16


Top
   
PostPosted: Mon Apr 13, 2009 6:18 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
И ещё. После изменений в экспортируемых функциях ядра надо увеличивать номер драйверной модели чтобы ядро не пыталось загрузить несовместимые драйверы. Текущий номер в ядре
DRV_COMPAT equ 5 ;minimal required drivers version
DRV_CURRENT equ 5 ;current drivers model version
надо заменить на 6. И в драйверах тоже.


Top
   
PostPosted: Mon Apr 13, 2009 6:41 pm 
Offline

Joined: Fri Nov 21, 2008 8:16 am
Posts: 180
1) Этот код вообще никак не работает. Его просто нет в kernel.mnt
Макрос proc, кроме всего прочего, еще и окружает все это дело условием if used ProcName
А префиксы входа, и макрос ret он переопределяет только по необходимости
Умный такой макрос...
Если не записаны аргументы, и не применено locals - ничего он и не добавит.
Такое окружение я сделал с единственной целью - чтобы в случае "большого глюка" было легче откатываться
Альтернатива была - совсем выкинуть

2) Serge, ну я ведь тоже серьезно. Ну трудно разбираться в кодах, которые раскиданы по 3-5 файлов, когда фактически все это умещается на страничке.
Сейчас это - просто первые 200 строк в sys32 (вместе с коментариями, определениями дескрипторов, и т.п.)
Честное слово, я значительно больше трачу время, чтобы найти все хвосты, чем на рефракторинг.
Вполне серьезно. Не, ну не сумашедший же я, чтобы писать так, чтобы сам ничего не понял
Например, как заморочены IRQ - я до конца еще и не понял.
Трудно потому-что. И мне кажется, что именно такое может отбить желание.

Пример: полчаса примерно разбирался, чем же занимается checkidle, и минут пять писал тот код, который сейчас (rev 1055).
Если бы сразу на него смотрел, то 5 минут и разбирался бы.
Это гипотеза конечно, но именно так я вполне серьезно и думаю...
Ну не пишу я так, чтобы сначала мне было понятно, а потом зашифровываю оптимизацией. Не, я сразу в таком стиле и пишу.
Ну да, когда задача уже кем-то решена, оптимальные (и понятные!!!) варианты сделать гораздо проще...
Чем когда рисуешь коды с нуля. В таком состоянии далеко не всегда знаешь чем оно закончится
А тут уже: вот оно, все и целиком, и ничего другого не будет
Это я не виноват, это закон природы такой... Я и над своими кодами издеваюсь НЕ МЕНЬШЕ... Стиль такой: работаешь, работаешь - а кодов с каждым днем становится все меньше и меньше.

А про C++ Ну блин... Порой перестаешь понимать, кто для кого: язык для нас, или мы для языка...
В ассемблере все честно - раз, два, и ты вышел на спецификацию проца...

В качестве offtopa
Была у меня история с C++ :wink:
Я ведь на полном серьезии верил, что сей продвинутый ЯВУ экономит время разработки
И довольно глубоко юзал IAR-овский CPP для avr-ок
Кстати говоря, по качеству: Борман или Gcc - рядом не стояли. У них особая технология линковки, которая разрешает т.н. "проблему отложенных конструкторов". Ну это так....
Да, экономит... Если ты делаешь работу, которую можно поднять за день
А вот через пару месяцев работы посмотришь в коды, и понимаешь, что когда задача уже прояснена на столько, то сделать этот же код на ASM-е - не больше 2-х дней. При лучшем качестве.
Сравните это с 2-мя месяцами, или пол-годом...
Это при всем при том, что не просматривать с пристрастием сгенерированные коды (в дизасме, например) сим компилятором - себе дороже. У меня это настолько в привычку вошло, что я даже и kernel.mnt в hiew посматриваю (про proc выше, это не я такой умный, это результаты наблюдений)
Есть такой фактор: ты борешься не только со своей проблемой (задачей), но и с компилятором

Serge, это все я - абсолютно серьезно. Закинул я этот компилятор
НО я никого в свою веру обращать не хочу...
Однако поверьте, рассказанное - не просто правда. Это больше чем правда. Так оно и было на самом деле
Не, ну давай я, к примеру, в три раза больше комментов писать буду.... :)

3) Ага, понял. Спасибо
Только кое-что уточнить надо...


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 34 posts ]  Go to page 1 2 3 Next

All times are UTC+03:00


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited