Mingw что это
Перейти к содержимому

Mingw что это

  • автор:

Mingw-w64

MinGW-w64 — набор средств разработки для Windows, включает в себя компилятор GNU C/C++, отладчик gdb, профайлер gprof, системы сборки make и cmake и прочие утилиты комплекта GNU. MinGW расшифровывается, как Minimalistic Gnu for Windows. Проект отделился от проекта MinGW.

Установка mingw-w64

Существуют различные независимые сборки mingw-w64, большинство их которых распространяется в виде нескольких архивов, которые необходимо отдельно распаковывать. Разобраться в том, какие именно архивы нужно скачивать и распаковывать довольно сложно. Вариант установки с использованием exe-приложения, самостоятельно скачивающего нужные пакеты, к сожалению, содержит весьма устаревшую версию 8.1.0 компилятора.

Довольно простой способ установки (понадобится скачать только один архив) актуальной версии компилятора — это использование сайта winlibs.com.

Откройте этот сайт и перейдите к разделу «Download». Там будет довольно много разных ссылок на скачивание, расскажем как выбрать правильный архив, если вы не знаете в точности, что именно вам нужно.

Перейдите к разделу «Release versions» — «UCRT runtime». Выберите самую верхнюю версию MinGW в списке, она помечена, как LATEST. Вам нужна версия для Win64. Если предлагаются варианты сборки с LLVM/Clang/LLD/LLDB, выберите вариант без (without) LLVM/Clang/LLD/LLDB (по крайней мере, если вы не знаете точно, что вам нужны именно LLVM/Clang/LLD/LLDB). Выберите zip-архив (если у вас установлен архиватор 7-zip, то можете скачать архив 7-zip, он меньше). То есть вам понадобится вот этот файл.

Выбор архива для скачивания mingw-w64 c winlibs.com

Внутри скачанного архива будет каталог mingw64. Распакуйте этот каталог на диск, лучше всего не использовать каталоги с пробелами или русскими буквами в именах (в том числе «Program Files»), поэтому лучше всего распаковать архив прямо в корень диска C:\. Далее будем считать, что у вас получился каталог C:\mingw64, внутри которого есть подкаталоги bin, include, lib, libexec, share и x86_64-w64-mingw32.

Добавление mingw-w64 в PATH

Для того, чтобы можно было использовать приложения из распакованного архива, а сторонние среды разработки, такие как Code::Blocks или Visual Studio Code могли найти компилятор, необходимо подкаталог bin из распакованного архива добавить в системную переменную Path.

Вам необходимо открыть окно «Свойства системы» панели управления Windows. Для этого нужно открыть проводник, сделать правый клик мышью на «Этот компьютер», выбрать «Свойства». Появится окно «Система — О системе», в котором нужно кликнуть на «Дополнительные параметры системы».

Или можно сразу открыть окно «Свойства системы», если нажать на Win+R, в строку «Открыть» ввести команду sysdm.cpl, затем нажать Enter.

В окне «Свойства системы» выберите вкладку «Дополнительно» и нажмите на «Переменные среды. «. Верхний список — это переменные среды для текущего пользователя, нижний список — системные переменные. В списке системных переменных выберите Path и нажмите на кнопку «Изменить». Нажмите на кнопку «Создать», в списке появится новая строка. Нажмите на кнопку «Обзор» и выберите каталог C:\mingw64\bin (или подкаталог bin подкаталога mingw64, если вы распаковали его в другое место). Нажмите на OK, затем на OK, затем на OK.

Подробней про переменные среды и их изменение можно прочитать здесь.

Проверка работы компилятора

После распаковки архива и добавления MinGW-w64 в Path, запустите командную строку. Нажмите на Win+R и введите команду cmd, затем нажмите Enter.

Наберите команду g++. Вы должны увидеть сообщение «g++: fatal error: no input files compilation terminated». Наберите команду

g++ --version

Вы увидите сообщение с версией компилятора. Убедитесь, что версия соответствует той, которую вы скачали.

MinGW-w64 — для 32- и 64-битной Windows загрузить для Windows

Это приложение для Windows под названием MinGW-w64 — для 32- и 64-разрядной версии Windows, последняя версия которого может быть загружена как mingw-w64-v10.0.0.zip. Его можно запустить онлайн в бесплатном хостинг-провайдере OnWorks для рабочих станций.

Загрузите и запустите онлайн это приложение под названием MinGW-w64 — для 32- и 64-битной Windows бесплатно с OnWorks.

Следуйте этим инструкциям, чтобы запустить это приложение:

— 1. Загрузил это приложение на свой компьютер.

— 2. Введите в нашем файловом менеджере https://www.onworks.net/myfiles.php?username=XXXXX с желаемым именем пользователя.

— 3. Загрузите это приложение в такой файловый менеджер.

— 4. Запустите любой онлайн-эмулятор OS OnWorks с этого сайта, но лучше онлайн-эмулятор Windows.

— 5. В только что запущенной ОС Windows OnWorks перейдите в наш файловый менеджер https://www.onworks.net/myfiles.php?username=XXXXX с желаемым именем пользователя.

— 6. Скачайте приложение и установите его.

— 7. Загрузите Wine из репозиториев программного обеспечения вашего дистрибутива Linux. После установки вы можете дважды щелкнуть приложение, чтобы запустить его с помощью Wine. Вы также можете попробовать PlayOnLinux, необычный интерфейс поверх Wine, который поможет вам установить популярные программы и игры для Windows.

Wine — это способ запустить программное обеспечение Windows в Linux, но без Windows. Wine — это уровень совместимости с Windows с открытым исходным кодом, который может запускать программы Windows непосредственно на любом рабочем столе Linux. По сути, Wine пытается заново реализовать Windows с нуля, чтобы можно было запускать все эти Windows-приложения, фактически не нуждаясь в Windows.

MinGW-w64 — для 32- и 64-битной Windows

MinGW

Колин Питерс (англ. Colin Peters ) , Ян-Яап-ван-дер-Хейден (нидерл. Jan-Jaap van der Heijden ) , Мумит Хан (англ. Mumit Khan ) , Андерс Норландер (англ. Anders Norlander ) , Эрни Бойд (валл. Earnie Boyd ) , Дейл Хендерсон (англ. Dale Handerson ) и др.

MinGW (англ. Minimalist GNU for Windows ) , ранее mingw32, — компилятор, родной программный порт GNU Compiler Collection (GCC) под Windows, вместе с набором свободно распространяемых библиотек импорта и заголовочных файлов для Windows API. MinGW позволяет разработчикам создавать родные (native) приложения Windows [1] . В MinGW включены расширения для библиотеки времени выполнения Microsoft Visual C++ для поддержки функциональности C99 [1] .

История

MinGW изначально назывался mingw32; затем цифры были отброшены, чтобы преодолеть заблуждение, что MinGW ограничен 32-битными системами [2] . Первый релиз, созданный Колином Петерсом (англ. Colin Peters ) в 1998 году, включал в себя только порт GCC из Cygwin [3] [4] . Первый нативный Windows-порт GCC был создан Jan-Jaap van der Heijden, также Heijdens добавил binutils и make [3] [4] . Mumit Khan позже принял участие в разработке, добавив в комплект больше специфичных для Windows возможностей, включая заголовочные файлы Win32, написанные Anders Norlander [3] [4] . В 2000 проект был перемещён на SourceForge.net, чтобы получить большую поддержку общественности и централизовать разработку [3] [4] .

В сентябре 2005 MinGW был выбран проектом месяца на SourceForge.net [4] .

Компоненты MinGW

Проект MinGW поддерживает и распространяет несколько различных ключевых компонентов и дополнительных пакетов, включая различные порты GNU toolchain, такие как GCC и binutils, переведённые в эквивалентые пакеты [5] [2] . Эти утилиты могут быть использованы из командной строки Windows или интегрированы в IDE.

В дополнение, компонент MinGW, известный как MSYS (Minimal SYStem) предоставляет win32-порты окружения легковесной Unix-подобной оболочки, включающей rxvt и набор инструментов POSIX, достаточный для запуска скриптов autoconf [6] .

Реализации заголовочных файлов Win32 и библиотек импорта Win32 для связывания во время выполнения программы от начала до её завершения имеют пермиссивную лицензию [7] , а порты GNU доступны под GNU General Public License. Бинарные сборки полного пакета MSYS и отдельных MinGW GNU утилит доступны для скачивания на сайте MinGW.

Сравнение с Cygwin

MinGW отделился от Cygwin 1.3.3. Несмотря на то, что и Cygwin, и MinGW используются для портирования программного обеспечения Unix под Windows, они используют разный подход [8] : цель Cygwin — предоставить полный слой POSIX (подобный тому, который находится в Linux и других Unix-системах) над Windows, жертвуя производительностью там, где это необходимо для совместимости. Соответственно, такой подход требует от Win32 программ, написанных с Cygwin, запуска поверх копилефтной библиотеки совместимости, которая должна распространяться с программой, а также с исходным кодом программы. Целью MinGW является предоставление нативной функциональности и производительности посредством прямых вызовов Windows API. В отличие от Cygwin, MinGW не нуждается в DLL-слое совместимости и, таким образом, программы не обязаны распространяться с исходным кодом.

Вследствие того, что MinGW использует вызовы Win32 API, он не может предоставить полного POSIX API; он не может скомпилировать некоторые приложения Unix, которые могут быть скомпилированы с Cygwin. В частности, это относится к приложениям, которые требуют такой функциональности POSIX, как fork(), mmap() или ioctl() [8] и предполагают запуск в среде POSIX. Приложения, написанные с использованием кроссплатформенных библиотек, таких, как SDL, wxWidgets, Qt или GTK+, как правило, легче компилируются в MinGW, чем в Cygwin.

Комбинация MinGW и MSYS предоставляет небольшую независимую среду, которая может быть загружена на съемные носители, не требуя добавления записей в файлы реестра. Cygwin, предоставляя бо́льшую функциональность, является более сложным для установки и поддержки.

Также возможна кросс-компиляция приложений Windows с MinGW-GCC под управлением операционных систем семейства POSIX. Это означает, что разработчику не нужно устанавливать Windows с MSYS, чтобы скомпилировать программы, которые будут запускаться под Windows без Cygwin.

MinGW-w64

В связи с тем, что в рамках изначального проекта MinGW не обещалось, что в его кодовую базу будут вноситься обновления, связанные с добавлением некоторых новых ключевых элементов Win32 API, а также наиболее необходимой поддержки 64-битной архитектуры, был создан проект [mingw-w64.sourceforge.net/ MinGW-w64]. Он является новой чистой реализацией портирования GNU Compiler Collection (GCC) под Microsoft Windows осуществленной изначально компанией OneVision и переданной затем в 2008 году [9] в общественное пользование ( Public Domain ). Сначала он был предложен на рассмотрение для интеграции с оригинальным проектом MinGW, но был отклонен в связи с подозрением на использование не свободного или проприетарного кода. По многим серьезным причинам этического характера, связанным с отношением со стороны авторов MinGW [10] , ведущие разработчики кода MinGW-w64 решили больше не пытаться кооперироваться с проектом MinGW.

MinGW-w64 обеспечивает более полную реализацию Win32 API, [11] включая:

  • лучшую поддержку стандарта C99
  • лучшую поддержку pthreads (включая возможность задействовать функциональность стандарта C++11 библиотеки libstdc++ компилятора GCC)
  • GCC multilib
  • точки входа в программу с поддержкой Unicode (wmain/wWinMain)
  • DDK (из проекта ReactOS)
  • DirectX (из проекта WINE)
  • Поддержку больших файлов
  • поддержка 64-битной архитектуры Windows

Напишите отзыв о статье «MinGW»

Примечания

  1. 12 [sourceforge.net/projects/mingw/ SourceForge.net: MinGW — Minimalist GNU for Windows]
  2. 12 [mingw.org/mingwfaq.shtml#faq-what What is MinGW?]
  3. 1234 [mingw.org/history MinGW — History]
  4. 12345 [sourceforge.net/potm/potm-2005-09.php SourceForge Project of the Month]
  5. [sourceforge.net/project/showfiles.php?group_id=2435 MinGW Components]
  6. [www.mingw.org/msys.shtml MinGW — Minimal SYStem]
  7. [www.mingw.org/license Licensing Terms | MinGW]
  8. 12 [www.mingw.org/node/21 Cygwin | MinGW]
  9. [sourceforge.net/apps/trac/mingw-w64/wiki/History История пректа MinGW-w64]. MinGW-w64 Wiki. Проверено 30 мая 2013.[www.webcitation.org/6IuipskOG Архивировано из первоисточника 16 августа 2013].
  10. [article.gmane.org/gmane.comp.gnu.mingw.devel/3390 Harmonizing mingwrt / w32api with mingw-w64]. MinGW Mailing list. Проверено 30 мая 2013.[www.webcitation.org/6IuirXucU Архивировано из первоисточника 16 августа 2013].
  11. [mingw-w64.sourceforge.net/picker.php mingw-w64.sourceforge.net/picker.php]. Проверено 30 мая 2013.[www.webcitation.org/6IuisuuZo Архивировано из первоисточника 16 августа 2013].

См. также

Ссылки

  • [gcc.gnu.org/ GCC Home Page]
  • [www.mingw.org/ Официальная страница MinGW]
  • [mingw-w64.sourceforge.net/ Официальная страница MinGW-w64]
  • [sourceforge.net/projects/mingw/ Страница MinGW] на SourceForge.net
  • [tdm-gcc.tdragon.net/ Unofficial TDM-MinGW GCC builds]
  • [mingw-w64.sourceforge.net/download.php GCC for both x64 & x86 Windows!]. Страница загрузки различных вариантов сборок проекта MinGW-w64. В том числе [sourceforge.net/projects/mingwbuilds/ Mingw-builds] — всегда последняя версия mingw-w64 GCC; установки не требует; из особенностей следует отметить основные: а) предоставляются 32 и 64 разрядные сборки, б) сборки являются двухцелевыми, в) полная поддержка С++11 thread support library.
  • [nuwen.net/mingw.html Неофициальная сборка]. Как правило, последняя версия GCC с разными библиотеками и утилитами. Установки не требует.

Отрывок, характеризующий MinGW

– Но это всё таки не значит, чтобы кампания была кончена, – сказал князь Андрей.
– А я думаю, что кончена. И так думают большие колпаки здесь, но не смеют сказать этого. Будет то, что я говорил в начале кампании, что не ваша echauffouree de Durenstein, [дюренштейнская стычка,] вообще не порох решит дело, а те, кто его выдумали, – сказал Билибин, повторяя одно из своих mots [словечек], распуская кожу на лбу и приостанавливаясь. – Вопрос только в том, что скажет берлинское свидание императора Александра с прусским королем. Ежели Пруссия вступит в союз, on forcera la main a l’Autriche, [принудят Австрию,] и будет война. Ежели же нет, то дело только в том, чтоб условиться, где составлять первоначальные статьи нового Саmро Formio. [Кампо Формио.]
– Но что за необычайная гениальность! – вдруг вскрикнул князь Андрей, сжимая свою маленькую руку и ударяя ею по столу. – И что за счастие этому человеку!
– Buonaparte? [Буонапарте?] – вопросительно сказал Билибин, морща лоб и этим давая чувствовать, что сейчас будет un mot [словечко]. – Bu onaparte? – сказал он, ударяя особенно на u . – Я думаю, однако, что теперь, когда он предписывает законы Австрии из Шенбрунна, il faut lui faire grace de l’u . [надо его избавить от и.] Я решительно делаю нововведение и называю его Bonaparte tout court [просто Бонапарт].
– Нет, без шуток, – сказал князь Андрей, – неужели вы думаете,что кампания кончена?
– Я вот что думаю. Австрия осталась в дурах, а она к этому не привыкла. И она отплатит. А в дурах она осталась оттого, что, во первых, провинции разорены (on dit, le православное est terrible pour le pillage), [говорят, что православное ужасно по части грабежей,] армия разбита, столица взята, и всё это pour les beaux yeux du [ради прекрасных глаз,] Сардинское величество. И потому – entre nous, mon cher [между нами, мой милый] – я чутьем слышу, что нас обманывают, я чутьем слышу сношения с Францией и проекты мира, тайного мира, отдельно заключенного.
– Это не может быть! – сказал князь Андрей, – это было бы слишком гадко.
– Qui vivra verra, [Поживем, увидим,] – сказал Билибин, распуская опять кожу в знак окончания разговора.
Когда князь Андрей пришел в приготовленную для него комнату и в чистом белье лег на пуховики и душистые гретые подушки, – он почувствовал, что то сражение, о котором он привез известие, было далеко, далеко от него. Прусский союз, измена Австрии, новое торжество Бонапарта, выход и парад, и прием императора Франца на завтра занимали его.
Он закрыл глаза, но в то же мгновение в ушах его затрещала канонада, пальба, стук колес экипажа, и вот опять спускаются с горы растянутые ниткой мушкатеры, и французы стреляют, и он чувствует, как содрогается его сердце, и он выезжает вперед рядом с Шмитом, и пули весело свистят вокруг него, и он испытывает то чувство удесятеренной радости жизни, какого он не испытывал с самого детства.
Он пробудился…
«Да, всё это было!…» сказал он, счастливо, детски улыбаясь сам себе, и заснул крепким, молодым сном.

На другой день он проснулся поздно. Возобновляя впечатления прошедшего, он вспомнил прежде всего то, что нынче надо представляться императору Францу, вспомнил военного министра, учтивого австрийского флигель адъютанта, Билибина и разговор вчерашнего вечера. Одевшись в полную парадную форму, которой он уже давно не надевал, для поездки во дворец, он, свежий, оживленный и красивый, с подвязанною рукой, вошел в кабинет Билибина. В кабинете находились четыре господина дипломатического корпуса. С князем Ипполитом Курагиным, который был секретарем посольства, Болконский был знаком; с другими его познакомил Билибин.
Господа, бывавшие у Билибина, светские, молодые, богатые и веселые люди, составляли и в Вене и здесь отдельный кружок, который Билибин, бывший главой этого кружка, называл наши, les nфtres. В кружке этом, состоявшем почти исключительно из дипломатов, видимо, были свои, не имеющие ничего общего с войной и политикой, интересы высшего света, отношений к некоторым женщинам и канцелярской стороны службы. Эти господа, повидимому, охотно, как своего (честь, которую они делали немногим), приняли в свой кружок князя Андрея. Из учтивости, и как предмет для вступления в разговор, ему сделали несколько вопросов об армии и сражении, и разговор опять рассыпался на непоследовательные, веселые шутки и пересуды.
– Но особенно хорошо, – говорил один, рассказывая неудачу товарища дипломата, – особенно хорошо то, что канцлер прямо сказал ему, что назначение его в Лондон есть повышение, и чтоб он так и смотрел на это. Видите вы его фигуру при этом?…
– Но что всего хуже, господа, я вам выдаю Курагина: человек в несчастии, и этим то пользуется этот Дон Жуан, этот ужасный человек!
Князь Ипполит лежал в вольтеровском кресле, положив ноги через ручку. Он засмеялся.
– Parlez moi de ca, [Ну ка, ну ка,] – сказал он.
– О, Дон Жуан! О, змея! – послышались голоса.
– Вы не знаете, Болконский, – обратился Билибин к князю Андрею, – что все ужасы французской армии (я чуть было не сказал – русской армии) – ничто в сравнении с тем, что наделал между женщинами этот человек.
– La femme est la compagne de l’homme, [Женщина – подруга мужчины,] – произнес князь Ипполит и стал смотреть в лорнет на свои поднятые ноги.
Билибин и наши расхохотались, глядя в глаза Ипполиту. Князь Андрей видел, что этот Ипполит, которого он (должно было признаться) почти ревновал к своей жене, был шутом в этом обществе.
– Нет, я должен вас угостить Курагиным, – сказал Билибин тихо Болконскому. – Он прелестен, когда рассуждает о политике, надо видеть эту важность.
Он подсел к Ипполиту и, собрав на лбу свои складки, завел с ним разговор о политике. Князь Андрей и другие обступили обоих.
– Le cabinet de Berlin ne peut pas exprimer un sentiment d’alliance, – начал Ипполит, значительно оглядывая всех, – sans exprimer… comme dans sa derieniere note… vous comprenez… vous comprenez… et puis si sa Majeste l’Empereur ne deroge pas au principe de notre alliance… [Берлинский кабинет не может выразить свое мнение о союзе, не выражая… как в своей последней ноте… вы понимаете… вы понимаете… впрочем, если его величество император не изменит сущности нашего союза…]
– Attendez, je n’ai pas fini… – сказал он князю Андрею, хватая его за руку. – Je suppose que l’intervention sera plus forte que la non intervention. Et… – Он помолчал. – On ne pourra pas imputer a la fin de non recevoir notre depeche du 28 novembre. Voila comment tout cela finira. [Подождите, я не кончил. Я думаю, что вмешательство будет прочнее чем невмешательство И… Невозможно считать дело оконченным непринятием нашей депеши от 28 ноября. Чем то всё это кончится.]
И он отпустил руку Болконского, показывая тем, что теперь он совсем кончил.
– Demosthenes, je te reconnais au caillou que tu as cache dans ta bouche d’or! [Демосфен, я узнаю тебя по камешку, который ты скрываешь в своих золотых устах!] – сказал Билибин, y которого шапка волос подвинулась на голове от удовольствия.

  • Программное обеспечение по алфавиту
  • Компиляторы Си
  • Компиляторы C++
  • Эмуляторы Юникс
  • Свободные компиляторы и интерпретаторы
  • Программное обеспечение проекта GNU
  • Свободное программное обеспечение только под Windows
  • Программное обеспечение с лицензией GNU GPL

Использование SEH в 32 разрядных приложениях Windows с компилятором Mingw-W64

Из всех механизмов, предоставляемых операционными системами семейства Windows, возможно наиболее широко используемым, но не полностью документированным, является механизм структурной обработки исключений (он же Structured Exception Handling, или просто – SEH). Структурная обработка исключений — это сервис, предоставляемый операционной системой, механизм обработки программных и аппаратных исключений в операционной системе Microsoft Windows, позволяющий программистам управлять обработкой исключений. Исключение — это событие при выполнении программы, которое приводит к её ненормальному или неправильному поведению.

Вся документация по SEH, которую вы, вероятно, найдете, описывает одну лишь компиляторно-зависимую оболочку, созданную функциями библиотеки времени выполнения (Run-Time-Library, RTL) вокруг реализации SEH операционной системы. В ключевых словах _try, _finally, или _except, нет ничего магического. Группы разработчиков из Microsoft, занимающиеся разработкой операционных систем и компиляторов, определили эти ключевые слова, и то, что они делают. Другие поставщики компиляторов просто поддержали эту семантику. Видимые программисту инструменты SEH уровня компилятора призваны скрыть базовый механизм SEH уровня операционной системы, что позволяет не обнародовать детали функционирования последнего. Основные детали базового механизма SEH уровня ОС будут рассмотрены в этой статье. В статье отражены личные взгляды и предпочтения автора.

Основной смысл SEH состоит в следующем: когда выполняющийся поток совершает ошибку, ОС дает возможность узнать об этом. Точнее, когда поток совершает ошибку, ОС приостанавливает поток, сохраняет все регистры процессора в специальной структуре и из служебного потока, связанного с тем, который вызвал ошибку, вызывает определенную пользователем callback-функцию. Функциональность этой callback-функции в значительной степени не регламентирована, т.е. в процессе своей работы она может делать все, что угодно. Например, она может устранить причину ошибки, если это возможно. Независимо оттого, что эта callback-функция делает, она должна возвратить значение, которое скажет системе, что делать дальше. Эта callback-функция называется exception handler(обработчик исключения). Для того, чтобы быть вызванной:

  1. Функция обработчик исключения должна соответствовать прототипу
  2. Адрес функции обработчика исключения должен быть указан в специальной структуре данных EXCEPTION_REGISTRATION
  3. Структура данных EXCEPTION_REGISTRATION должна располагаться в стеке потока, который вызвал исключение с выравниванием адреса структуры и ее компонентов на адрес, кратный 4 (биты 0 и 1 адреса равны нулю)
  4. Тело функции обработчика исключения не должно располагаться в стеке потока, который вызвал исключение
Технические детали SEH

Прототип функции обработчика исключения:

EXCEPTION_DISPOSITION __cdecl _except_handler( struct _EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, struct _CONTEXT *ContextRecord, void * DispatcherContext );

EXCEPTION_DISPOSITION это макроопределение, имеющее тип int, _EXCEPTION_RECORD содержит информацию о произошедшем исключении, EstablisherFrame — адрес структуры EXCEPTION_REGISTRATION в стеке потока, вызвавшего исключение, _CONTEXT — адрес структуры содержащей все регистры процессора в момент возникновения исключения, DispatcherContext — служебая информация

Структура данных EXCEPTION_REGISTRATION

_EXCEPTION_REGISTRATION struc prev dd ? handler dd ? _EXCEPTION_REGISTRATION ends

Как видно из определения, структура состоит из 2х элементов по 32 бита, prev — адрес структуры с предыдущим обработчиком, handler — адрес функции обработчика исключения. Наличие элемента prev позволяет выстраивать цепочку из обработчиков, адрес последней структуры с актуальным обработчиком доступен через регистр fs:0, отсюда и начинается просмотр и вызов последовательности обработчиков, до тех пор, пока один из них не вернет значение ExceptionContinueExecution (0). Если ни один обработчик из цепочки обработчиков не может обработать исключение, то его обрабатывает первый элемент цепочки — обработчик исключений по умолчанию (стандартный обработчик), у которого нет варианта отказаться от обработки исключения.

SEH это ошибка

Я совершенно уверен в том, что сама изначальная идея SEH ошибочна. Операционная система будет сообщать программе о возникновении незапланированных «исключительных» ситуаций, таких как «деление на 0», «неверный HANDLE», «попытка исполнения неверной инструкции процессора» «попытка доступа к памяти при отсутствии соответствующих разрешений» и так далее. Совершенно нереально исправить такие ошибки во время исполнения программы, ошибка уже случилась, программа уже пошла по неверному пути, который привел ее к этой ошибке. Нельзя уже сделать ничего разумного, но SEH дает возможности:

  1. Скрыть ошибку, заменив стандартный обработчик ошибок своим, и «обработать» исключение
  2. Позволить программе «прожить» немного дольше, сделав вид, что «ничего не случилось»

К сожалению, стандартные обработчики ошибок современных ОС семейства Windows не показывают пользователю ничего, что могло бы информировать его о том, что случилось и что надо делать, после паузы и показа неинформативного окна приложение аварийно закрывается. Моя идея состоит в том, чтобы при возникновении исключения программист должен иметь возможность информировать пользователя об ошибке с помощью специально сформированных сообщений, после чего выполнить минимально возможную «приборку за собой» и постараться корректно закрыть программу. Еще раз напоминаю, что в большинстве случаев нормальное продолжение выполнения программы после возникновения исключения невозможно.

Компилятор GCC

GCC является главным компилятором для сборки ряда операционных систем; среди них — различные варианты Linux и BSD, а также ReactOS, Mac OS X, OpenSolaris, NeXTSTEP, BeOS и Haiku.

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

GCC является лидером по количеству процессоров и операционных систем, которые он поддерживает. Имеет развитые средства для программирования на встроенном ассемблере (ассемблерные вставки). Генерирует компактный и быстрый исполняемый код. Имеет возможности оптимизации, в том числе с учетом ассемблерных вставок. К относительным недостаткам GCC можно отнести непривычный синтаксис AT&T используемый во встроенном ассемблере.

GCC/MinGW является полностью надежным качественным компилятором, который, на мой взгляд, превосходит любой доступный на сегодняшний день компилятор языка Си по качеству сгенерированного кода. Это несколько менее выражено с самыми последними версиями MSVC, но все еще заметно. Особенно для всего, что связано с inline assembly, GCC на мой взгляд, превосходит MSVC.

Соответствие стандартам, как мне кажется, также намного лучше в GCC.

MinGW-W64 компилятор

MinGW— набор инструментов разработки программного обеспечения для создания приложений под Windows. Включает в себя компилятор, родной программный порт GNU Compiler Collection (GCC) под Windows вместе с набором свободно распространяемых библиотек импорта и заголовочных файлов для Windows API. В MinGW включены расширения для библиотеки времени выполнения Microsoft Visual C++ для поддержки функциональности C99.

В связи с тем, что в рамках изначального проекта MinGW не обещалось, что в его кодовую базу будут вноситься обновления, связанные с добавлением некоторых новых ключевых элементов Win32 API, а также наиболее необходимой поддержки 64-битной архитектуры, был создан проект MinGW-w64. Он является новой чистой реализацией портирования GNU Compiler Collection (GCC) под Microsoft Windows, осуществленной изначально компанией OneVision и переданной в 2008 году в общественное пользование (Public Domain). Сначала он был предложен на рассмотрение для интеграции с оригинальным проектом MinGW, но был отклонен в связи с подозрением на использование несвободного или проприетарного кода. По многим серьезным причинам этического характера, связанным с отношением со стороны авторов MinGW, ведущие разработчики кода MinGW-w64 решили больше не пытаться кооперироваться с проектом MinGW.

MinGW-w64 обеспечивает более полную реализацию Win32 API, включая:

  • лучшую поддержку стандарта C99
  • лучшую поддержку pthreads (включая возможность задействовать функциональность стандарта C++11 библиотеки libstdc++ компилятора GCC)
  • GCC multilib
  • точки входа в программу с поддержкой Unicode (wmain/wWinMain)
  • DDK (из проекта ReactOS)
  • DirectX (из проекта WINE)
  • поддержку больших файлов
  • поддержку 64-битной архитектуры Windows
Поддержка SEH в Mingw-w64

Совершенно неудовлетворительна поддержка SEH, проще сказать – ее нет, несмотря на наличие макросов __try1() и __except1. Мало того, что ни синтаксически (поскольку синтаксис __try __except() не поддерживается), ни семантически (макросы __try1 __except1 только позволяют установить/удалить обработчик исключений) невозможно программирование SEH, как с компиляторами Microsoft или Borland/Embarcadero, даже само использование макросов __try1 __except1 может приводить к проблемам

Проблемы

Использование стандартных макросов __try1 и __except1 может приводить к проблемам, так как в этих макросах явно изменяется состояние регистра ESP, но компилятор, который должен вести учет использования стека (что означает, что компилятор всегда должен «знать», каково значение регистра ESP), об этом не уведомляется. Может быть, стандартные макросы будут работать, а может быть и нет.

Решение

Во-первых, однозначно придется отказаться от использования стандартных макросов __try1 и __except1, вместо них будут ассемблерные вставки, не затрагивающие регистр ESP и локальная переменная типа EXCEPTION_REGISTRATION в стеке. Приблизительно вот так:

static int exception=0; EXCEPTION_REGISTRATION seh_ex_reg; seh_ex_reg.handler = (PEXCEPTION_ROUTINE) exception_handler; /*ассемблерная вставка, которая в поле prev записывает адрес предыдущей структуры из fs:0 и устанавливает новый адрес этой структуры в fs:0 */ asm ("\t movl %%fs:0, %%eax; movl %%eax, %0 \n" : "=r" (seh_ex_reg.prev) : : "%eax"); asm volatile("\t movl %0,%%eax; movl %%eax, %%fs:0 \n"::"r" (&seh_ex_reg) : "%eax"); // блок try < // code if(exception == 0) < //ассемблерная вставка: убираем обработчик исключений asm ( // restore previous handler, ESP is not modified "\t movl %0, %%eax \n" "\t movl %%eax, %%fs:0 \n" : :"r" (seh_ex_reg.prev) : "%eax" ); goto end; >> // блок except < trusted_code://сюда мы попадаем при исключении //ассемблерная вставка: убираем обработчик исключений //выполняем очистку >end: exit(); 

Во-вторых, необходимо отделить доверяемый код (т.е., отлаженный, не генерирующий исключений) от недоверяемого (где возможны исключения). Это достаточно стандартная практика, где за блоком try следует блок except С помощью нескольких глобальных переменных, ассемблерных вставок и имеющего дурную славу опрератора goto удалось решить такую задачу. Решение не претендует на универсальность, над этим еще надо думать, пока это выглядит как сваленный в кучу набор трюков. Недостатки: много ассемблерного кода, используются статические переменные, не производится «размотка» стека, состояние локальных переменных в стеке try блока теряется безвозвратно. Корректное завершение программы возможно, используя только переменные и функции из except блока.

От использования статических переменных, впрочем, легко отказаться, для чего придется «расширить» структуру EXCEPTION_REGISTRATION, дополнив ее недостающими элементами, перенести туда все бывшие ранее статическими переменные. Это сделает код примера не намного сложнее, но зато код будет по-настоящему структурным, способным обрабатывать исключения на нескольких уровнях вложенности. Доступ к дополнительным элементам расширенной структуры EXCEPTION_REGISTRATION_EX из функции обработчика исключения осуществляется через параметр EstablisherFrame который нужно преобразовать к соответствующему типу. Заодно сохраним значения регистров ESP и EBP, чтобы восстановить стек фрейм к тому состоянию, которое было в начале блока try. Теперь наш пример обретает законченную форму. К сожалению, при возникновении исключения, содержимое локальных переменных блока try безвозвратно теряется.

  • Программирование
  • Компиляторы
  • C
  • Разработка под Windows

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *