Pull to refresh

Comments 26

Я начинаю всерьез опасаться за психическое здоровье разработчиков Wine и ReactOS. Им же это повторять…

А за перевод спасибо, буду давать ссылку последователям :)
беспокоетесь
Сейчас-же
всё-же
на прошлой недели
соеденять
колличество
объеденённую
сдесь
надеятся

Вы серьезно хотите переводить на русский?

«ClientContext» («КонтекстКлиента». Прим. перев.)
«TimestampType» («ТипМеткиВремени». Прим. перев.)

А то пацаны английского-то совсем не знают! (прим. читат.)
Спасибо (Прим. перев.)
"крассный флаг для принцыпа" забыли
Там еще с десяток опечаток, я в ЛС отправил, в том числе эту. Будем вежливыми!
Мне честно стыдно за такие ошибки. Но, что поделать, попался.
Почему люди так любят арифметику указателей? Для того, чтобы поместить массив символов в конец структуры, достаточно создать свою структуру из двух полей — исходной структуры и массива символов.
я тоже когда-то любил, считал что «профессионалы» так и должны писать. А потом пописал на языках более высокого уровня и понял, что читаемость кода на первом месте.
Люди просто не в курсе, что *(a + 4) == a[4] по ходу. А уж те, кто указатели в интах хранят заслужили отдельной печи в аду.
Ох, и не говорите. Встречал как-то в продакшене код, в котором указатели преобразовывались в unsigned и складывались в std::vector. Хотел бы я пообщаться с тем, кто это писал…
a[4] — любой школяр на Фортране напишет. Но *(a + 4) — это чувство, как будто можешь разглядывать женщину сквозь одежду. Или даже сквозь кожу.
А много вы знаете школьников, которые знают Фортран?
Много. Но они сейчас либо член-корры, либо в Хайфе…
В Linux тоже встречаются подобные вещи. Например, неудобен API Video4Linux (подсистема работы с видео в ядре linux). Например, отсутствует модель обратного вызова при захвате с устройства. То есть необходимо городить свой поток для чтения видеоданных.

У ffmpeg тоже есть недочет: вместо того чтобы сделать классическое указание времени до таймаута при вызове блокирующей av_read_frame(...) и других блокирующих функций, нужно описывать так называемую interrupt_callback-функцию, которая будет дергаться ffmpeg'ом постоянно и в ней ты уже отсчитываешь таймаут (либо делаешь что-то еще, но ОЧЕНЬ кратковременно). Если возвращать из нее 0, то последняя блокирующая операция продолжит висеть, если вернуть 1 (например, при наступлении того же таймаута), то операция прервется и выйдет с ошибкой. Если код interrupt_callback будет выполняться некратковременно(в попугаях), то неисключены всякие SEGFAULT'ы и прочие радости :)
Функция вместо таймаута — это объяснимо хотя бы.
Я когда-то, лет 15 назад, имел несчастье делать кроссплатформенный GUI layer для одной софтины, в случае винды работавший с чистым Win32 (долго объяснять, почему так получилось… но вот получилось). Из этого экспириенса мне больше всего запомнились разрушение памяти ядра в Win9x на BitBlt(), и, конечно, INITCOMMONCONTROLSEX. Последнее, мне кажется, хорошо отражает некоторые особенности работы с многими из Windows API.
Так как в жизни получается разрабатывать под Windows, то очень часто слышу, при сравнени API Windows и Linux, что плох только API Windows, а Linux API — почти что идеален — нет никаких проблем. Хотелось бы узнать Ваше мнение. Есть ли такие косяки и в мире Linux API?

Я начинал с WinAPI и считал, что его разрабатывали настолько крутые дядьки, что мне никогда не понять их замысла. А на самом деле API Windows настолько плох, что по Linux сравнению с ним — божественен!
Припоминаю, однажды испытывал точно такие-же чувства когда понадобилось написать простенькое приложение, выводящее через WinApi список всех подключённых USB-флешек. То, что по моим прикидкам должно было занять пару дней работы, в итоге заняло 2 недели, включающие в себя прочтение просто гор документации, поиск примеров на различных форумах и несколько вопросов на StackOverflow. Мда…
CMSIS для stm тоже тот еще ад. Явно писали инженеры, которые чуть знают программирование.

Сегодня ковырял разные ipc для linux и не нашел ни одного удобного и одновременно масштабируемого.
По ходу kdbus, когда станет доступен, принесет много много пользы.
Как человек, весьма много работавший с ETW, хочу ответственно заявить, что автор статьи совершенно не понимает о чем говорит. И дело даже не в самом ETW API (которое, скажем прямо, далеко от идеального) — дело в непонимании кучи БАЗОВЫХ вещей.

Начнем с того, что автор пытается использовать низкоуровневое API и с удивлением обнаруживает, что оно… НИЗКОУРОВНЕВОЕ. Ну явно какие то дебилы писали. Использовать к примеру StartKernelTrace было бы можно, но как же тогда писать возмущенную статью. Если нужно более гибкое, но высокоуровневое API, можно использовать WPRControl (это тем более удобно, что тот же самый профайл можно будет запускать отдельно от собственной программы, а также менять состав собираемого лога без перекомпиляции — простой правкой конфигурационного файла).

Возмущение по поводу GUID вообще не в кассу. Здесь человеку нужно почитать о размещении значимых типов в C/C++ и единицах трансляции. Отличие INITGUID в том, что оно заставляет макрос DEFINE_GUID определять переменную (с выделением места в data секции для текущей единицы трансляции). По умолчанию (без INITGUID) данный макрос только объявляет (extern) переменную и предоставляет линкеру позаботиться о поиске определения (и, соответственно, размещения). Да-да, тупой Майкрософт «не смог найти способ внедрить их в заголовочные файлы (я могу насчитать несколько возможных способов, но, я полагаю, им не понравился не один из них)». На минуточку, здесь прозвучало предложение внедрять ОПРЕДЕЛЕНИЯ переменных (то есть выделение памяти для них) в заголовочне файлы ПО УМОЛЧАНИЮ. Конечно же, что может быть лучше заголовочных файлов с непустым вкладом в объектный файл? Ведь всегда можно налепить сверху хак вроде __declspec(selectany). Динамически выделяемую память, кстати, за собой тоже можно не чистить — достаточно просто прибить процесс и никто и не заметит утечек.

Возмущение по поводу ограниченного количества «флагов» в «kernel trace» провайдере забавны в свете того, что вот прямо сейчас вон там из 33, а «xperf -providers K» из Windows 8.1 SDK выдает список из 55 возможных флагов (это только публичная часть — возможно для «внутреннего потребления» их еще больше).

Предложенные варианты API забавны, ибо совершенно не попадают в сценарии использования ETW. Самое главное требование — низкая стоимость (околонулевая в случае, когда на событие никто не подписан и не более пары тысяч тактов, если подписан). При этом необходимо обеспечить возможность работы на *всех* IRQL (к примеру есть возможность писать в лог с IPI или CLOCK уровней, когда не только диспетчер не работает, но и большинство прерываний от устройств замаскированы). При этом все должно продолжать работать на многопроцессорных системах (из чего следует, что использование любых видов блокировок запрещено). Необходимо иметь возможность писать в кольцевой буфер (подумайте о флаге REFSET который трейсит все ОБРАЩЕНИЯ к памяти — хотите ли Вы в пользовательском режиме обрабатывать все такие события? В реальном времени?). Нужно иметь возможность начать лог до старта не только первого пользовательского процесса, который мог бы в ETWBeginTrace, а и до старта, собственно, ядра (да-да, winload умеет писать в ETW лог — предлагаю угадать как он это делает). Это только то, что пришло в голову прямо сейчас (мне даже представлять не хочется этап сбора требований в команде, которая разрабатывала этот компонент).

Собственно разделение сессий трассировки и потребителей трейса — вполне логичное следствие даже тех поверхностных требований, которые я уже привел. Поэтому и разделение StartTrace/OpenTrace — трейс запускается в сессии, а потреблять его может кто угодно (собственно, это ОСНОВНОЙ режим работы API — запуск трейса xperf/wpr на тестовой/проблемной машине и анализ лога на машине разработчика — я даже и не припомню когда бы мне пришлось сталкиваться с «realtime» трейсами).

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

Это даже комментировать не хочется. Ну конечно, канал «утечки» системной информации не имеет никакого значения для того, что требуется права администратора. Это было сделано исключительно для того, чтоб никто не мог вырвать сессию.

Кстати, по поводу «безумия». SystemTraceProvider и его же сессия — действительно выделены в отдельный специальный случай, что выглядит несколько некрасиво. Но, как и многие другие компромиссы, этот был сделан ради производительности — уж сильно много всего трейсит данный провайдер. Для остальных провайдеров API более универсально, но за универсальность, как обычно платят производительностью. Начиная с Win8, его можно включить до восьми раз. В принципе в моей практике почти всегда хватало одного. Исключения — это всякие когда запущен какой нибудь Process Explorer/Process Hacker (я активно исследую что-либо) и при этом мне хочется собрать трейс. Если включить эти случаи, то мне изредка нужно 2-3 сессии. И при этом я, в отличие от автора статьи, действительно не один год провел ковыряясь в производительности.
Напишите, пожалуйста, свою статью о ETW. Тема крайне мало где освещена и каждый разработчик изучает её по-своему.
В расчет стоит брать несколько вещей
— Вы совершенно правы, говоря, что задача перед инженерами MS стояла не тривиальная — логи из ядра штука не тривиальная, достаточно хотя бы посмотреть как с этим делом справляется Линукс
— Желчность статьи скорее можно списать на культурные особенности англо-саксов и современных американцев, т.е. уровень эмоций нужно поделить где то на 5 чтоб получить соотносимое с нашей культурой восприятие.
— В свое время занимался получением трейсов из драйверов через ETW. Что могу сказать — незабываемый опыт:
* Плохо документированное API, порой откровенно вводит в заблуждение в силу мелких ошибок или пробелов
* Реверс инжиниринг получаемых структур от драйвера ибо они вообще не документированы от слова совсем
* Дублирование информации в получаемых структурах (порой по нескольку раз на 1 структуру с вложенными структурами)
* ThreadID (если источником данных является UserSpace процесс) не соответсвует реальному Thread
* Если пишите в файл системными функциями ETW будьте готовы к тому что файл будет поврежден — перееханный системный заголовок, HexEdit вам в руки (говорят в Windows 8 исправлено, но на слово верить не привык)
* Отдельный трэд для потребления можно вполне понять, но удобства это не добавляет
* «Удобство» API можно конечно тоже переварить, не самое худшее, но до приемлимого уровня ему еще далеко.
* Были еще какие то сложности и не мало, но за давностью лет уже не помню.

В общем как всегда — все усилия на индусов и C# а люди что пишут драйвера и так умные — разберутся сами в спагетти из идей и недокументированного API, дебаггер в руки и побежали.
UFO just landed and posted this here
UFO just landed and posted this here
Sign up to leave a comment.

Articles