Ну во-первых, интересует отношение как разработчиков ядра, так и приложений - к необходимости такой фишки: Structured Exception Handler
Сегодня прикладной программист имет лишь возможность перехватить исключения по FPU и SSE.
Ну слабовато, вообще-то...
И по другим исключениям можно совершать в приложении более осмысленные действия, чем "Process - forced terminate"
Мои соображения:
1) Без этого механизма как-то не очень и солидно...
2) Работа делится на две части: ядро занимается обработкой исключений и возвращает управление некому хуку, который заказало приложение, в месте с 32-х битной маской для исключений
3) Этот хук, в отличие от уже имеющихся для FPU и SSE, должен как-то получать номер исключения, да и некий TLS (Thread Local Storage) тоже иметь бы неплохо. А может - и крайне необходимо...
4) А вот коды этого хука могли бы содержаться в некой системной библиотеке (или в приложении, если таковая библиотека - это библиотека макросов), и именно эти коды могли бы определять стратегию раскрутки исключения... Однопроходную, двух, и т.п..
Ту часть, что в ядре - могу взять на себя. Пока все это свежо в памяти
Просто как-то надо решить, как это сделать интерфейсно...
Чтобы это не конфликтовало с сегодня имеющимися хуками.
Где располагать этот TLS, чтобы код потока не дергал ядро по всякой ерунде, когда надо узнать в каком контексте он работает. Собственно, это не только в SEH может понадобиться...
В общем, обсудить это надо...
Как сделать полноценный SEH
Засыпаю, посему обрывки мыслей:
ИМХО то как Sexual Exception Handler сделан в Win (FS:0) - не лучший способ. Для меня предпочтительнее интерфейс UNIX (POSIX) сигналов. Так же нужно подумать о возможности вложенных обработчиков (очередь обратоки, не обработал крайний - передается предыдущему, и т.д. вплоть до системного - просто прикрывающего процесс, как сейчас ). Ещё нужно не забыть дать возможность установки выделенного стека для обработчика, простой пример: исключение ESP - на границе памяти, pop *... Ну и раз уж мы отдаем обработку исключений приложению, и система у нас мультизадачная, то и двойного исключения при ошибке в пользовательском обработчике (например затирание кода...), аппаратно возникать не будет, это надо отслеживать программно (новое состояние процесса?). Кроме того с сигналами можно сделать и человеческий таймер, и как ни как это IPC.
ИМХО то как Sexual Exception Handler сделан в Win (FS:0) - не лучший способ. Для меня предпочтительнее интерфейс UNIX (POSIX) сигналов. Так же нужно подумать о возможности вложенных обработчиков (очередь обратоки, не обработал крайний - передается предыдущему, и т.д. вплоть до системного - просто прикрывающего процесс, как сейчас ). Ещё нужно не забыть дать возможность установки выделенного стека для обработчика, простой пример: исключение ESP - на границе памяти, pop *... Ну и раз уж мы отдаем обработку исключений приложению, и система у нас мультизадачная, то и двойного исключения при ошибке в пользовательском обработчике (например затирание кода...), аппаратно возникать не будет, это надо отслеживать программно (новое состояние процесса?). Кроме того с сигналами можно сделать и человеческий таймер, и как ни как это IPC.
Дык время-то еще детское (было)
Ну ты главное проснувшись - продолжи
1) Про FS:0 спорить не буду. Да, как-то и не принято, как мне показалось, в KoApi, чтобы ядро само аллоцировало память, и хитро возвращало ее потоку... Даже стек при создании потока - проблемы пользователя. Ну так и пущай, к примеру, при создании потока в аргументах идет не только адрес вершины стека, но и его дна. А там и будет располагаться TLS. В котором одним из значений и будет номер исключения...
2) Ну если не FS:0, то может быть некий фиксированный адрес в адресном пространстве потока??? Точнее, одно из полей хедера. Что сразу приводит к следующей версии хедера, а в этом поле исходно (design-time) и будет прошиваться адрес TLS стартового потока приложения. Ну а do_change_task тупо, но честно, будет писать туда адрес текущего - не супер и работа-то...
: Кстати говоря, у меня давно было желание про следующую версию хедера, чтобы одним из полей был адрес таблицы импорта....
3) Про POSIX - должной эрудицией не обладаю... Но мне пока кажется: мухи - отдельно, котлеты отдельно. Способы раскрута, и место сохранения информации для этих раскрутов - это дело третьего кольца. Про системную библиотеку говорить можно бесконечно... Где-то уже говорил, что это должно получиться (имхо) вовсе не виндячие user32, а наоборот - больше похожее на некую визуальную библиотеку + некую системную некого языка. Чтобы для запуска пустой формы было достаточно двух операций: создания некого апплета, и запуска его метода Run
А попробуй такое сделать - сразу же упрешься в ограничения KoApi
И seh - один из таких вопросов, где сразу упираешься. Ну вот, я со стороны ядра и пытаюсь потихоньку чистить ситуацию...
4) Как-то меня не очень напрягают повторные исключения... В том смысле, что делай некий супер стек, не делай его - все равно пользователь сумеет уронить приложение. А зачем платить больше, если нет разницы
Но, согласен. Некий флаг работы в исключении - заводить в APPDATA будет нужно. Ну типа, в основном режиме работает фильтр перехвата, а перехвативши - он как бы и "нулевой", и любое исключение, это "Process - forced terminate" (ну или debug_notification)
5) Про таймеры... Ну опиши конкретно свое видение интерфейса. Вплоть до номеров ф-й/подф-й...
Возьму да сделаю... Обсудивши коротенько
Типа, я уже самый большой специалист по "правильным ожиданиям"
Ну ты главное проснувшись - продолжи
1) Про FS:0 спорить не буду. Да, как-то и не принято, как мне показалось, в KoApi, чтобы ядро само аллоцировало память, и хитро возвращало ее потоку... Даже стек при создании потока - проблемы пользователя. Ну так и пущай, к примеру, при создании потока в аргументах идет не только адрес вершины стека, но и его дна. А там и будет располагаться TLS. В котором одним из значений и будет номер исключения...
2) Ну если не FS:0, то может быть некий фиксированный адрес в адресном пространстве потока??? Точнее, одно из полей хедера. Что сразу приводит к следующей версии хедера, а в этом поле исходно (design-time) и будет прошиваться адрес TLS стартового потока приложения. Ну а do_change_task тупо, но честно, будет писать туда адрес текущего - не супер и работа-то...
: Кстати говоря, у меня давно было желание про следующую версию хедера, чтобы одним из полей был адрес таблицы импорта....
3) Про POSIX - должной эрудицией не обладаю... Но мне пока кажется: мухи - отдельно, котлеты отдельно. Способы раскрута, и место сохранения информации для этих раскрутов - это дело третьего кольца. Про системную библиотеку говорить можно бесконечно... Где-то уже говорил, что это должно получиться (имхо) вовсе не виндячие user32, а наоборот - больше похожее на некую визуальную библиотеку + некую системную некого языка. Чтобы для запуска пустой формы было достаточно двух операций: создания некого апплета, и запуска его метода Run
А попробуй такое сделать - сразу же упрешься в ограничения KoApi
И seh - один из таких вопросов, где сразу упираешься. Ну вот, я со стороны ядра и пытаюсь потихоньку чистить ситуацию...
4) Как-то меня не очень напрягают повторные исключения... В том смысле, что делай некий супер стек, не делай его - все равно пользователь сумеет уронить приложение. А зачем платить больше, если нет разницы
Но, согласен. Некий флаг работы в исключении - заводить в APPDATA будет нужно. Ну типа, в основном режиме работает фильтр перехвата, а перехвативши - он как бы и "нулевой", и любое исключение, это "Process - forced terminate" (ну или debug_notification)
5) Про таймеры... Ну опиши конкретно свое видение интерфейса. Вплоть до номеров ф-й/подф-й...
Возьму да сделаю... Обсудивши коротенько
Типа, я уже самый большой специалист по "правильным ожиданиям"
Если tls не очень большой можно сделать персональную страницу для каждого потока и мапить её при переключении контекста.
Serge, Вы имеете в виду фиксированные адреса в приложении для всех потоков ???
Тогда какие....
В смысле, как бы это могло выглядеть со стороны пользователя
Хотя, если напихаем туды барахла на 4К это уже больше на винду будет похоже, чем на Kolibri
Мне пока понятнее наоборот - значительно меньше, чем 4К
Тогда какие....
В смысле, как бы это могло выглядеть со стороны пользователя
Хотя, если напихаем туды барахла на 4К это уже больше на винду будет похоже, чем на Kolibri
Мне пока понятнее наоборот - значительно меньше, чем 4К
Приложение определяет адрес и размер tls (можно и через заголовок) а ядро для каждого потока создаст персональную страницу и будет мапить её на этот адрес. В этом случае доступ к данным tls будет для программиста таким же простым как и к обычным данным, без разных ухищрений.
для fasmдля gcc
int local_data __attribute__ ((section (".tls))) = 0;
Большинство компиляторов яву умеют размещать данные в именованых секциях. В крайнем случае данные можно объявить extern а tls секцию сделать на асме.
для fasm
Code: Select all
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:
int local_data __attribute__ ((section (".tls))) = 0;
Большинство компиляторов яву умеют размещать данные в именованых секциях. В крайнем случае данные можно объявить extern а tls секцию сделать на асме.
Угу, согласен. Доступ будет проще на одну косвенность...
В том варианте, что я думал, программисту очень просто добраться до переменной, которая лишь указывает на TLS (зато ядру практически ничего делать не надо)
Чего смущает: мы скидываем на пользователя выравнивание этого блока (как по адресу, так и по размеру) на пользователя
Ошибется разок, захватив 4К-блоком по настоящему глобальные переменные - вот намучается-то коллега
Подумать надо......
Такой вопрос: а насколько мы связаны в своих фантазиях проблемами совместимости
В смысле, использовал ли кто уже имеющиеся хуки на FPU и SSE
Думаю себе... Ну предположим, в калькуляторе (или еще где) мы решили посчитать логорифм отрицательного числа...
Оказываемся в хуке, и чего мы там должны делать ???
Простой ret, это повторение пройденного. Следовательно, надо делать что-то типа ljmp (играться со стеком, в общем) в то место, где эти неправильные данные формировались, и чего-то каким-то макаром исправлять
Даже интересно посмотреть бы...
В том варианте, что я думал, программисту очень просто добраться до переменной, которая лишь указывает на TLS (зато ядру практически ничего делать не надо)
Чего смущает: мы скидываем на пользователя выравнивание этого блока (как по адресу, так и по размеру) на пользователя
Ошибется разок, захватив 4К-блоком по настоящему глобальные переменные - вот намучается-то коллега
Подумать надо......
Такой вопрос: а насколько мы связаны в своих фантазиях проблемами совместимости
В смысле, использовал ли кто уже имеющиеся хуки на FPU и SSE
Думаю себе... Ну предположим, в калькуляторе (или еще где) мы решили посчитать логорифм отрицательного числа...
Оказываемся в хуке, и чего мы там должны делать ???
Простой ret, это повторение пройденного. Следовательно, надо делать что-то типа ljmp (играться со стеком, в общем) в то место, где эти неправильные данные формировались, и чего-то каким-то макаром исправлять
Даже интересно посмотреть бы...
На работу ядра ошибка не повлияет, это главное. А страховать программиста от всех возможных ошибок ядро не обязано.
Обработка исключений FPU есть в Open Watcom. Всё работает и протестировано. fpeinth.asm - пример обработчика.
Обработка исключений FPU есть в Open Watcom. Всё работает и протестировано. fpeinth.asm - пример обработчика.
Кстати там эмулируются сигналы POSIX. Библиотека устанавливает свой первичный обработчик. Он производит анализ исключения FPU. Потом из таблицы обработчиков сигналов вызывается пользовательский обработчик если он установлен.
Code: Select all
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 */
}
}
Уточню вопрос
Реально ли сделать изменения в системной библиотеке Open Watcom, чтобы она не пользовалась f68:15/18, но предоставляла те же (вообще-то - большие) возможности прикладному программисту
Грубо говоря, чтобы он ничего незаметил...
Естественно, после того, как мы закончим нашу постановочную часть.
Откуда ноги растут
Эти хуки сегодня локализованы в строках 135-141 файла sys32.inc. Теперь же просто в глаза бросается, что вместо этого надо лепить один универсальный.
Можно конечно пытаться оставить и то, и другое... Но не факт, что это получится полноценно и без костылей. Да и смотреться будет типа: "здесь играть, здесь не играть, а здесь рыбу заворачивали..."
Вопрос исключений при делении на 0, и программистам на Open Watcom - тоже не безынтересен должен быть...
Вот еще....
Поясните, если можно, Ваши магические слова про POSIX, и егойные "сигналы". На 100% не надо, скажем так - "тремя фразами", но чтобы хоть базовое понимание осталось...
Уровень моей образованности примерно таков: с nix-ами сроду дело не имел. Сделать любого типа перехваты исключений в винде через winApi - да без проблем (как это делается конкретно на VC - тоже знаю).
А вот чтобы поднять это на ЯВУ - мегабайты кодов же перелопатить надо
Фиг поймешь, где там чего начинается, и где заканчивается...
На ассемблере оно как-то "по-настоящему" и поэтому значительно более понятно.
Добавлю даже, что и бесполезно.
Просто смотрю, есть два варианта... Оба вроде должны быть работоспособны.
Какие есть факторы: а) насколько это вызывает суету в ядре при переключениях б) насколько это вредоносно, или наоборот - удобно пользователю.
Вот и все
Для себя - я еще и сам не понял окончательно. Может и еще какие факторы есть, кроме вышепречисленного, и более приоритетные
Будем спешить не торопясь...
Реально ли сделать изменения в системной библиотеке Open Watcom, чтобы она не пользовалась f68:15/18, но предоставляла те же (вообще-то - большие) возможности прикладному программисту
Грубо говоря, чтобы он ничего незаметил...
Естественно, после того, как мы закончим нашу постановочную часть.
Откуда ноги растут
Эти хуки сегодня локализованы в строках 135-141 файла sys32.inc. Теперь же просто в глаза бросается, что вместо этого надо лепить один универсальный.
Можно конечно пытаться оставить и то, и другое... Но не факт, что это получится полноценно и без костылей. Да и смотреться будет типа: "здесь играть, здесь не играть, а здесь рыбу заворачивали..."
Вопрос исключений при делении на 0, и программистам на Open Watcom - тоже не безынтересен должен быть...
Вот еще....
Поясните, если можно, Ваши магические слова про POSIX, и егойные "сигналы". На 100% не надо, скажем так - "тремя фразами", но чтобы хоть базовое понимание осталось...
Уровень моей образованности примерно таков: с nix-ами сроду дело не имел. Сделать любого типа перехваты исключений в винде через winApi - да без проблем (как это делается конкретно на VC - тоже знаю).
А вот чтобы поднять это на ЯВУ - мегабайты кодов же перелопатить надо
Фиг поймешь, где там чего начинается, и где заканчивается...
На ассемблере оно как-то "по-настоящему" и поэтому значительно более понятно.
Дык собственно, я не о страховке говорил...Serge wrote:А страховать программиста от всех возможных ошибок ядро не обязано
Добавлю даже, что и бесполезно.
Просто смотрю, есть два варианта... Оба вроде должны быть работоспособны.
Какие есть факторы: а) насколько это вызывает суету в ядре при переключениях б) насколько это вредоносно, или наоборот - удобно пользователю.
Вот и все
Для себя - я еще и сам не понял окончательно. Может и еще какие факторы есть, кроме вышепречисленного, и более приоритетные
Будем спешить не торопясь...
Не уверен что нужен именно один универсальный. #gpf, #pf это одно, а исключение fpu или sse совсем другое. Валить всё в одну кучу - только усложнять код. Фактически получится что сначала ядро сгребает все исключения вместе чтобы вызвать одну единственную функцию, а потом функция должна снова разобрать эти исключения и вызвать для каждого свой обработчик. Ненужная двойная работа.
Исключения POSIX подробно описаны в gnu libc manual
Исключения POSIX подробно описаны в gnu libc manual
Serge, дык ты возьми и сравни.
Это раньше была двойная работа. Можно даже сказать, что очень много двойной работы. Да и не всегда одинаково эта, одна и та же работа, в разных местах выполнялась...
А #pf и так
Это раньше была двойная работа. Можно даже сказать, что очень много двойной работы. Да и не всегда одинаково эта, одна и та же работа, в разных местах выполнялась...
А #pf и так