Comments 65
Реверс-инжиниринг не является взломом, хоть и часто используется при взломе.
Копирасты продавили изменения в законодательствах большинства стран, и теперь реверс-инжиниринг по юридическим последствиям стоит в одном ряду со взломом.
А раньше и реверс, и даже патчинг кода был в ряде случаев разрешён. Например, для обеспечения запуска на имеющемся у реверсера железе.
Там используется слово "hacked", которое в английском имеет более широкий смысл, не только негативный. В данном случае по смыслу близко "встроил в компилятор C++ 28-летней давности"...
"вкорячил в компилятор C++ 28-летней давности"
И даже, судя по всему, не ничего не делал с компилятором, а всего лишь написал свои реализации служебных процедур ("хуков"), вызовы которых компилятор генерирует на try/catch/throw.
Я такое делал для MS VC++, который в отладочном режиме умеет вставлять вызовы служебных процедур, проверяющих целостность служебных же данных. Стандартные реализации тянут за собой изрядный объем кода из libc, который не умеет работать в ядре, поэтому бедняги из MS во всех своих ядерных модулях этой возможностью не пользуются, а я уже двадцать лет пользуюсь во весь рост. :)
Корявый перевод слова hack.
Боже мой, когда уж стюардессу-то закопают. Имею в виду Watcom.
Очень хорошая стюардесса, что ж вы так
Откапывать и откапывать? ;-)
Подтверждаю, не так давно им вполне коммерческую халтурку сделал :) Все эти современные полупрозрачные графонии и прочие рюшечки, тупо подцепил апи директных дров образца тыща поросятого года и всё кинулось мигать, сверкать и щёлкать так, как заказчик хотел :) А 64 бита там не требовалось, некуда и незачем.
Жив курилка!
Ладно, но потом - закопать!
Если в архитектуре используется обработка исключение как обработка ошибок, что-то пошло не так.
Wacom ,кстати был оберткой вокруг Си, и в каких-то версиях там бы Сишные структурированные исключения... он копал не в ту сторону ?
Если в архитектуре используется обработка исключение как обработка ошибок, что-то пошло не так.
Можете поподробнее раскрыть свою мысль? А то мне кажется, что по вашему мнению, на исключениях обработку ошибок делать неправильно.
Ну вот в Go возвращают errno на каждом шагу и гордятся этим.
"Возвращают errno" это оксюморон. errno в C это глобальная переменная, которая неявно модифицируется функцией, а не возвращаемое значение. И даже если воспринимать "errno" в широком смысле как "код ошибки", то вы неправы, потому что в Go в качестве ошибки можно возвращать (и на практике возвращаются) не только числа, а любые произвольные объекты с детальной информацией.
errno вполне может быть оберткой вокруг функции, афайк, т.к. требует локальности по отношению к потоку. Правильнее конечно сказать устанавливает. https://man7.org/linux/man-pages/man3/errno.3.html
если код не использует стронние библиотеки, то не надо допускать исключения в своем коде,
если вы вызываете функции сторонних библиотек, то желательно не допускать условия при которых функции завершаются с исключениями
надо, по мере сил, пытаться не допускать ошибок, которые вызывают исключения, а не наварачивать "модную" обработку ошибок на исключениях, неужели вы этого не знаете?
Ну и как мне открыть файл без вероятности исключений?(замена исключения на errno не рассматриваем)
https://medium.com@cummingsi19933/the-operation-result-pattern-a-simple-guide-fe10ff959080
На всех проектах, где есть either, работать с апи вообще желания нет. Посмотри на kotlin coroutines, dart async. Тут всё сделано для того, чтобы было удобно с исключениями работать. В то же время, если тебе надо сделать несколько последовательных операций с Either, то делай код лесенкой. Хотя мог бы в 1 try catch обернуть
А как открытие файла связано с исключениями? В Си++ там все на битах состояния ( good, bad, fail, eof)
Очень сильное утверждение. Но я пожалуй продолжу разрабатывать нормально
Неправильно. Есть паттерн result. В Rust это класс Result, в Scala и Haskell - Either, например. Логика обработки ошибок в идеале должна крутиться вокруг них, так как возможные ошибки вписываются в контракт функции, как и обязательность их обработки. Исключения ломают контракт функций - это по сути еще одно возвращаемое значение, не вписанное в сигнатуру. В Java пытались это решить, сделав декларируемые исключения, но это оказалось неудобным (особенно в свете функционального программирования).
Причем тут Rust, Scala и прочие языки программирования? Давайте притянем за уши еще Брайнфак, в котором обработки ошибок вообще нет.
Обсуждается компилятор C++, в котором исключения архитектурно предназначены в том числе и для обработки ошибок.
Мне показалось что речь шла не о вреде исключений вообще, а именно на уровне архитектуры - взаимодействия компонент. Есть какой то API, есть протокол взаимодействия, и вдруг оттуда прилетает эксепшен. В вводе выводе эксепшены удобны, но их область распространения должна быть ограничена, иначе что за прикол нажать кнопку на плеере и получить окошко что у Васи usb диск отмонтирован.
Я тоже не понял комментарий @MiyuHogosha, поэтому и попросил уточнить его возражения. Исключения сами по себе - это просто инструмент для реализации алгоритма, и не более.
Естественно, функции Сишной библиотеки не должны выбрасывать исключений, даже если они используются внутри компонент в самой библиотеке. Но это не означает, что "Если в архитектуре используется обработка исключение как обработка ошибок, что-то пошло не так."
Я парафразировал Мейерса. Анархист и нв13 даже привелии некоторые из его аргументов. А примеров что у него, что на практике - сотни. Использование исключений оголяет множество подводных камней с RAII, в стандарт даже вносились изменния только ради исправления безвыходных ситуаций, см make_unique или порядок инициализации аргументов функции.
Использование исключений оголяет множество подводных камней с RAII, ...
При реализации RAII в С++ есть подводные камни, которые вскрылись при использовании исключений и ... что? Как по мне, так наоборот, благодаря исключениям были исправлены UB, что сделало поведение программы более детерминированным.
Именно. А еще хуже, что в процессе какой-то файл не был закрыт, ибо этот код скипнули.
Нигде не сказано что они прдназначены для обработки ошибок. они предназначены для обработки exception, что есть слово-враг переводчика, имеющнее еще одно , узко-специализированное значение - удолетворенный протест. Это событие, требующее немедленной реакции без предпринятия каких либо других действий. Обработка состояний ошибок может быть рутинной логикой, в случае исключений программа не может работать дальше и должна занятьсяконтролем повреждений.
в случае исключений программа не может работать дальше и должна заняться контролем повреждений
Да где вы этого начитались?
Исключение, это не ошибка в программе. Исключение, это одна из базовых архитектурных конструкций для реализации алгоритма. Поведение при исключении строго детерминировано и программа продолжает свое выполнение (зависит от реализованного алгоритма), в отличии от Segmentation Fault, при возникновении которого программа просто падает.
С помощью исключений, можно обрабатывать логические ошибки, но никто не запрещает их обрабатывать их с помощью кодов возврата.
Авторы языков Rust, Scala и Haskell сильно постарались для того, чтобы использовать их Result и Either не было больно. Но язык С++ поддерживает только исключения.
std::expected в стандарт попал, а std::optional с 17 стандарта, что намекает, что костыли вокруг местного Result городились много лет.
А вообще одно не отменяет другого. Причин невозможности записать в файл настолько много, что городить плотную лестницу из обработки ошибок в каждом месте вызова - путь си с классами.
Учавствовал я в одном проекте, где не применяли исключения потому что они медленные (безосновательно абсолютно), а вместо этого возвращали 0 если в цепочке вызовов на 22 уровне стека что-то пошло не так. Но там был си с классами и типичные lib_malloc/lib_free без попыток это как-то обернуть в RAII, с соответствующим результатом сегфолтов в случайные моменты времени.
std::optional-то, может, и с 17 стандарта - но вот хотя бы метод and_then у него появился в том же стандарте, что и std::expected
Однако, в С++ лямбды писать не так удобно как в других языках, и один только and_then не может сделать использование std::expected удобным.
Чтобы конкурировать по удобству с исключениями, монаде Result нужна либо нормальная do нотация (как в Scala и Haskell), либо собственный оператор (как в Rust). В крайнем случае можно припрячь сопрограммы, но тогда непонятно как применять эту штуку в, собственно, сопрограммах.
То есть, реализовать даже в виде библиотеки невозможно?
что... в Си++ исклбчения привернули с краю в 90ые, позаимствовав идею из расширения для Си (было несколmько разных, в том числе и мелкомягкое)
Видимо вы не читали Мейерса.
Исключения - это исключительные ситуации. Вроде случая, когда вы обратились к нелегальной памяти (а значит код неверен) или у вас кончилась память. Исключения приводят к развертке стека и устранению всех созданных объектов... если код написан правильно. Это медленно, затраты недетерминированы, есть большая возмошность выстрела граблей в ногу. Существование и адекватность инвариантов глобальных объектов под угрозой. Есть причина почему популярные фреймаорки выкидывают из программы "вы не обработали исключение до выхода из слота". Возврат кода или сохранение состояния ошибки в объекте более предпочтительны.
Исключения - это исключительные ситуации. ...
Это масло масляное. Исключение, это вполне себе конкретное и детерминированное поведение и они создаются при нормальном выполнении программы, а не возникают "по волшебству" из-за неправильного обращения к памяти или при её нехватке.
И если у вас действительно произойдет ошибка при работе с памятью, то это будет Segmentation Fault, а не исключение.
Не надо писать логику на исключениях, а обработка ошибок - нормально.
В случае работы с вводом\выводом, например сокетами или файлами обработка кодов ошибок и есть часть логики, см. POSIX коды ошибок не являющиеся ошибками. Если вы под обработкой ошибок подразумеваете аварийные ситуации - да, это и есть назначение исключений. В действительности исключение - это неверный устойчивый перевод. Оно использовалось в смысле английского легализа - подтвержденный акт изъявления протеста в суде, когда сказанное должно быть проигнорированно (см. witnesses whose authority is beyond exception).
Watcom же жив в виде Open Watcom с открытым исходным кодом и до сих пор поддерживает DOS.
Ну как жив? Учитывая, что он по своей природе не поддерживает 64-разрядный код, то это уже не очень-то жизнь.
Коллега, я тоже не понимаю, зачем там что-то бинарное взламывать, если можно просто перейти на открытое решение.
Рубрика: "Угадай автора новости по заголовку".
У самурая нет цели, только путь.
Но зачем?
О, Ватком! С середины 90-х его не видел :)
взломал
Какой невероятно отвратительный перевод слова "hack". Не умеете переводить - не беритесь.
Эта простыня на первом скриншоте до боли напоминает обработку ошибок в Go, но там исключения не планируются :)
Проблема Go не в отсутствии исключений, а в отсутствии sum types и сахара для пробрасывания, по типу ?
в Rust или do notation в Haskell. Пробрасывание по значению не обязательно должно быть вербозным. В том же расте высокоуровневый код выглядит так же, как аналогичный на языке с эксепшнами, только приправленный парочкой ?
. Особенно если используется anyhow. И при этом отсутствуют все недостатки эксепшнов. Код легко композируется и для каждой функции по сигнатуре понятно, может ли она вернуть ошибку.
Sum types в Go правда тоже не планируются, но это уже упрямость и ошибка авторов. Такая же, как отсутствие дженериков (до недавних пор) и повторение the billion dollar mistake.
Я не очень понял, при чём тут "взломал" и "реверс". Код Watcom же открыли 20 лет назад?
Разработчик взломал компилятор C++ 28-летней давности, чтобы проект поддерживал исключения