Русский
Русский
English
Статистика
Реклама

Visual studio

Перевод Разработка Diablo IV в Blizzard и отладка дампов памяти из Linux в Visual Studio

18.02.2021 16:06:37 | Автор: admin
В блоге Microsoft недавно была опубликована статья, которую написал Билл Рэндольф, старший инженер-программист Blizzard, занимающийся разработкой Diablo IV. В этой статье раскрыты некоторые особенности работы над Diablo IV и, в частности, рассказано об использовании Visual Studio для отладки кода, рассчитанного на Linux. Сегодня мы предлагаем вашему вниманию перевод этого материала.


Введение


Мы, работая над Diablo IV, пишем весь код в Windows, а потом компилируем его для разных платформ. Это относится и к нашим серверам, которые работают под управлением Linux. (Код включает в себя директивы условной компиляции и, там, где это нужно, в нём есть фрагменты, написанные специально для конкретной платформы.) Наша работа организована именно так по многим причинам. Для начала ключевые профессиональные навыки нашей команды относятся к Windows. Даже наши серверные программисты лучше всего знакомы именно с Windows-разработкой. Мы ценим возможность применения одних и тех же инструментов и одной и той же базы знаний всеми программистами нашей команды.

Ещё одна, самая важная причина того, что мы занимаемся разработкой на Windows, заключается в возможности пользоваться высокофункциональным и надёжным набором инструментов, который даёт нам Visual Studio. И даже если бы мы разрабатывали что-то в Linux, то я могу сказать, что в мире Linux нет ничего такого, что можно было бы хотя бы сравнить с Visual Studio.

Правда, из-за этого мы сталкиваемся с некоторыми сложностями, которые возникают тогда, когда сервер даёт сбой и нам надо отладить дамп памяти. У нас есть возможность удалённого входа в виртуальную машину (или, точнее в контейнер), который дал сбой, мы можем запустить gdb для выяснения причин произошедшего. Но у такого подхода есть множество недостатков. Например мы не разворачиваем бинарные файлы вместе с исходным кодом в результате при работе с виртуальной машиной или с контейнером исходный код в gdb-сессии недоступен.

Ещё одна сложность кроется в самом gdb. Дело в том, что если не пользоваться этим инструментом постоянно, на регулярной основе, его нельзя освоить на таком уровне, который бы нас устраивал. Проще говоря, наши разработчики гораздо охотнее пользовались бы знакомыми инструментами для отладки кода. Так как только 2-3 из наших разработчиков очень хорошо знают gdb, то, когда что-то идёт не так, поисками проблемы занимаются именно они. А это нельзя назвать оптимальным распределением нагрузки на программистов.

Нам всегда хотелось найти такой способ отладки Linux-кода, который отличался бы интуитивной понятностью. Именно поэтому нас так восхищает возможность использования новой возможности Visual Studio, которая позволяет нам решать именно эту задачу в знакомой среде! И вовсе не преувеличением будет сказать, что благодаря этому наша мечта сбылась.


О применяемом нами процессе отладки кода


Отладка Linux-кода в Visual Studio возможна лишь в том случае, если в системе установлена подсистема Windows для Linux (WSL), или тогда, когда в менеджере подключений (Connection Manager) настроено подключение к Linux. Все наши серверные разработчики установили WSL, используя дистрибутив, на котором мы разворачиваем наш проект. Мы запускаем написанный мной скрипт, который устанавливает все инструменты разработки и вспомогательные библиотеки, необходимые для сборки нашего сервера в WSL.

(Ненадолго отвлекусь от нашей основной темы. Мне хотелось бы подчеркнуть, что мы пришли к выводу о том, что WSL это лучшее из существующих окружений, позволяющих разработчикам тестировать изменения в Linux-сборках. Крайне удобно выглядит такая схема работы: переход в WSL, использование команды cd для входа в общую директорию с кодом и сборка проекта прямо оттуда. Это гораздо лучшее решение, чем использование виртуальной машины или даже контейнера. Если вы собираете проекты с использованием CMake, это значит, что вы, кроме того, можете задействовать встроенную в Visual Studio поддержку WSL.)

Немного расскажу о наших сборках. Мы разрабатываем код в Windows и у нас есть Windows-версия нашего сервера, рассчитанная на работу в этой ОС. Это приносит нам пользу при работе над обычными возможностями проекта. Но мы разворачиваем наш серверный код в среде Linux, что требует выполнения сборок на Linux. Linux-сборки создаются на сборочной ферме. Там используется система сборки, работающая на Linux-компьютере. С её помощью собирается наш серверный проект и соответствующий контейнер, который в дальнейшем и развёртывается. Исполняемые файлы, рассчитанные на Linux, разворачиваются только в контейнерах. Обычно у разработчиков нет доступа к этим контейнерам.

Когда один из серверов нашей инфраструктуры даёт сбой, нас об этом уведомляет специальный скрипт, после чего файлы дампа записываются в общую сетевую папку. Для отладки этих файлов, либо в Linux, либо в Visual Studio, необходима работающая программа. При отладке полезно использовать в точности те общие библиотеки, которые применялись в развёрнутом контейнере. Для получения этих файлов мы используем другой скрипт. Сначала мы копируем дамп на локальную машину, а потом запускаем скрипт и передаём ему сведения об этом дампе. Скрипт загружает контейнер Docker, который был собран для исследуемой версии кода, извлекает из него исполняемые файлы нашего сервера, а так же определённые общие библиотеки времени выполнения. Всё это нужно для gdb. (Это, при работе с gdb, позволяет избежать проблем с совместимостью, которые могут возникнуть в том случае, если WSL-версия системы не является точно такой же, как её развёрнутая Linux-версия.) Скрипт, настраивая отладочную сессию, пишет данные в ~/.gdbinit, указывая, что общие библиотеки являются системными библиотеками.

Потом мы переходим в Visual Studio, где и начинается самое интересное. Мы загружаем решение для сборки Windows-версии наших серверов. Затем мы открываем новое диалоговое окно отладки, воспользовавшись командой Debug -> Other Debug Targets -> Debug Linux Core Dump with Native Only. Мы устанавливаем флажок Debug on WSL и вводим пути к файлам дампа и к серверным бинарникам (предназначенным для WSL!). После этого достаточно нажать на кнопку Debug и наблюдать за происходящим.


Запуск отладки в Visual Studio

Visual Studio самостоятельно запускает gdb в WSL. После того, как некоторое время система поработает с диском, выводится стек вызовов программы, давшей сбой, а указатель инструкций устанавливается на соответствующую строку кода. Это, воистину, дивный новый мир!

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

В давние времена, а именно, несколько недель назад, мы применили бы gdb для обратной трассировки всех потоков, а после этого просмотрели бы получившийся список в поиске потока, в стеке вызовов которого, вероятнее всего, произошёл сбой. Например, если поток находился в спящем состоянии, то сбой в нём, скорее всего, не происходил. Нам нужен стек, в котором есть нечто большее, чем несколько кадров и сведения о том, что мы имеем дело со спящим потоком. Далее, нам надо исследовать код для того чтобы понять, что перед нами за проблема. Если это что-то простое это можно увидеть прямо в коде. Если же перед нами проблема посложнее придётся прибегать к возможностям gdb для исследования состояния процесса.

А вот Visual Studio даёт нам значительно более мощные возможности, чем имелись у нас раньше. В многопоточных средах можно открыть в отладочной сессии окно Threads и, пощёлкав по потокам, посмотреть их стеки. Это, правда, очень похоже на подход, используемый в gdb. Поэтому, если надо изучить, скажем, 50 потоков, это может превратиться в довольно трудоёмкую и скучную задачу. К счастью, в Visual Studio есть инструмент, значительно упрощающий эту задачу. Речь идёт об окне Parallel Stacks.

Признаю: большинство из нас не знали о Parallel Stacks до тех пор, пока Эрика Свит и её команда не сказали нам об этом. Если во время работы отладочной сессии выполнить команду Debug -> Windows -> Parallel Stacks будет открыто новое окно, которое выводит сведения о стеке вызовов каждого потока в исследуемом процессе. Это нечто вроде вида с высоты птичьего полёта на всё пространство процесса. По любому кадру стека любого потока можно сделать двойной щелчок. После этого Visual Studio перейдёт в этот кадр и в окне исходного кода, и в окне стека вызовов. Это очень сильно помогает нам экономить время.

После того, как мы видим код, находящийся поблизости от места сбоя, мы можем исследовать переменные с использованием мыши, с помощью QuickWatch, или применив любой другой из множества инструментов Visual Studio. Конечно, в релизных сборках многие переменные подвергаются оптимизации, но, в то же время, многие не подвергаются! Мы, применяя интерфейс Visual Studio, можем выявить проблему гораздо быстрее, чем раньше, используя gdb.



Итоги


Наша команда просто счастлива возможностью отлаживать дампы из Linux в Visual Studio, в окружении, в котором мы занимаемся разработкой. Для нас это серьёзное улучшение, так как это позволяет гораздо большему количеству разработчиков, чем раньше, диагностировать проблемы в естественных условиях их возникновения. Это позволяет всем нам пользоваться мощными отладочными инструментами Visual Studio. После того, как завершена предварительная подготовка рабочей среды, оказаться в отладочной сессии Visual Studio можно буквально за считанные минуты. Эта возможность значительно повышает скорость нахождения проблем и эффективность нашей работы. Благодарю Эрику и её команду за помощь.

Какие возможности Visual Studio вы считаете самыми полезными?

Подробнее..

Мартовские обновления безопасности от Microsoft

18.03.2021 10:09:11 | Автор: admin

В марте компания Microsoft выпустила плановые обновления безопасности, закрывающие 82 уязвимости в своих продуктах, 10 из которых были классифицированы каккритические. Среди закрытых уязвимостей 2 являются 0-day и обнародованы публично, а эксплуатация одной из этих уязвимостей была зафиксирована в реальных атаках.

В данной статье я расскажу о самых главных моментах этого выпуска.

Примечание: помимо плановых обновлений в марте был внеплановый выпуск обновлений безопасности для локальных версий Microsoft Exchange Server 2010, 2013, 2016, 2019. Подробности об этом выпуске можно получить в нашемблоге.

Сводная информация по количеству и типу уязвимостей в соответствующих продуктах приведена на графике ниже.

На следующие уязвимости и обновления безопасности следует обратить особое внимание.

Была закрыта критическая уязвимость удаленного исполнения кодаCVE-2021-26867в гипервизоре Microsoft Hyper-V (CVSS 9.9), которой подвержены все последние версии Windows 10 20H2, 2004, 1909 и Windows Server 20H2, 2004, 1909.

Мартовские обновления также исправляют важную уязвимость повышения привилегийCVE-2021-27077в компонентах Windows Win32k (CVSS 7.8). Она была публично раскрыта исследователями из команды Trend Micro Zero Day Initiative. Данная уязвимость затрагивает все поддерживаемые версии Windows и Windows Server.

Отдельного внимание заслуживает закрытая критическая уязвимость удаленного исполнения кодаCVE-2021-26897в службе сервера разрешения сетевых имен Windows DNS (CVSS 9.8). Уязвимости подвержены все поддерживаемые версии Windows Server c 2012 по 2019.

Также обновления затронули важную уязвимость повышения привилегийCVE-2021-24090в функции создания отчетов об ошибках Windows Error Reporting (CVSS 7.8), которой подвержены все последние версии Windows 10 20H2, 2004, 1909 и Windows Server 20H2, 2004, 1909.

Были закрыты сразу 10 уязвимостей в расширении видеокодека HEVC, наиболее интересной из которых является критическая уязвимость удаленного исполнения кодаCVE-2021-24089(CVSS 7.8). Этот компонент не входит по умолчанию в поставку ОС, поэтому данным уязвимостям подвержены только те системы, в которых пользователь или администратор загрузили и установили данное расширение из магазина Microsoft. Причем приложения из магазина Microsoft обновляются автоматически. Подробнее об этом можно узнать изэтойстатьи.

Замыкает команду лидеров мартовского выпуска критическая уязвимость нулевого дня, уже использующаяся в атаках это критическая уязвимость повреждения памятиCVE-2021-26411в браузере Internet Explorer (CVSS 8.8). Данная уязвимость затрагивает версию браузера IE 11. Подробнее об атаках в этойстатье.

Остальные уязвимости были исправлены в компонентах Microsoft Edge (на движке EdgeHTML), Microsoft Office (приложениях и веб-сервисах), SharePoint Server, Visual Studio, VS Code, Azure Kubernetes Service, Azure Container Instance, Azure Spring Cloud, Azure Service Fabric, Azure Sphere и Power BI Report Server.

Полный список статей базы знаний для соответствующих пакетов обновлений, с которыми связаны потенциальные проблемы при установке, приведен взаметках к выпуску.

Обновления Servicing Stack Updates (SSU) быливыпущеныдля следующих версий ОС: Windows 10 версии 1809, 1909, 2004, 20H2 и Windows Server версии 2019, 1909, 2004, 20H2.

О важных изменениях в жизненном цикле обновлений SSU и объединении в единый накопительный пакет обновлений вы можете прочитать в нашемблоге. О том, как установить сразу и SSU, и обновления безопасности ОС в одном накопительном пакете, автоматически, соблюдая правильную последовательность, читайте в нашемблоге.

Также хочу напомнить, что в марте заканчивается поддержка браузера Microsoft Edge Legacy (на движке EdgeHTML). Все подробности на нашемпортале.

Как всегда самую полную и актуальную информацию об уязвимостях и обновлениях безопасности вы можете найти на нашем порталеSecurity Update Guide. Нам очень интересно узнать ваше мнение о новом портале Security Update Guide, поэтому мы призываем вас поделиться обратной связью о работе портала через этуформу.

Вы также можетепосмотретьзапись нашего ежемесячного вебинара Брифинг по безопасностис более подробным разбором этого выпуска обновлений безопасности Microsoft.

А для того чтобы быть в курсе самых актуальных новостей информационной безопасности Microsoft, подписывайтесь на канал.

Помните, почти 90% всех уязвимостей уже имели патчи от производителей на момент обнародования*, и своевременно обновляйте ваши системы.

Артём Синицын CISSP, CCSP, MCSE, MC: Azure Security Engineer
старший руководитель программ информационной безопасности в странах Центральной и Восточной Европы
Microsoft
Twitter YouTube

Подробнее..

Update Tuesday Microsoft выпустила апрельские обновления безопасности

14.04.2021 14:22:42 | Автор: admin

Microsoft выпустила плановые обновления безопасности, закрывающие 114 уязвимостей, включая 6 уязвимостей в Microsoft Edge и 4 уязвимости в Exchange Server. 19 уязвимостей были классифицированы как Критические и 88 как Важные. Среди закрытых уязвимостей две были обнародованы публично, а эксплуатация одной из этих уязвимостей была зафиксирована в реальных атаках (0-day).

В данной статье я расскажу о самых главных моментах этого выпуска.

Сводная информация по количеству и типу уязвимостей в соответствующих продуктах приведена на графике.

На следующие уязвимости и обновления безопасности следует обратить особое внимание.

Была закрыта критическая уязвимость удаленного исполнения кода CVE-2021-28329 в компонентах среды исполнения RPC), которой подвержены все поддерживаемые версии Windows и Windows Server. Рейтинг CVSS составил 8.8, а согласно индексу эксплуатации у атак с использованием данной уязвимости низкий уровень вероятности.

Апрельские обновления также исправляют важную уязвимость повышения привилегий CVE-2021-28313 в компонентах Windows Diagnostics Hub. Данная уязвимость затрагивает последние версии Windows 10 и Windows Server 20H2, 2004, 1909. Рейтинг CVSS составил 7.8, а согласно индексу эксплуатации у атак с использованием данной уязвимости низкий уровень вероятности.

Также была закрыта важная уязвимость повышения привилегий CVE-2021-28347 в компонентах среды исполнения Windows Speech. Уязвимости подвержены все поддерживаемые версии Windows 10. Рейтинг CVSS составил 7.8, а согласно индексу эксплуатации у атак с использованием данной уязвимости низкий уровень вероятности.

Устранена важная уязвимость удаленного исполнения кода CVE-2021-27091 в компонентах службы RPC Endpoint Mapper, которая была обнародована публично. Данной уязвимости подвержена только ОС Windows Server 2012. Рейтинг CVSS составил 7.8, а согласно индексу эксплуатации у атак с использованием данной уязвимости низкий уровень вероятности.

Также обновления закрывают критическую уязвимость удаленного исполнения кода CVE-2021-27095 в видео-декодере Windows Media, которой подвержены все версии Windows. Рейтинг CVSS составил 7.8, а согласно индексу эксплуатации у атак с использованием данной уязвимости низкий уровень вероятности.

Была закрыта важная уязвимость удаленного исполнения кода CVE-2021-28445 в компонентах Windows Network File System (NFS. Данной уязвимости подвержены все ОС Windows кроме Windows 10 и Windows Server 1803. Рейтинг CVSS составил 8.1, а согласно индексу эксплуатации у атак с использованием данной уязвимости низкий уровень вероятности.

Устранена важная уязвимость удаленного исполнения кода CVE-2021-28451 в приложении Microsoft Excel. Данной уязвимости подвержены Microsoft Office 2019 for Windows/Mac, Microsoft Excel 2013-2016, Microsoft 365 Apps for Enterprise, Microsoft Office Online Server, Microsoft Office Web Apps Server 2013. Рейтинг CVSS составил 7.8, а согласно индексу эксплуатации у атак с использованием данной уязвимости низкий уровень вероятности.

Замыкает команду лидеров апрельского выпуска уязвимость нулевого дня, уже использующуюся в атаках это важная уязвимость повышения привилегий CVE-2021-28310 в компонентах Win32k. Данная уязвимость затрагивает версии Windows 10 и Windows Server 20H2, 2004, 1909, 1809, 1803. Рейтинг CVSS составил 7.8.

Отдельного внимание заслуживают ряд уязвимостей в почтовом сервере Microsoft Exchange. На этот раз затронуты все поддерживаемые версии Exchange Server 2013, 2016, 2019.

Примечание: помимо плановых обновлений в марте был внеплановый выпуск обновлений безопасности для локальных версий Microsoft Exchange Server 2010, 2013, 2016, 2019. Подробности об этом выпуске можно получить в нашем блоге.

Все 4 уязвимости в апрельском выпуске CVE-2021-28480, CVE-2021-28481, CVE-2021-28482, CVE-2021-28483 были классифицированы как Критические, и потенциально позволяют злоумышленнику удаленно выполнить произвольный код на почтовом сервере.

Информация о данных уязвимостях не была обнародована публично и на данный момент не было зафиксировано использование рабочих эксплоитов в реальных атаках. Максимальный рейтинг CVSS среди уязвимостей составил 9.8 из 10 (самый низкий рейтинг 8.8) и согласно индексу эксплуатации у атак с использованием этих уязвимостей высокий уровень вероятности.

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

  • Exchange Server 2013 CU23

  • Exchange Server 2016 CU19/CU20

  • Exchange Server 2019 CU8/CU9

Все подробности вы можете узнать в блоге команды Microsoft Exchange.

Остальные уязвимости были исправлены в компонентах Microsoft Edge (на движке Chromium), Microsoft Office (приложения и веб-сервисы), SharePoint Server, Visual Studio, VS Code, Azure DevOps Server, Azure Sphere, GitHub Pull Requests and Issues Extension и Maven Java Extension.

Полный список статей базы знаний для соответствующих пакетов обновлений, с которыми связаны потенциальные проблемы при установке приведен в заметках к выпуску.

Также хочу напомнить, что в марте закончилась поддержка старой версии браузера Microsoft Edge (на движке EdgeHTML). При установке апрельского накопительного пакета старый браузер будет заменен новой версией Microsoft Edge на движке Chromium. Подробности - в нашем блоге.

Обновления стека обслуживания

Обновления Servicing Stack Updates (SSU) были выпущены для всех поддерживаемых ОС: Windows 10 версии 1809, 1909, 2004, 20H2 и Windows Server версии 2019, 1909.

А для версий 2004, 20H2 обновления SSU теперь поставляются в едином накопительном пакете вместе с остальными обновлениями. О том, как установить сразу и SSU, и обновления безопасности ОС в одном накопительном пакете, автоматически, соблюдая правильную последовательность, читайте в нашем блоге.

Как всегда самую полную и актуальную информацию об уязвимостях и обновлениях безопасности вы можете найти на нашем портале Security Update Guide. Нам очень интересно узнать ваше мнение о новом портале Security Updates Guide, поэтому мы призываем вас поделиться обратной связью о работе портала через эту форму.

Вы также можете посмотреть запись нашего ежемесячного вебинара "Брифинг по безопасности" с более подробным разбором этого выпуска обновлений безопасности Microsoft.

А для того, чтобы быть в курсе самых актуальных новостей информационной безопасности Microsoft, подписывайтесь на канал https://aka.ms/artsin.


Помните, почти 90% всех уязвимостей уже имели патчи от производителей на момент своего обнародования*, поэтому так важно не просто обновлять ваше ПО, но и делать это своевременно.

Автор: Артём Синицын CISSP, CCSP, MCSE, MC: Azure Security Engineer
старший руководитель программ информационной безопасности в странах Центральной и Восточной Европы
Microsoft

Twitter: https://aka.ms/artsin
YouTube: https://aka.ms/artsinvideo

*Vulnerability Review Report by Flexera

Подробнее..

Хакеры создали подставную фирму SecuriElite, чтобы атаковать исследователей безопасности и других хакеров

21.04.2021 16:08:09 | Автор: admin

Сайт несуществующей компании SecuriElite

В январе 2021 года специалисты Google Threat Analysis Group (TAG) рассказали об атаке на исследователей ИТ-безопасности по всему миру. Теперь опубликованы некоторые подробности этой необычной операции.

Злоумышленники использовали новые 0-day, которые срабатывают в последних версиях Windows 10 и Chrome. Кроме того, исследователям предлагали поучаствовать в совместном проекте Visual Studio и по их запросу предоставляли DLL якобы с кодом эксплоита (хэш DLL на VirusTotal). Такой вектор социальной инженерии встречается впервые в мире.

Как показало расследование, хакерская группа контактировала с исследователями безопасности через поддельные аккаунты в социальных сетях Twitter и LinkedIn.



Фейковые профили пользователей LinkedIn и Twitter

Более того, они создали поддельную компанию под названием SecuriElite, которая базируется в Турции и якобы приглашает экспертов по безопасности. Как сообщается, компания предлагает услуги offensive security, включая пентесты, оценку безопасности программного обеспечения и эксплоиты.

В общей сложности Google идентифицировала восемь аккаунтов Twitter и семь профилей LinkedIn, которые участвовали в операции. Блог с интересной информацией на тему ИБ для привлечения целевой аудитории был запущен в 2020 году.


Блог с интересной информацией для привлечения исследователей по безопасности

Для операции были зарегистрированы профили на ряде платформ, включая Telegram, Keybase и Discord, чтобы общаться с исследователями и завоевать их доверие.

14 января 2021 года злоумышленники опубликовали в Twitter и на YouTube видео с демонстрацией эксплоита для недавно закрытой уязвимости в Windows Defender (CVE-2021-1647).



Если кто-то из исследователей по безопасности заглотил наживку, ему предлагали поучаствовать в совместном проекте Visual Studio. Это новый метод социальной инженерии, который ранее ещё не встречался.


Хакеры обещали, что в проекте Visual Studio будет код эксплоита, показанного на видео, и предоставляли DLL, которая исполнялась через Visual Studio Build Events. Сразу после этого она устанавливала соединение с удалённым командным сервером.



Сайт SecuriElite запустили 17 марта 2021 года. До этого атака велась только через блог.



Корейские коллеги уже определили уязвимость 0-day, через которую эксплоит срабатывал в Internet Explorer. О других браузерах информации пока нет.



Кроме сайта, атака велась через официальный блог blog.br0vvnn[.]io. Ранее сообщалось, что эксплоит срабатывает в последних версиях Windows 10 и Chrome со всеми патчами. Сейчас антивирусы уже начали его распознавать.

Если избранных жертв индивидуально приглашают на заражённый сайт, то это таргетированный фишинг. Если жертва сама нашла новый интересный сайт, то это немного похоже на атаку типа watering hole (когда взламывается настоящий сайт, которым пользуется целевая группа). Наверное, в данном случае можно говорить о гибридной технике.

Пока непонятно, с какой целью на компьютеры специалистов устанавливали бэкдоры. Возможно, злоумышленники искали информацию о новых 0-day. Это ценный товар на чёрном рынке. Сведения о багах в популярном ПО продаются за сотни тысяч долларов. Уязвимости эксплуатируются несколько месяцев или лет, пока о них не становится известно широкой публике. Если хакер находит серьёзную уязвимость в Windows или iOS он может обеспечить себе безбедное существование на годы вперёд и пожизненный авторитет в сообществе.

Теоретически, жертвой нацеленной атаки может стать каждый, даже эксперт по безопасности, если он не использует для выхода в интернет отдельный компьютер. Антивирусные программы здесь не помогут, скорее наоборот: зачастую они увеличивают поверхность атаки и ухудшают безопасность системы.

Google Threat Analysis Group опубликовала список аккаунтов в соцсетях, адреса командных серверов (в том числе взломанных чужих серверов, которые использовались как командные), хэши DLL для VS Project и индикаторы компрометации (IOCs).




Подробнее..

SecretStorageVSCodeextensionAPI

12.05.2021 12:08:48 | Автор: admin

ВVSCodeсуществуетнесколькоспособовхранитьнастройкипользователя.Доприходаверсии1.53.0конфиденциальнуюинформациюприходилосьсохранять вMementoобъектахв workspaceState и globalState илинапример keytar. А хранение паролей с токенами в стандартном конфигурационном файле или с помощью переменных окружения, являлось не самой лучшей идеей, так как эти данные могли быть прочитаны и кэшированы другими расширениями.

В статье мы посмотрим на способы чтения данных из settings.json и environment variables. А затем создадим класс с минимальным функционалом, отвечающий за хранение и отдачу ключей со значениями из VSCode SecretStorage.

Проект мы условно назовем fancycolor. Процесс инициализации проекта подробно расписан в документации VSCode Extensions, поэтому сразу приступим к интересному.

settings.json

Все настройки от всех VSCode extensions хранятся в общем файле settings.json и соответственно могут быть доступны из любого расширения. К примеру, из нашего приложения fancycolor мы можем легко прочитать список всех хостов и соответствующие им платформы из нашего конфига другого популярного приложения SSH - Remote.

const configurationWorkspace = workspace.getConfiguration()const sshRemotePlatform: string | undefined = configurationWorkspace.get(  "remote.SSH.remotePlatform")console.log(sshRemotePlatform)

Данный код выведет список вашей конфигурации для расширения SSH - Remote.

Proxy {ubuntu: 'linux', home: 'linux', raspberry: 'linux'}

environment variables

VSCode расширения по умолчанию имеют доступ к переменным окружения пользователя. Все переменные которые вы сохранили в .bashrc в Linux или User.Environment в Windows можно получить с помощью глобального объекта process.env.

Например создадим файл /home/ubuntu/.env с переменной ACCESS_TOKEN_ENV и добавим его в .bashrc.

echo 'export ACCESS_TOKEN_ENV="d8aba3b2-fda0-414a-b867-4798b7892bb4"' >> /home/ubuntu/.envecho "source /home/ubuntu/.env" >> /home/ubuntu/.bashrc

В Windows тоже самое достигается через Powershell.

[System.Environment]::SetEnvironmentVariable('ACCESS_TOKEN_ENV', 'd8aba3b2-fda0-414a-b867-4798b7892bb4', [System.EnvironmentVariableTarget]::User)

Теперь прочитаем его в VSCode fancycolor extension.

import * as process from "process"export const accessTokenEnv = process.env["ACCESS_TOKEN_ENV"]console.log(accessTokenEnv)

В выводе мы видим наш токен.

d8aba3b2-fda0-414a-b867-4798b7892bb4

SecretStorage

На сегодняшний день является лучшим способом хранения паролей, логинов, токенов и другой конфиденциальной информации в VSCode. Для демонстрации создадим простенький класс AuthSettings, где будем хранить fancycolor_token, с минимально необходимыми методами:

  • init для инициализации нашего SecretStorage

  • getter instance

  • storeAuthData для записи в SecretStorage

  • getAuthData для извлечения данных из SecretStorage

import { ExtensionContext, SecretStorage } from "vscode"export default class AuthSettings {private static _instance: AuthSettingsconstructor(private secretStorage: SecretStorage) {}static init(context: ExtensionContext): void {/*Create instance of new AuthSettings.*/AuthSettings._instance = new AuthSettings(context.secrets)}static get instance(): AuthSettings {/*Getter of our AuthSettings existing instance.*/return AuthSettings._instance}async storeAuthData(token?: string): Promise<void> {/*Update values in bugout_auth secret storage.*/if (token) {this.secretStorage.store("fancycolor_token", token)}}async getAuthData(): Promise<string | undefined> {/*Retrieve data from secret storage.*/return await this.secretStorage.get("fancycolor_token")}}

В extension.ts напишем функционал позволяющий добавлять и извлекать токен с помощью команд в Command Palette.

import * as vscode from "vscode"import AuthSettings from "./settings"export function activate(context: vscode.ExtensionContext) {// Initialize and get current instance of our Secret StorageAuthSettings.init(context)const settings = AuthSettings.instance// Register commands to save and retrieve tokenvscode.commands.registerCommand("fancycolor.setToken", async () => {const tokenInput = await vscode.window.showInputBox()await settings.storeAuthData(tokenInput)})vscode.commands.registerCommand("fancycolor.getToken", async () => {const tokenOutput = await settings.getAuthData()console.log(tokenOutput)})}export function deactivate() {}

Останется только в package.json зарегистрировать команды fancycolor.setToken и fancycolor.getToken. В последствии при работе с VSCode SecretStorage, мы сможем обратиться исключительно к конкретному SecretStorage созданному для нашего приложения, которому будет присвоен свой _id: 'undefined_publisher.fancycolor'.

Подробнее..

Улучшения нового редактора Razor в Visual Studio

27.01.2021 16:20:11 | Автор: admin

Прошло шесть месяцев с тех пор, как мы анонсировали первую предварительную версию нового экспериментального редактора Razor для Visual Studio, основанного на общем языковом сервере Razor, и пришло время рассказать о наших успехах. Команда усердно работала над приведением нового редактора Razor в соответствие со старым, исправлением ошибок и добавлением множества замечательных новых функций. Мы думаем, что новый редактор близок к тому, чтобы быть готовым к нормальной повседневной разработке, поэтому сейчас самое время попробовать его с последней предварительной версией Visual Studio. Мы надеемся, что вы попробуете новый редактор Razor, и поделитесь с нами своими впечатлениями!

Начало работы

Чтобы начать работу с новым редактором Razor :

  1. Установите последнююVisual Studio preview (16.9 Preview 3).

    • Заметка: Превью-версии Visual Studio можно безопасно устанавоивать вместе со стабильной установкой Visual Studio .

  2. ПерейдитеTools>Options>Environment>Preview Featuresи выберите опциюEnable experimental Razor editor:

Когда вы собираетесь включить новый редактор Razor, вы можете обнаружить, что он уже включен. Начиная с Visual Studio 16.9 Preview 3, мы постепенно развертываем новый редактор Razor для различных групп пользователей. Если вы опробовали новый редактор ранее, а затем отключили его, вы не будете участвовать в автоматическом внедрении. Вам нужно будет повторно включить его вручную, чтобы увидеть весь прогресс, которого мы достигли. Многие из известных проблем с новым редактором теперь исправлены, поэтому стоит попробовать еще раз, если вы столкнулись с проблемами в более ранних сборках.

Что нового?

В дополнение к работе над основами редактора Razor (завершение, диагностика, всплывающие подсказки, раскраска синтаксиса и т. д.) команда добавила в новый редактор Razor ряд новых функций. Многие из этих функций стали возможными или их получилось проще реализовать благодаря новой архитектуре, основанной на протоколе языкового сервера (LSP).

Улучшенное форматирование

В новом редакторе Razor есть улучшенный механизм форматирования, который более консервативен, чем старый (во-первых, не навреди!), а также намного умнее в области обработки кода.

Мы стремимся исправить форматирование Razor, чтобы оно заставляло вас улыбаться с новым редактором, поэтому сообщите нам, если у вас возникнут проблемы с форматированием, и мы обязательно их исправим.

C# code actions

Некоторые действия кода C# теперь доступны в файлах Razor:

  • Добавьте директивы @using или полные имена типов.

  • Добавьте null checks.

Дизайн нового редактора Razor значительно упрощает включение действий кода C#, и мы ожидаем, что в будущих выпусках будет доступно гораздо больше.

Переименовывание в закрытых файлах

Переименование больше не ограничивается открытыми файлами Razor. Имена в закрытых файлах Razor также будут обновлены.

Переименовывание компонентов Blazor

Теперь вы можете переименовать компонент Blazor из его тега. Компонентный файл Razor будет переименован автоматически.

Действия кода компонента

Также теперь доступны несколько действий кода для конкретных компонентов:

  • Создать компонент из неизвестного тега.

  • Извлечь @code в код программной части.

  • Добавить @using для компонентов или полностью квалифицированный тег компонента.

Перейти к определению компонента

Вам нужно быстро увидеть код этого компонента? Просто нажмите F12 на теге, и вы на месте!

Изменение Razor с LiveShare

Новый редактор Razor также работает с LiveShare, поэтому вы получите все новые возможности редактирования Razor даже при работе с Razor в удаленном сеансе.

Используйте новый редактор Razor с Visual Studio Code

Поскольку новый редактор Razor основан на переиспользуемом языковом сервере Razor, новый редактор Razor и его новые функции также доступны в Visual Studio Code с установленным расширением C#.

А как насчет Visual Studio для Mac? Visual Studio для Mac пока не поддерживает LSP, но как только поддержка появится, мы добавим новый редактор Razor в Visual Studio для Mac.

Улучшения подсветки синтаксиса Razor

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

Ждем вашу обратную связь

Если у вас возникла проблема с новым редактором, лучший способ сообщить нам об этом - использовать функциюSend Feedback > Report a Problemв Visual Studio.

Подробнее..

Работа с большими решениями .NET 5 в Visual Studio 2019 16.8

10.02.2021 10:11:22 | Автор: admin

С выпуском .NET 5 миграция решений из .NET Framework увеличилась. В частности, мы начали наблюдать перемещение очень крупных решений. Чтобы обеспечить максимальное удобство, мы работали над оптимизацией Visual Studio для обработки решений, содержащих большое количество проектов .NET 5 и .NET Core. Многие из этих оптимизаций были включены в версию 16.8, и в этом посте рассматриваются внесенные нами улучшения.

Запуск компилятора C# и VB вне процесса

Roslyn, компилятор C# и Visual Basic, парсит и анализирует все решение для поддержки служб, таких как IntelliSense, Go to Definition и диагностика ошибок. В результате Roslyn имеет тенденцию потреблять ресурсы, которые увеличиваются пропорционально размеру открытого решения, что может стать весьма значительным для больших решений. Команда Roslyn уже работала над минимизацией этого воздействия, активно кэшируя информацию на диске, которая не требуется немедленно, но даже при таком кэшировании нельзя избежать необходимости хранить данные в памяти.

Чтобы уменьшить влияние на более крупные решения Visual Studio, команда Roslyn приложила значительные усилия, чтобы вывести компилятор Roslyn из процесса Visual Studio в его собственный процесс. Запуск Roslyn в собственном процессе освобождает ресурсы в самой Visual Studio и дает компилятору Roslyn больше места для выполнения своей работы. Для больших решений это может сэкономить до трети памяти, потребляемой Visual Studio при открытии большого решения.

Оптимизация узла зависимостей

Каждый проект .NET 5 и .NET Core имеет узел в обозревателе решений с именем Dependencies, который отображает все, от чего зависит проект: другие проекты, сборки, пакеты NuGet и т.д. В дополнение к отображению непосредственных зависимостей проекта, узел также показывает транзитивные зависимости проекта, т.е. все, от чего зависит каждая зависимость, и так далее. Для проекта любого разумного размера этот список транзитивных зависимостей может стать довольно большим.

К сожалению, первоначальная реализация узла Dependencies не была очень эффективной в том смысле, что она хранила информацию о переходных зависимостях в памяти. В нем содержалось гораздо больше информации, чем было необходимо, и большая часть данных была избыточной. Мы переписали код, чтобы сохранить только ту информацию, которая абсолютно необходима, и начали использовать существующую информацию о зависимостях, которая уже хранится в NuGet. Эта перезапись сэкономила до 1015% памяти, потребляемой Visual Studio при открытии большого решения.

Уменьшение дублирования информации в MSBuild

После Roslyn одним из других основных потребителей ресурсов в процессе Visual Studio является MSBuild. Это связано с тем, что в качестве механизма сборки большая часть среды IDE основана на объектной модели MSBuild. Хотя мы сделали сами файлы проектов намного меньше в .NET 5 и .NET Core, существует значительное количество вспомогательных файлов проектов, которые импортируются в проекты через SDK. Оценка всех этих файлов необходима для понимания и построения проекта и может потреблять до трети памяти, нужной Visual Studio при открытии большого решения.

Хотя файлы проекта генерируют много данных, большая часть этих данных повторяется, и мы начали дедупликацию этих данных в памяти. Строки - один из наиболее распространенных побочных продуктов системы проектов, и они хранят такую информацию, как имена файлов, параметры и пути. В частности, пути могут быть довольно длинными и потреблять много памяти, если их слишком много или они дублируются слишком много раз. Обеспечено хранение только одной копии строки, что позволяет сэкономить до 510% памяти, потребляемой Visual Studio при открытии большого решения.

Уменьшение количества копий проекта, удерживаемых системой проектов

Одним из важных аспектов проектирования системы проектов .NET 5 и .NET Core является асинхронность. Часто системе проекта требуется выполнять работу в ответ на действие пользователя (например, добавление новой ссылки в проект). Вместо того, чтобы блокировать Visual Studio, пока она завершает свою работу, система проектов позволяет пользователю продолжать работу в среде IDE и выполнять работу в фоновом режиме.

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

Улучшения загрузки большого решения

Проделав всю эту работу, мы значительно оптимизировали работу с большими решениями .NET 5 и .NET Core. Начиная с версии 16.8, во многих наших тестах мы наблюдали увеличение в 2,5 раза размера решения, которое мы можем открыть, прежде чем столкнуться с проблемами ресурсов. Мы также наблюдаем снижение до 25% сбоев, сообщаемых из-за исчерпания ресурсов.

Перечисленные выше улучшения - это только начало изменений, которые мы вносим для улучшения работы с большими решениями в Visual Studio. Производительность отдельных решений по-прежнему может варьироваться в зависимости от размера решения, типа проектов, загруженных расширений и т.д., И есть области, которые мы ищем для улучшения. Мы рекомендуем всем пользователям, у которых возникают проблемы с медленной загрузкой или сбоями при загрузке решений, обращаться к нам по адресу vssolutionload@microsoft.com, чтобы мы могли продолжать улучшать загрузку решений всех типов!

Подробнее..

О поиске утечек памяти в СQt приложениях

16.02.2021 14:15:09 | Автор: admin

Каждый программист, работающий с языком С++, должен уметь находить утечки памяти. Язык С++ - сложный язык, делать ошибки легко, а находить их бывает муторно. Особенно это касается утечек памяти. Ситуация с отловом утечек памяти только усугубляется, если в коде С++ используется библиотека Qt.

Эта статья посвящена разным инструментам, которые можно с той или иной степенью успешности применять для отлова утечек памяти в С++/Qt приложениях (desktop). Инструменты будут рассмотрены в связке с IDE Visual Studio 2019. В статье будут рассмотрены не все возможные инструменты, а лишь наиболее популярные и эффективные.

Наша команда давно и пристально изучает подобные инструменты и использует их в своей работе. Объем кода, на котором есть возможность проверить подобные инструменты, составляет около 1.5 миллиона строк. Опираясь на большой практический опыт, мы расскажем о плюсах и минусах разных инструментов, расскажем, что они способны найти, а что не по зубам, расскажем о неочевидных нюансах и, главное, составим сводную сравнительную таблицу по реальному примеру. Мы постараемся максимально быстро и просто ввести в курс дела (показать быстрый старт), потому даже если ты, читатель, никогда не занимался поиском утечек памяти, эта статья поможет за пару часов разобраться и найти свою первую утечку. Поехали!

В чем проблема?

Утечка памяти ситуация, когда память была выделена (например, оператором new) и ошибочно не была удалена соответствующим оператором/функцией удаления (например, delete).

Пример 1.

int* array = nullptr;for (int i = 0; i < 5; i++){array = new int[10];}delete[] array;

Здесь налицо утечка при выделении памяти для первых 4 массивов. Утекает 160 байт. Последний массив удаляется корректно. Итак, утечка строго в одной строке:

array = new int[10];

Пример 2.

class Test{public:Test(){a = new int[100];b = new int[300];}~Test(){delete[] a;delete[] b;}private:int* a;int* b;};int main(){Test* test = new Test;return 0;}

Здесь утечек уже больше: не удаляется память для a (400 байт), для b (1200 байт) и для test (16 байт для x64). Впрочем, удаление a и b в коде предусмотрено, но его не происходит из-за отсутствия вызова деструктора Test. Таким образом, утечек три, но ошибка, приводящая к этим утечкам, всего одна, и она порождается строкой

Test* test = new Test;

При этом в коде класса Test ошибок нет.

Пример 3.

Пусть есть класс Qt, примерно такой:

class InfoRectangle : public QLabel{Q_OBJECTpublic:InfoRectangle(QWidget* parent = nullptr);private slots:void setInfoTextDelayed();private:QTimer* _textSetTimer;};InfoRectangle::InfoRectangle(QWidget* parent): QLabel(parent){_textSetTimer = new QTimer(this);_textSetTimer->setInterval(50);connect(_textSetTimer, &QTimer::timeout, this, &InfoRectangle::setInfoTextDelayed);}void InfoRectangle::setInfoTextDelayed(){// do anythingsetVisible(true);}

Пусть также где-то в коде затесалось выделение памяти:

InfoRectangle* rectangle = new InfoRectangle();

Будет ли являться это утечкой, если явно не вызван delete? Это зависит от того, включен ли объект в иерархию объектов Qt. Если объект включён одним из следующих примерных вызовов, то нет, не утечка:

mnuLayout->addWidget(rectangle);rectangle->setParent(this);

В остальных же случаях утечка. Причем если мы будем считать точное количество утечек в этом примере, то можем наткнуться на неожиданный вывод: утечек больше, чем можно сначала предположить. Очевидная утечка выделение памяти для InfoRectangle. Побочная утечка выделение памяти для QTimer, несмотря на включение объекта _textSetTimer в иерархию объектов Qt. А вот утечка, которая совсем не очевидна вызов функции connect.

Дело в том, что в ее реализации вызовом new всё же создается некий объект:
template <typename Func1, typename Func2>    static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,                const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot,                Qt::ConnectionType type = Qt::AutoConnection)    {        typedef QtPrivate::FunctionPointer<Func1> SignalType;        typedef QtPrivate::FunctionPointer<Func2> SlotType;        const int *types = nullptr;        if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)            types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();        return connectImpl(sender, reinterpret_cast<void **>(&signal),                           receiver, reinterpret_cast<void **>(&slot),                           new QtPrivate::QSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,                                          typename SignalType::ReturnType>(slot),                            type, types, &SignalType::Object::staticMetaObject);    } 

Таким образом, утечки памяти могут обнаруживаться в весьма неожиданных местах. А могут и вовсе не обнаруживаться, в зависимости от используемого инструментария. К примеру, если инструментарий не способен проникнуть внутрь кода Qt, то он не сможет ни обнаружить утечку в connect, ни разобраться с иерархиями Qt, а последнее, в свою очередь, уже чревато ложными срабатываниями.

Зафиксируем еще один важный момент: причина утечки одна, а самих утечек при этом может быть много. Этот нюанс важен при обсуждении инструментариев по отлову утечек. Идеальный инструментарий тот, который, не давая ложных срабатываний и не пропуская утечек, указывает именно на первопричины утечек, то есть на каждую причину выдает ровно одну строку кода, ей соответствующую (а не целую кучу). То есть делает так, как делал бы человек. Забегая вперед, скажем, что таких инструментариев на данный момент не существует.

Раз их не существует, то как сравнивать между собой разные, не всегда коррелирующие результаты поиска утечек, полученные разными реальными инструментами? Мы ведь хотим сравнения

Для этого мы взяли реальный пример конкретную ревизию репозитория, для которой было точно известно, что утечки есть, и начали подробно с ней работать. Мы взяли один типичный сценарий работы пользователя с нашим приложением и начали на нём запускать все возможные динамические инструменты отлова утечек. Запускали многократно с разными настройками, детально анализируя полученные отчеты об ошибках. В итоге сформировали итоговый список ошибок в коде, приведших к утечкам памяти. Этот список назвали эталонным и посчитали, что других ошибок (ненайденных) нет. И в дальнейшем результаты, полученные каждой отдельной утилитой поиска утечек, сравнивали с эталонным списком ошибок.

Проект

Размер кода

Сценарий работы пользователя

Ревизия репозитория

Кол-во ошибок в эталоне

Суммарный объем утекающей памяти

Конкретный проект

1.5 млн строк

Конкретный сценарий: запускаем ПО, жмем на кнопку 1, потом на кнопку 2, ждем завершения вычислений, закрываем ПО

конкретная

7

253 кБ

Таблица 1. Эталон поиска утечек памяти.

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

Intel Inspector

Intel Inspector графическая утилита, удобно встраиваемая в Visual Studio и позволяющая в виде кликабельного списка выдавать места в коде с предполагаемыми утечками оперативной памяти проверяемого приложения и некоторыми другими проблемами памяти. В сценарии отлова утечек памяти Intel Inspector использует динамический анализ, а это значит, что если в процессе работы приложения код с утечками памяти не будет вызван, то и проблем в нем не будет найдено.

Установка

Intel Inspector входит в состав пакета Intel Parallel Studio 2019, при этом есть возможность установить только сам Intel Inspector, убрав галочки с остальных компонентов дистрибутива при установке. Visual Studio 2019 должна быть закрыта в момент установки Intel Parallel Studio. После установки, Intel Inspector будет автоматически встроен в Visual Studio и должен появиться на панели инструментов (рис. 1).

Рис. 1. Начало работы с Intel Inspector`омРис. 1. Начало работы с Intel Inspector`ом

Если значок Intel Inspectorа не виден на панели инструментов, нужно щёлкнуть правой кнопкой мыши где-нибудь на этой панели инструментов и поставить галочку Intel Inspector.

Запуск

При нажатии на кнопку-значок появится вкладка Intel Inspector с выбором глубины анализа. Выбираем первый пункт Detect Leaks и включаем все галочки, соответствующие всем видам анализа (рис. 2). Если какие-то галочки пропустить, то, к сожалению, есть риск, что не все утечки будут найдены.

Рис. 2. Вкладка Intel Inspector`а для его настройки и запускаРис. 2. Вкладка Intel Inspector`а для его настройки и запуска

Далее нажимаем кнопку Start, через некоторое время откроется приложение. В нем нужно запустить тот или иной сценарий работы, а лучше все сразу (то есть, как следует погонять приложение), затем закрыть. Чем больше на разных параметрах, в разных режимах и в разных сценариях проработает приложение, тем больше утечек памяти будет найдено. И это общий принцип для всех механизмов поиска утечек, использующих динамический анализ. Как мы уточнили ранее, в целях сравнения мы запускали только эталонный сценарий тестирования (см. табл. 1). Итак, после закрытия приложения Intel Inspector слегка задумывается и в итоге выдаёт отчёт следующего вида (рис. 3):

Рис. 3. Пример результатов анализа ПО на утечки памяти с помощью Intel Inspector.Рис. 3. Пример результатов анализа ПО на утечки памяти с помощью Intel Inspector.

В отчете выдаются кликабельный и сортируемый список утечек, размеры утечек, места в коде с утечками, call-stack и многое другое. Короче, форма выдачи результатов весьма и весьма на уровне. Все очень быстро понимается и усваивается. Все это внутри IDE!

Это будет работать, если есть отладочная информация. То есть debug работать будет, а release нет. В С++-приложениях часто бывает так, что работа в режиме debug намного медленнее, чем в release (мы фиксировали разницу в скорости до 20 раз), и пользоваться debug'ом очень некомфортно. Однако на этот случай есть лайфхак собрать версию release (быструю, со всеми ключами оптимизации), дополнительно включив в нее отладочную информацию. Это позволяет Intel Inspector'у подсветить строки в исходном коде, где он предполагает наличие утечек. О том, как включить в release отладочную информацию, написано здесь.

Результаты

Мы провели сравнение скоростных характеристик работы приложения в разных режимах работы: с Intel Inspector (будем называть его Инспектор) и без него, в debug и release. Тестирование проводилось на эталонном примере (см. табл 1).

Конфигурация

Среднее время теста, с

Замедление
работы, что привносит Инспектор, раз

Без Инспектора

С Инспектором

Release c отладочной информацией

10

70

7

Debug

101

973

9,6

Таблица 2. Время тестирования с учётом работы Intel Inspector`а

По таблице можно видеть, что проверка на утечки памяти требует весьма существенного времени. Особенно этот факт начинает играть существенными красками в свете непрерывной интеграции. То есть, если, к примеру, тот сценарий, на котором мы проверяли, включен в состав тестов регрессионного тестирования, то он в них выполняется за 10 секунд. Если же мы захотим на этом же сценарии прогонять поиск утечек памяти (в debug), то это займет примерно в 100 раз больше времени. Прогонять каждую ночь (а тем более, по каждому коммиту) тесты становится невозможно.

Самое главное что можно сказать по качеству найденных утечек? Действительно ли они являются утечками? Нет ли утечек, не замеченных Intel Inspector`ом?

Конфигурация

Кол-во ошибок в эталоне: n

Найдено утечек

Пропущено ошибок из эталона: r

Точность: (n-r)/n

Избыточность: N/n

Всего: N

Верных

Ложных

Release c отладочной информацией

7

192

168

24

0

1 (100%)

27 раз

Debug

7

129

107

22

0

1 (100%)

18 раз

Таблица 3. Результаты работы Intel Inspector

Да, Intel Inspector действительно способен найти реальные утечки памяти. Это долго и мучительно, но он их находит. Пропусков утечек памяти мы не зафиксировали. При этом в итоговом отчете, который формирует Intel Inspector, бывает так, что на каждую строчку кода, где реально совершена ошибка, выводится куча строчек, которые породились этой ошибкой (как в примерах 2 и 3, см. выше).

Если ликвидировать все такие реальные ошибки, то Intel Inspector все равно будет показывать еще немало утечек, и все они ложные. Более того, по таблице видно, что этих ложных срабатываний в release больше, чем в debug. И в этом случае, судя по всему, сработала оптимизация при компиляции она скрыла от Инспектора некоторые детали, и Инспектор запутался.

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

Пример 1. Утечки в системных dll.

Intel Inspector может обнаружить вот такие вот странные утечки в подгружаемых системных dll, с таким интересным стеком. К проверяемому нами коду такие утечки вообще отношения не имеют, даже если по факту там утечки и есть.

Рис. 4. Утечки в системных dll.Рис. 4. Утечки в системных dll.

Пример 2. aligned_malloc.

m_pVitData = (VITDEC_DATA*)_aligned_malloc(sizeof(VITDEC_DATA), 16);m_pDcsnBuf = (byte*)_aligned_malloc(64 * (VITM6_BUF_LEN + VITM6_MAX_WND_LEN), 16);..._aligned_free(m_pDcsnBuf);_aligned_free(m_pVitData);

К счастью, подобная "утечка" находится только в release, а в debug нет.

Пример 3. Pragma.

#pragma omp parallel for schedule(dynamic)for (int portion = 0; portion < portionsToProcess; ++portion){}

Утечка показывается именно в строке с директивой #pragma!

Возможно, какими-то настройками (внутри Intel Inspector, внутри VS, переменные окружения и т.д.) можно победить этот вал ложных утечек, но из коробки точно нет. Возможно также, что на маленьких и простых приложениях (<50000 строк кода) таких проблем с Intel Inspector не будет. На серьезных же приложениях точно будут, к гадалке не ходи.

Вывод

Intel Inspector штука довольно удобная и полезная, способная найти все утечки (если прогнать все сценарии), выдающая относительно немного ложных срабатываний. Работа в конфигурации release с отладочной информацией довольно быстра, но выдает больше ложных срабатываний (а значит, больше ручной работы по их проверке), чем debug. При этом работа в конфигурации debug фантастически медленна.

Что касается стабильности работы, то Intel Inspector здесь не может показать выдающиеся результаты. Иногда в процессе тестирования бывают падения, иногда зависания, причем на ровном месте. Иногда нам попадались такие важные для нас проекты и сценарии работы пользователя, когда вообще не получалось дажезавести Intel Inspector, не то, что доехать на нём до получения результатов.

Visual Leak Detector

Visual Leak Detector (далее VLD) маленькая библиотека, включаемая в исходный код каждого проекта и выводящая в окно Output (IDE Visual Studio 2019) отчёт по утечкам памяти.

Установка

  1. Убедиться, что Visual Studio не запущена.

  2. Перед установкой VLD нужно сначала удалить старый VLD, если такой есть, через Панель управления, т.к. предлагаемая автоматическая деинсталляция старой версии не всегда работает.

  3. Далее установить последний VLD (на момент написания статьи vld-2.5.1-setup.exe) по умолчанию, оставив при установке все галочки включёнными (на добавление в Path и встраивание в Visual Studio). Установщик можно скачать отсюда.

  4. На момент написания статьи в дистрибутиве VLD нет нужных dll-файлов для работы с Visual Studio 2019, потому необходимо скопировать dbghelp.dll из папки C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\Extensions\Cpp\x64 в папку C:\Program Files (x86)\Visual Leak Detector\bin\Win64.

  5. Нужно создать заголовочный файл примерно со следующим содержанием:

    #pragma once//#define LEAKS_DETECTION#ifdef LEAKS_DETECTION#include <vld.h>#endif
    

    Как видно, пока что это пустой файл, проверка на утечки памяти в нем выключена.

  6. В любой файл реализации (сpp) нужно включить этот новый заголовочник. Это нужно сделать только для одного файла внутри проекта, и для каждого проекта в solution.

Запуск

Достаточно раскомментировать в заголовочном файле строчку

#define LEAKS_DETECTION

и собрать solution. После этого можно запускать (F5) приложение и прогонять разные сценарии, где могут быть утечки памяти. Запускать можно только в конфигурации debug. Release c отладочной информацией работать не будет.

После закрытия проверяемого приложения VLD выведет отчет в окно Output. Отчет содержит список утечек, кликабельный call-stack по каждой утечке, размеры утечек.

Пример того, что выводит VLD
---------- Block 652047 at 0x0000000027760070: 8787200 bytes ----------  Leak Hash: 0x02B5C300, Count: 1, Total 8787200 bytes  Call Stack (TID 30996):    ucrtbased.dll!malloc()    d:\agent\_work\63\s\src\vctools\crt\vcstartup\src\heap\new_array.cpp (29): SniperCore.dll!operator new[]()    D:\SOURCE\SAP_Git\sap_win64\core\alg\fbg\ddec\S2Ldfg.cpp (445): SniperCore.dll!CS2Ldfg::CreateLLRTbls() + 0xD bytes    D:\SOURCE\SAP_Git\sap_win64\core\alg\fbg\ddec\S2Ldfg.cpp (217): SniperCore.dll!CS2Ldfg::SetModeEB()    D:\SOURCE\SAP_Git\sap_win64\core\alg\fbg\ddec\S2Ldfg.cpp (1447): SniperCore.dll!CS2Ldfg::Set() + 0xA bytes    D:\SOURCE\SAP_Git\sap_win64\core\alg\fbg\ddec\ddec.cpp (509): SniperCore.dll!DFBase::instanceS2Dec()    D:\SOURCE\SAP_Git\sap_win64\core\alg\fbg\ddec\ddec.cpp (58): SniperCore.dll!DFBase::DFBase() + 0xF bytes    D:\SOURCE\SAP_Git\sap_win64\core\alg\fbg\ddec\ddec.cpp (514): SniperCore.dll!DgbS5FecAnlzr::DgbS5FecAnlzr() + 0xA bytes    D:\SOURCE\SAP_Git\sap_win64\core\alg\fbg\fbganalyser.cpp (45): SniperCore.dll!TechnicalLayer::FBGAnalyser::FBGAnalyser() + 0x21 bytes    D:\SOURCE\SAP_Git\sap_win64\core\engine\handlers\fbganalysishandler.cpp (218): SniperCore.dll!TechnicalLayer::FBGAnalysisHandler::init() + 0x2A bytes    D:\SOURCE\SAP_Git\sap_win64\core\engine\handlers\fbganalysishandler.cpp (81): SniperCore.dll!TechnicalLayer::FBGAnalysisHandler::enqueueRequest()    D:\SOURCE\SAP_Git\sap_win64\core\engine\threadedhandler2.cpp (57): SniperCore.dll!TotalCore::ThreadedHandler2::run()    Qt5Cored.dll!QTextStream::realNumberPrecision() + 0x89E8E bytes    kernel32.dll!BaseThreadInitThunk() + 0xD bytes    ntdll.dll!RtlUserThreadStart() + 0x1D bytes  Data:    00 00 00 00    01 01 01 01    01 01 01 02    02 02 02 02     ........ ........    02 02 03 03    03 03 03 03    03 04 04 04    04 04 04 04     ........ ........    05 05 05 05    05 05 05 05    06 06 06 06    06 06 06 07     ........ ........    07 07 07 07    07 07 08 08    08 08 08 08    08 09 09 09     ........ ........    09 09 09 09    0A 0A 0A 0A    0A 0A 0A 0B    0B 0B 0B 0B     ........ ........    0B 0B 0C 0C    0C 0C 0C 0C    0C 0D 0D 0D    0D 0D 0D 0D     ........ ........    0E 0E 0E 0E    0E 0E 0E 0E    0F 0F 0F 0F    0F 0F 0F 10     ........ ........    10 10 10 10    10 10 11 11    11 11 11 11    11 12 12 12     ........ ........    EE EE EE EE    EF EF EF EF    EF EF EF F0    F0 F0 F0 F0     ........ ........    F0 F0 F1 F1    F1 F1 F1 F1    F1 F2 F2 F2    F2 F2 F2 F2     ........ ........    F3 F3 F3 F3    F3 F3 F3 F3    F4 F4 F4 F4    F4 F4 F4 F5     ........ ........    F5 F5 F5 F5    F5 F5 F6 F6    F6 F6 F6 F6    F6 F7 F7 F7     ........ ........    F7 F7 F7 F7    F8 F8 F8 F8    F8 F8 F8 F9    F9 F9 F9 F9     ........ ........    F9 F9 FA FA    FA FA FA FA    FA FB FB FB    FB FB FB FB     ........ ........    FC FC FC FC    FC FC FC FC    FD FD FD FD    FD FD FD FE     ........ ........    FE FE FE FE    FE FE FF FF    FF FF FF FF    FF 00 00 00     ........ ........---------- Block 2430410 at 0x000000002E535B70: 48 bytes ----------  Leak Hash: 0x7062B343, Count: 1, Total 48 bytes  Call Stack (TID 26748):    ucrtbased.dll!malloc()    d:\agent\_work\63\s\src\vctools\crt\vcstartup\src\heap\new_scalar.cpp (35): SniperCore.dll!operator new() + 0xA bytes    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.28.29333\include\xmemory (78): SniperCore.dll!std::_Default_allocate_traits::_Allocate()    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.28.29333\include\xmemory (206): SniperCore.dll!std::_Allocate<16,std::_Default_allocate_traits,0>() + 0xA bytes    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.28.29333\include\xmemory (815): SniperCore.dll!std::allocator<TotalCore::TaskResult *>::allocate()    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.28.29333\include\vector (744): SniperCore.dll!std::vector<TotalCore::TaskResult *,std::allocator<TotalCore::TaskResult *> >::_Emplace_reallocate<TotalCore::TaskResult * const &>() + 0xF bytes    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.28.29333\include\vector (708): SniperCore.dll!std::vector<TotalCore::TaskResult *,std::allocator<TotalCore::TaskResult *> >::emplace_back<TotalCore::TaskResult * const &>() + 0x1F bytes    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.28.29333\include\vector (718): SniperCore.dll!std::vector<TotalCore::TaskResult *,std::allocator<TotalCore::TaskResult *> >::push_back()    D:\SOURCE\SAP_Git\sap_win64\include\core\engine\task.h (119): SniperCore.dll!TotalCore::LongPeriodTask::setTmpResult()    D:\SOURCE\SAP_Git\sap_win64\include\core\engine\discretestephandler.h (95): SniperCore.dll!TotalCore::DiscreteStepHandler::setResult()    D:\SOURCE\SAP_Git\sap_win64\core\engine\handlers\prmbdtcthandler.cpp (760): SniperCore.dll!TechnicalLayer::PrmbDtctHandler::setContResult() + 0x1A bytes    D:\SOURCE\SAP_Git\sap_win64\core\engine\handlers\prmbdtcthandler.cpp (698): SniperCore.dll!TechnicalLayer::PrmbDtctHandler::processPortion()    D:\SOURCE\SAP_Git\sap_win64\core\engine\threadedhandler2.cpp (109): SniperCore.dll!TotalCore::ThreadedHandler2::tryProcess()    D:\SOURCE\SAP_Git\sap_win64\core\engine\threadedhandler2.cpp (66): SniperCore.dll!TotalCore::ThreadedHandler2::run()    Qt5Cored.dll!QTextStream::realNumberPrecision() + 0x89E8E bytes    kernel32.dll!BaseThreadInitThunk() + 0xD bytes    ntdll.dll!RtlUserThreadStart() + 0x1D bytes  Data:    10 03 51 05    00 00 00 00    B0 B4 85 09    00 00 00 00     ..Q..... ........    60 9D B9 08    00 00 00 00    D0 1B 24 06    00 00 00 00     `....... ..$.....    30 B5 4F 11    00 00 00 00    CD CD CD CD    CD CD CD CD     0.O..... ........

В конце отчёта присутствует краткий итог в виде:

Visual Leak Detector detected 383 memory leaks (253257876 bytes).Largest number used: 555564062 bytes.Total allocations: 2432386151 bytes.Visual Leak Detector is now exiting.

Или, если утечек нет,

No memory leaks detected.Visual Leak Detector is now exiting.

Результаты

Мы провели сравнение скоростных характеристик работы приложения в конфигурации debug в разных режимах работы: с VLD и без него. Как было сказано, в конфигурации release (пусть даже и с отладочной информацией) vld работать не может. В табл. 4 замеры времени выполнения для release приводятся исключительно для сравнения с debug. Тестирование проводилось на эталонном примере (см. табл. 1).

Конфигурация

Среднее время теста, с

Замедление работы, что привносит VLD, раз

Без VLD

С VLD

Debug

101

172

1,7

Release c отладочной информацией

10

-

-

Таблица 4. Время тестирования с учётом работы VLD

Что можно сказать по качеству найденных утечек? Действительно ли они являются утечками? Нет ли утечек, не замеченных VLD?

Конфигурация

Кол-во ошибок в эталоне: n

Найдено утечек

Пропущено ошибок из эталона: r

Точность: (n-r)/n

Избыточность: N/n

Всего: N

Верных

Ложных

Debug

7

185

185

0

0

1 (100%)

26 раз

Таблица 5. Результаты работы VLD

Да, VLD находит реальные утечки памяти. Пропусков утечек памяти мы не зафиксировали. При этом в итоговом отчете, который формирует VLD, бывает так, что на каждую строчку кода, где реально совершена ошибка, выводится очень большая куча строчек, которые породились этой ошибкой (как в примерах 2 и 3, см. выше). Из-за того, что эти утечки нельзя никак сортировать (или группировать), оказывается не очень приятно работать с такой большой плоской простыней. Да и вообще, как поначалу можно доверять тому списку утечек, где фигурирует такая вот утечка:

connect(arrowKeyHandler, &ArrowKeyHandler::upPressed,[this] { selectNeighbourSignal(TopSide); }); 

Потом, разбираясь, оказывается, что деструктор класса всё же не вызывается, и утечка в функции connect действительно есть (см. пример 3). Но поначалу этому списку сложно поверить из-за большой избыточности.

Если ликвидировать все такие реальные ошибки, то VLD честно скажет, что утечек нет. И этот факт крайне важен для continuous integration.

Вывод

Visual Leak Detector штука очень простая и очень полезная, способная найти все утечки (если прогнать все сценарии) и при этом не выдающая ложных срабатываний. Прогон сценариев в VLD довольно медленный, однако, он всё же быстрее, чем в Intel Inspector в конфигурации debug. Плоский, не очень дружественный и простынообразный вывод результатов способен запутать своей объемностью и дубликатами, однако со временем и к нему можно привыкнуть и даже использовать в continuous integration.

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

Снимки оперативной памяти в VS 2019

В IDE Visual Studio 2019 есть собственный встроенный компонент для диагностики проблем Diagnostic Tools. В его составе есть механизм получения снимков памяти (snapshots). С его помощью можно находить утечки памяти как разницу (дельта) между снимками. Само собой, чтобы дельта показывала именно утечки, надо делать снимки в определенные, далеко не случайные моменты.

Запуск

Запустите приложение в отладчике (в конфигурации debug или release c отладочной информацией). При запуске должна по умолчанию появиться панель Diagnostic Tools. Выберите на этой панели вкладку Memory Usage, нажмите кнопку Heap Profiling и дальше делайте снимки кнопкой Take Snapshot.

Чтобы поймать утечку памяти, возникающую в каком-то сценарии работы с приложением, надо получить снимки непосредственно до и после выполнения сценария, а затем взять между ними дельту. Это будет работать только для тех сценариев, для которых точно известно, что они должны освобождать занятые ресурсы после своего завершения. К сожалению, далеко не для всех сценариев это так.

Перед созданием каждого снимка удобно либо временно приостанавливать работу приложения кнопкой Break All при отладке, либо ставить точку останова на нужное место в коде, и она сработает в нужный момент, после чего можно делать снимок.

Рис. 5. Работа со снимками памяти.Рис. 5. Работа со снимками памяти.

Для просмотра результатов нажмём на прирост памяти между снимками (см. Рис. 5, где стрелочка). В появившейся вкладке в области редактора кода выберем ViewMode -> Stacks View (вместо Types View), и через некоторое время формирования отчёта увидим интерактивное дерево вызовов:

Рис. 6. Работа со снимками памяти, call-stack.Рис. 6. Работа со снимками памяти, call-stack.

Результаты

Надо честно признать, что работать со снимками памяти при нахождении утечек очень сложно в больших приложениях на Qt: очень большой лог, глубоко завязанный на специфику Qt. Из него можно вычленять крупицы реальных ошибок, но это довольно трудоемко. Взяв наш эталонный сценарий тестирования (см. табл. 1), мы не смогли за пару часов найти ни одной утечки. Зато смогли добиться того, чтобы инструмент самопроизвольно отключался с ошибкой.

Вывод

Для поиска утечек памяти механизмом снимков можно пользоваться только, если никакой другой инструментарий попросту не запускается на вашем тесте (падает, зависает и т.д.). Даже если механизмом снимков удастся найти утечку, скорее всего, это потребует колоссального ручного анализа. Однако для поиска простых утечек (вроде выделения большого куска памяти в маленьком приложении) снимки памяти могут пригодиться.

PVS-Studio

Последняя из рассматриваемых в данной статье утилита, которая может помочь в нахождении утечек памяти, - PVS-Studio. Она делает статический анализ кода, не требующий запуска приложения. Анализ может запускаться и для одного выделенного проекта, и для всех проектов в solution. Также он может запускаться при каждом новом сохранении редактируемого файла исходного кода, инкрементно, сразу указывая на сомнительные места в новом коде.

Установка

Проблем с установкой нет. В результате установки PVS-Studio оказывается встроенной в Visual Studio 2019, в меню Extensions.

Запуск

Для запуска всего solution`а вызываем команду Extensions->PVS-Studio->Check. Результат проверки выдается во вкладке PVS-Studio и содержит список потенциальных ошибок в коде, распределённых по вкладкам с критичностью High, Medium и Low.

Этот объемный результирующий список будет содержать не только утечки памяти, а и все остальные ошибки в коде, что PVS-Studio посчитает ошибками. Чтобы оставить только то, что касается только утечек памяти, нужно фильтровать список по следующим кодам: V599, V680, V689, V701, V772, V773, V1005, V1023 (более подробно см. здесь).

Для фильтрации нужно зайти в настройки Visual Studio в меню Tools -> Options -> PVS-Studio и на вкладке Detectable Errors (C++) выставить нужные галочки, убрав остальные (при этом удобно сначала использовать команду Hide All, а потом уже ставить галочки) Рис. 8. Также нужно убрать галочки из других групп и вкладки Detectable Errors (C#) (выбирая Hide All или Disabled).

Рис. 8. Фильтрация списка найденных утилитой PVS-Studio ошибок.Рис. 8. Фильтрация списка найденных утилитой PVS-Studio ошибок.

Чтобы показать все сообщения с выбранными кодами ошибок, нужно убедиться, что в окне PVS-Studio над сообщениями все кнопки High, Medium и Low включены.

Результаты

Итак, для поиска утечек памяти был запущен анализ на проекте, включающем около 1.5 млн строк кода и 2269 файлов кода. Анализ производился на Intel Core i7 4790K. Конфигурация кода (debug или release) значения не имеет, поскольку анализ статический (если более точно, разница есть из-за условной компиляции, но она непринципиальна).

Время анализа

Кол-во ошибок в эталоне: n

Найдено утечек

Пропущено ошибок из эталона: r

Точность: (n-r)/n

Всего

Верных

Ложных

30 мин

7

2

0

2

7

0 %

Таблица 6. Поиск утечек памяти утилитой PVS-Studio

Вывод

Для поиска утечек памяти этой утилитой можно пользоваться только, если под рукой нет чего-то более заточенного под утечки памяти (Intel Inspector, VLD). Она не способна находить все утечки, но выдает ложные срабатывания. Это не удивительно, поскольку утилита PVS-Studio никогда и не заявлялась как специализированный инструмент поиска утечек.

Сравнение работы инструментов для поиска утечек памяти

Подводя итоги, можно однозначно выделить в качестве лучших 2 инструмента для поиска утечек Intel Inspector и Visual Leak Detector. На основании проведенного тестирования мы получаем следующую их сравнительную таблицу:

Intel Inspector

VLD

Вид анализа

Динамический

Динамический

Стабильность работы

Средняя

Высокая

На любом ли примере (сценарии) может отработать

Нет

Нет

Удобство использования

Среднее

Низкое

Замедление debug

9.6 раз

1,7 раз

Замедление release с отладочной информацией

7 раз

-

Находит ли реальные утечки в debug

Да, все. Избыточность результатов 18 раз.

Да, все. Избыточность результатов 26 раз.

Находит ли реальные утечки в release с отладочной информацией

Да, все. Избыточность результатов 27 раз.

-

Ложные срабатывания в debug

Да, немного

Нет

Ложные срабатывания в release с отладочной информацией

Да, немного

-

Можно ли использовать в Continuous Integration

Нет

Да

Таблица7. Сравнение Intel Inspector и VLD.

Место 1 в рейтинге целесообразно отдать VLD, поскольку он не выдает ложных срабатываний, более стабилен в работе и более подходит для использования в сценариях непрерывной интеграции.

Подробнее..

Шаблон микросервиса зачем нужен и как его внедрить в разработку

19.02.2021 12:19:30 | Автор: admin

Сегодня речь пойдёт про шаблоны, которые позволяют нашим командам создавать новые микросервисы буквально за несколько минут. Рассказываем, как он устроен и почему эта история не только про автоматизацию ручного труда, но про эффективность разработки как таковой.

В том или ином виде шаблоны используют многие разработчики. Чаще всего, чтобы сэкономить время, они копируют код из старых проектов. С нашей точки зрения, у такой практики есть сразу несколько недостатков:

1. Можно выбрать неудачный микросервис для копирования - с недостающими элементами, некорректными настройками и т.д.

2. Если у разработчиков нет эталона, повышается риск дополнительных ошибок. Значит, кому-то придётся потратить лишнее время, чтобы их исправить.

3. Всегда есть риск проглядеть важные элементы, не заметить недостающий пайплайн, использовать старую версию библиотеки, указать неверные настройки авторизации или логирования.

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

Что даёт шаблон микросервиса

Шаблон микросервиса это кирпичик программного продукта, конструктивный элемент, который можно переиспользовать от проекта к проекту.

С его помощью вы обеспечиваете командам общую технологическую базу все работают по одному образцу, который по умолчанию включает все элементы, которые нужны в проекте (о составе шаблона подробнее рассказываем ниже). Разработчики освобождаются и от копирования кода, и от необходимости его лишний раз проверять.

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

  • Использование шаблонов обеспечивает разработчикам стабильное качество с меньшими затратами ресурсов. Достаточно один раз потратить время на подбор нужных элементов - и после этого у всех разработчиков сразу будет под рукой готовый инструментарий.

  • Чем меньше времени уходит на лишние действия, тем меньше time-to-market. Релизы поставляются чаще, продукт развивается быстрее.

  • Шаблон помогает выполнять стандарты Production Ready. Это включает в себя не только архитектурные элементы, которые должны быть в каждом продукте, но и другие важные вещи вроде средств работы с метриками и Feature Flags, базовых тестов.

  • Возможность распространить лучший опыт сразу на все команды помогает качественно повысить уровень их работы. Вы избавляетесь от влияния субъективных факторов один разработчик пишет так, другой эдак, третий недавно пришёл в компанию и пока не разобрался, какие библиотеки нужно использовать. Шаблоны убирают путаницу и упрощают ревью.

  • С шаблонами вы получаете возможность быстро и централизованно обновлять набор библиотек, настраивать пайплайны, накатывать политики на репозитории и т.д. Коллеги исследовали новую технологию, рассказали о ней на митапе, все оценили и в кратчайшие сроки она быстро появляется у всех в рабочем инструментарии.

  • Развитие микросервисной архитектуры - чем проще создавать микросервисы, тем больше ими пользуются разработчики. У команд больше нет накладных расходов на создание скелета микросервиса, сделать один микросервис или разбить логику на пять практически не имеет значения. Поэтому шаблон является драйвером развития настоящей микросервисной архитектуры.

Что фиксируется в шаблоне

  1. Структура папок и базовые классы необходимые для любого микросервиса

  2. Настройки Rest API, баз данных, авторизации, брокеров сообщений

  3. Правильные версии базовых библиотек

  4. Наши внутренние наработки и настройки

    • Библиотеки собственной разработки

    • Пайплайны сборки и поставки (CI/CD)

    • То, что называется Observability, а именно логирование, трассировка, health check monitoring

  5. Помимо самого кода, мы стандартизуем всю экосистему для нашего будущего микросервиса: настраиваем политики работы Git репозитория, пайплайны Jenkins/Gitlab.

Как выглядит наш шаблон микросервиса для .Net

Наш базовый микросервис является расширением Microsoft Visual Studio и объединяет в себе пять компонентов:

  • Web API Project - бэк-сервис, который отвечает на HTTP-запросы.

  • Data base project база данных микросервиса.

  • HTTP Service client project позволяет вызывать методы в сервисе бэка

  • MassTransit consumers project обеспечивает получение сообщений из RabbitMQ.

  • Job Project применяется для выполнения каких-либо действий по расписанию.

Модули можно добавить в проект сразу все разом или по отдельности. Выбор сделан на основе простого UI, где достаточно галочками прощёлкать нужные компоненты:

Готовый шаблон помещается в маркетплейс Visual Studio или другой репозиторий, который позволит вам автоматически обновлять его содержимое.

Итоги

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

Что дальше? Мы будем тиражировать этот опыт на другие команды. Мы хотим максимально сохранить целостность шаблона и при этом сделать его универсальным для использования в разных проектах. Мы будем создавать шаблоны для всех платформ. Так мы обеспечим себе единый уровень качества и единый набор лучших практик вне зависимости от условий в каждом конкретном случае.

Подробнее..

Python в Visual Studio Code февральский релиз 2021

26.02.2021 10:11:26 | Автор: admin

Мы рады сообщить, что стал доступен релиз расширения Python для Visual Studio Code от февраля 2021 года. Вы можете загрузить расширение Python из Marketplace или установить его прямо из галереи расширений в Visual Studio Code. Если у вас уже установлено расширение Python, вы также можете получить последнее обновление, перезапустив Visual Studio Code. Вы можете узнать больше о поддержке Python в Visual Studio Code в документации.

Этот выпуск включает интеграцию с TensorBoard и улучшения работы с кодом с использованием Pylance. Если вам интересно, вы можете изучить полный список улучшений в нашем журнале изменений.

Обновления расширения Python

Интеграция с TensorBoard

Мы рады запустить интеграцию TensorBoard в VS Code. TensorBoard - это вспомогательный дашборд по анализу данных, который помогает разработчикам PyTorch и TensorFlow визуализировать свои наборы данных и обучение модели. С помощью TensorBoard, непосредственно интегрированного в VS Code, вы можете выборочно проверять прогнозы своих моделей, просматривать архитектуру модели, анализировать потери и точность модели с течением времени, профилировать свой код, чтобы находить узкие места, и многое другое!

Чтобы начать сессию TensorBoard, откройте палитру команд (Ctrl/Cmd + Shift + P) и найдите команду Python: запустить TensorBoard. После этого вам будет предложено выбрать папку, в которой находятся файлы журнала TensorBoard. По умолчанию мы будем использовать ваш текущий рабочий каталог и автоматически обнаружим ваши файлы журнала TensorBoard в любых подкаталогах, но вы также можете указать свой собственный каталог. Затем VS Code откроет новую вкладку с TensorBoard, и ее жизненный цикл также будет управляться VS Code.

Обновления расширения Pylance

Улучшенная читаемость строк документации

Мы рады объявить о значительных улучшениях в "readability" и форматировании строк документации в Pylance. Теперь вы можете более легко читать строки документации с областями с отступом (например, блоки параметров в документах numpy и pandas), вложенные списки (например, в argparse) и модули, использующие форматирование epydoc (например, OpenCV).

Улучшено поведение "go to definition" и "go to declaration"

Мы также улучшили навигацию по коду, чтобы упростить поведение перехода к определению и перехода к описанию и привести вас прямо туда, куда вы хотите. Теперь вместо того, чтобы быть представленным в окне для выбора между типом области (.pyi) или исходным файлом (например, файлы .py), когда оба доступны, переход к определению приведет вас к исходному файлу, а переход к объявлению приведет вас к типу области. Если любой из этих вызовов в противном случае не дал бы никаких результатов (например, перейти к определению, когда доступна только область типа), то Pylance приведет вас к любому доступному файлу, чтобы вы по-прежнему получали некоторую информацию об интересующем символе.

Прочие изменения и улучшения

Мы также добавили небольшие улучшения и исправили проблемы, запрошенные пользователями, которые должны улучшить ваш опыт работы с Python в Visual Studio Code. Заметные изменения включают:

  • Минимально необходимая версия VS Code повышена до 1.51.

  • Реорганизована команда Enable Linting, чтобы предоставить пользователю возможность выбора Enable или Disable линтинг, чтобы сделать ее более интуитивно понятной.

  • Команда Pylance: Report Issue автоматически заполняет новый шаблон GitHub для более простого сообщения об ошибках сервера.

Загрузите расширение Python для Visual Studio Code сейчас, чтобы опробовать вышеуказанные улучшения. Если у вас возникнут какие-либо проблемы или у вас есть предложения, сообщите о проблеме на странице Python VS Code на GitHub.

Подробнее..

Visual Studio 2022

21.04.2021 10:22:09 | Автор: admin

У меня захватывающие новости - этим летом выйдет первая общедоступная предварительная версия Visual Studio 2022.

Следующий крупный выпуск Visual Studio будет более быстрым, доступным и легким, предназначенным как для учащихся, так и для тех, кто создает решения промышленного масштаба. Впервые Visual Studio будет 64-разрядной. Пользовательский интерфейс будет более чистым, интеллектуальным и ориентированным на действия.

Команды разработчиков стали более рассредоточенными географически, чем когда-либо. За последний год стало очевидно, что организациям нужны команды разработчиков для безопасного взаимодействия, более быстрого предоставления решений и постоянного повышения удовлетворенности конечных пользователей и повышения их ценности. Мы упрощаем совместную работу за счет улучшенной интеграции с GitHub, что упрощает переход от идеи к коду.

Visual Studio 2022: 64-bit

Visual Studio 2022 будет 64-битным приложением, которое больше не будет ограничено ~ 4 ГБ памяти в основном процессе devenv.exe. С помощью 64-разрядной Visual Studio в Windows вы можете открывать, редактировать, запускать и отлаживать даже самые большие и сложные решения, не исчерпывая памяти.

Хотя Visual Studio переходит на 64-разрядную версию, это не меняет типы или разрядность приложений, которые вы создаете с помощью Visual Studio. Visual Studio по-прежнему будет отличным инструментом для создания 32-разрядных приложений.

Мне очень приятно смотреть это видео о масштабировании Visual Studio с целью использования дополнительной памяти, доступной для 64-разрядного процесса, поскольку открывается решение с 1600 проектами и ~ 300к файлов.

Мы также работаем над тем, чтобы сделать каждую часть вашего рабочего процесса быстрее и эффективнее, от загрузки решений до отладки F5.

Дизайн для всех

Мы обновляем пользовательский интерфейс, чтобы вы всегда были в курсе событий. Некоторые из изменений - это тонкие косметические штрихи, которые модернизируют пользовательский интерфейс или уменьшают скопление людей. В целом мы стремимся снизить сложность и когнитивную нагрузку, чтобы вы могли сосредоточиться и оставаться в зоне работы. Кроме того, повышение доступности Visual Studio повысит удобство использования для всех - следующая версия Visual Studio будет включать:

  • Обновленные значки для большей четкости, разборчивости и контрастности

  • Cascadia Code, новый шрифт фиксированной ширины для лучшей читаемости и поддержки лигатур. (Если хотите, можете попробовать Cascadia Code прямо сейчас!)

  • Обновленные и улучшенные темы продуктов

  • Интеграция с Accessibility Insights для раннего обнаружения проблем доступности - до того, как они попадут к вашим конечным пользователям.

Персонализация

Как разработчики, мы понимаем, что персонализация вашей IDE так же важна, как и выбор рабочего стула. Мы должны сделать все в самый раз, прежде чем сможем работать максимально продуктивно. Сделать Visual Studio 2022 подходящей для вас будет проще, чем когда-либо, от возможности настраивать аспекты IDE до синхронизации настроек между устройствами для тех, кто поддерживает несколько блоков разработки.

Создание современных приложений

Azure

Visual Studio 2022 позволит быстро и легко создавать современные облачные приложения с Azure. Мы поможем вам начать с большого количества репозиториев, описывающих общие шаблоны, используемые в современных приложениях. Эти репозитории состоят из кода, показывающего эти шаблоны в действии, ресурсов IAAC для предоставления ресурсов Azure, а также предварительно созданных рабочих процессов и действий GitHub, настраивающих вас с помощью полного решения CI/CD при первом создании проекта. Кроме того, в репозитории будет определена необходимая среда разработки, чтобы вы могли сразу приступить к кодингу и отладке.

.NET

Visual Studio 2022 будет иметь полную поддержку .NET 6 и его единой платформы для веб-приложений, клиентских и мобильных приложений для разработчиков как для Windows, так и для Mac. Это включает в себя пользовательский интерфейс многоплатформенного приложения .NET (.NET MAUI) для кроссплатформенных клиентских приложений в Windows, Android, macOS и iOS. Вы также можете использовать веб-технологии ASP.NET Blazor для написания настольных приложений через .NET MAUI.

А для большинства типов приложений, таких как веб-приложения, настольные компьютеры и мобильные устройства, вы сможете использовать .NET Hot Reload для применения изменений кода без необходимости перезапуска или потери состояния приложения.

С++

Visual Studio 2022 будет включать надежную поддержку рабочей нагрузки C++ с новыми функциями повышения производительности, инструментами C++ 20 и IntelliSense. Новые возможности языка C++ 20 упростят управление большими базами кода, а улучшенная диагностика упростит отладку сложных проблем с помощью шаблонов и концепций.

Мы также интегрируем поддержку CMake, Linux и WSL, чтобы упростить вам создание, редактирование, сборку и отладку кроссплатформенных приложений. Если вы хотите перейти на Visual Studio 2022, но беспокоитесь о совместимости, двоичная совместимость со средой выполнения C++ сделает это безболезненным.

Инновации

Диагностика и дебаггинг

Возможность уверенно отлаживать приложения - это центральный элемент вашего повседневного рабочего процесса. Visual Studio 2022 будет включать улучшения производительности в основном отладчике с дополнительными функциями.

Коллаборация в реальном времени

Live Share открывает новые возможности для сотрудничества с другими, обмена идеями, парного программирования и анализа кода. В Visual Studio 2022 Live Share появится интегрированный текстовый чат, чтобы вы могли быстро обсуждать свой код без каких-либо переключений контекста. У вас будет возможность запланировать повторяющиеся сеансы с повторным использованием одной и той же ссылки, что упростит совместную работу с вашими частыми контактами. Чтобы лучше поддерживать Live Share в организациях, мы также представим политики сеансов, которые определяют любые требования соответствия для совместной работы (например, должны ли терминалы чтения/записи быть общими?).

Инсайты и продуктивность

Подсистема AI IntelliCode в Visual Studio продолжает совершенствоваться, легко предвидя ваш следующий шаг. Visual Studio 2022 обеспечит все более глубокую интеграцию в ваши повседневные рабочие процессы, помогая вам предпринимать правильные действия в нужном месте в нужное время.

Асинхронная коллаборация

Visual Studio 2022 будет включать новую мощную поддержку Git и GitHub. Фиксация кода, отправка запросов и слияние ветвей - это когда мой код становится нашим кодом. Вы заметите много встроенной логики и контрольных точек, которые помогут вам эффективно провести процесс слияния и проверки, не ожидая отзывов от коллег, которые могут замедлить работу. Наш руководящий принцип здесь заключался в том, чтобы помочь вам больше доверять коду.

Улучшенный поиск кода

Поиск кода - неотъемлемая часть жизненного цикла разработки программного обеспечения. Разработчики используют поиск кода по множеству причин: учиться у других, делиться кодом, оценивать влияние изменений во время рефакторинга, исследовать проблемы или анализировать изменения. Мы стремимся повысить производительность всех этих критически важных действий в Visual Studio 2022, чтобы ваша продуктивность была еще выше. Вы также сможете искать за пределами загруженной области, чтобы найти то, что ищете, независимо от того, в какой базе кода или репозитории оно находится.

Обновление Visual Studio для Mac

Наша цель в Visual Studio 2022 для Mac - создать современную среду разработки .NET, адаптированную для Mac, которая обеспечит продуктивную работу, которая вам так полюбилась в Visual Studio. Мы работаем над переводом Visual Studio для Mac на собственный пользовательский интерфейс macOS, что означает повышение производительности и надежности. Это также означает, что Visual Studio для Mac может в полной мере использовать все встроенные функции специальных возможностей macOS. Мы обновляем меню и терминологию в среде IDE, чтобы сделать Visual Studio более согласованной между Mac и Windows. Новые возможности Git из Visual Studio также появятся в Visual Studio для Mac, начиная с появления окна инструмента Git Changes.

Поделитесь с нами вашими мыслями

Мы показали вам лишь несколько основных моментов нашей незавершенной работы над Visual Studio 2022. Как всегда, вы можете перейти в новое сообщество разработчиков, чтобы просмотреть существующие запросы функций, проголосовать и комментировать или создать свои собственные.

Следите за новостями о доступности 64-разрядной версии Visual Studio 2022 Preview 1, которая будет включать наши улучшения пользовательского интерфейса и специальные возможности. (И помните! Как и любая другая работа, эти функции все еще находятся в разработке, поэтому некоторые из них появятся в Visual Studio 2022 после первого общедоступного выпуска.)

Спасибо!

Подробнее..

Перевод Почему в Visual Studio стек вызовов асинхронного кода иногда перевёрнут?

03.05.2021 18:11:31 | Автор: admin

Вместе с моим коллегой Евгением мы потратили много времени. Приложение обрабатывает тысячи запросов в асинхронном конвейере, полном async/await. Во время нашего исследования мы получили странные вызовы, они выглядели как бы перевернутыми. Цель этого поста рассказать, почему вызовы могут оказаться перевёрнутыми даже в Visual Studio.


Давайте посмотрим результат профилирования в Visual Studio

Я написал простое приложение .NET Core, которое имитирует несколько вызовов async/await:

static async Task Main(string[] args){    Console.WriteLine($"pid = {Process.GetCurrentProcess().Id}");    Console.WriteLine("press ENTER to start...");    Console.ReadLine();    await ComputeAsync();    Console.WriteLine("press ENTER to exit...");    Console.ReadLine();}private static async Task ComputeAsync(){    await Task.WhenAll(        Compute1(),        ...        Compute1()        ); }

ComputeAsync запускает много задач, выполнения которых будут ожидать другие методы async:

private static async Task Compute1(){    ConsumeCPU();    await Compute2();    ConsumeCPUAfterCompute2();}private static async Task Compute2(){    ConsumeCPU();    await Compute3();    ConsumeCPUAfterCompute3();}private static async Task Compute3(){    await Task.Delay(1000);    ConsumeCPUinCompute3();    Console.WriteLine("DONE");}

В отличие от методов Compute1 и Compute2, последний Compute3 ждёт одну секунду, прежде чем задействовать какие-то ресурсы CPU и вычислить квадратный корень в хелперах CompusumeCPUXXX:

[MethodImpl(MethodImplOptions.NoInlining)]private static void ConsumeCPUinCompute3(){    ConsumeCPU();}[MethodImpl(MethodImplOptions.NoInlining)]private static void ConsumeCPUAfterCompute3(){    ConsumeCPU();}[MethodImpl(MethodImplOptions.NoInlining)]private static void ConsumeCPUAfterCompute2(){    ConsumeCPU();}private static void ConsumeCPU(){    for (int i = 0; i < 1000; i++)        for (int j = 0; j < 1000000; j++)        {            Math.Sqrt((double)j);        }}

В Visual Studio использование ЦП этой тестовой программой профилируется через меню Debug | Performance Profiler....

На панели итоговых результатов (Summary result) нажмите ссылку Open Details....

И выберите древовидное представление стека вызовов.

Вы должны увидеть два пути выполнения:

Если открыть последний из них вы увидите ожидаемую цепочку вызовов:

...если методы были синхронными, что не соответствует действительности. Таким образом, чтобы представить красивый стек вызовов, Visual Studio проделала отличную работу с деталями реализации async/await. Однако если вы откроете первый узел, то получите нечто более тревожное:

... если вы не знаете, как реализованы async/await. Мой код Compute3 определённо не вызывает Compute2, который не вызывает Compute1! Именно здесь реконструкция интеллектуального фрейма/стека вызовов Visual Studio вносит самую большую путаницу. Что же происходит?

Разбираемся с реализацией async/await

Visual Studio скрывает реальные вызовы, но с помощью dotnet-dump и команды pstacks вы сможете увидеть, какие методы на самом деле вызываются:

Пройдя по стрелкам снизу вверх, вы должны увидеть такие асинхронные вызовы

  1. Обратный вызов таймера вызывает <Compute3>d__4.MoveNext(), что соответствует концу Task.Delay в методе Compute3.

  2. <Compute2>d__3.MoveNext() вызывается после await Compute3, чтобы продолжить выполнение кода.

  3. <Compute1>d__.MoveNext() вызывается после await Compute2.

  4. ConsumeCPUAfterCompute2() вызывается как ожидалось.

  5. ComputeCPU() или ConsumeCPUInCompute3() также вызываются как ожидалось.

Все причудливые имена методов связаны с типами машины состояний, генерируемых компилятором C#, когда вы определяете асинхронные методы, которые затем ожидают выполнения других асинхронных методов или любой ожидаемый объект. Роль этих методов заключается в управлении машиной состояний, чтобы синхронно выполнять код до вызова await, затем до следующего вызова await снова и снова, пока метод возвращается.

Все эти типы <имя метода>d__* содержат поля, соответствующие каждому асинхронному методу локальных переменных и параметров, если таковые имеются. Например, вот что генерируется для методов ComputeAsync и Compute1/2/3 async без локальных переменных или параметров:

Поле integer <>1__state отслеживает состояние выполнения машины. К примеру, после создания конечного автомата в Compute1 этому полю присваивается значение -1:

Я не хочу углубляться в детали конструктора, но давайте просто скажем, что метод MoveNext машины состояний <Compute1>d__2 выполняется тем же потоком. Прежде чем рассматривать соответствующую методу Compute1 реализацию MoveNext (без обработки исключений), имейте в виду, что она должна:

  1. Выполнить весь код до вызова await.

  2. Изменить состояние исполнения (об этом позже).

  3. Зарядиться магией, чтобы выполнить этот код в другом потоке (об этом позже, когда понадобится).

  4. Вернуться, чтобы продолжить выполнение кода после вызова await.

  5. И делать это до следующего вызова await, снова и снова.

<>1__state равно -1, поэтому выполняется первая "синхронная" часть кода, то есть вызывается метод ComsumeCPU).

Затем для получения соответствующего ожидаемого объекта вызывается метод Compute2 (здесь Task). Если задача выполняется немедленно (т.е. нет вызова await, такого как простая задача . FromResult() в методе async), IsCompleted() вернёт true, и код после вызова await будет выполняться тем же потоком. Да, это означает, что вызовы async/await могут выполняться синхронно одним и тем же потоком: зачем создавать поток, когда он не нужен?

Если задача передаётся в пул потоков для выполнения потоком-воркером, значение <>1__state устанавливается в 0 (поэтому при следующем вызове MoveNext будет выполнена следующая синхронная часть (т.е. после вызова await).

Теперь код вызывает awaitUnsafeOnCompleted, чтобы сотворить магию: добавить продолжение к задаче Compute2 (первый параметр awaiter), чтобы MoveNext был вызван на той же машине состояния (второй параметр this), когда задача завершится. Затем тихо возвращается текущий поток.

Поэтому, когда заканчивается задача Compute2, её продолжение выполняется для вызова MoveNext, на этот раз с <>1__state в значении 0, поэтому выполняются последние две строки: awaiter.GetResult() возвращается немедленно, потому что возвращённая Compute2 Task уже завершена, и теперь вызывается последний метод CinsumeCPUAfterCompute2. Вот краткое описание происходящего:

  • Каждый раз, когда вы видите асинхронный метод, с помощью метода MoveNext компилятор C# генерирует выделенный тип конечного автомата, отвечающий за синхронное выполнение кода между вызовами await.

  • Каждый раз, когда вы видите вызов await, это означает, что продолжение добавится к задаче Task, обёртывающей выполняемый метод async. Этот код продолжения вызовет метод MoveNext конечного автомата вызывающего метода, чтобы выполнить следующий фрагмент кода, до следующего вызова await.

Вот почему Visual Studio, пытаясь точно сопоставить каждый фрейм состояния асинхронного метода MoveNext исходя из самого метода, показывает перевёрнутые стеки вызовов: фреймы соответствуют продолжениям после вызовов await (зелёным цветом на предыдущем рисунке).

Обратите внимание, что я более подробно описал, как работает async/await, а также действие AwaitUnsageOnCompleted во время сессии на конференции DotNext с Кевином, поэтому не стесняйтесь смотреть запись с этого момента, если вы хотите углубиться в тему.

А если вы хотите погрузиться в C# обратите внимание на наш курс по разработке на этом языке. Универсальный стек среди ваших навыков серьёзно укрепит ваши позиции на рынке труда и увеличит доход.

Узнайте, как прокачаться и в других специальностях или освоить их с нуля:

Другие профессии и курсы
Подробнее..

11 анонсов конференции Microsoft Build для разработчиков

27.05.2021 10:19:54 | Автор: admin

Привет, Хабр! Сегодня, как и обещали*, делимся подборкой самых интересных для разработчиков конференции Microsoft Build 2021. Их получилось 11, но это не значит, что это все. Чтобы узнать еще больше, изучайте сайт конференции.

* пообещали это мы во вчерашней подборке 8 анонсов конференции Microsoft Build 2021, которую подготовила наша бизнес-команда.

1. Представлен Windows Terminal Preview 1.9

Поздравляем с Microsoft Build 2021 и вторым днем рождения Windows Terminal! Этот выпуск представляет версию 1.9 для Windows Terminal Preview и переносит Windows Terminal в версию 1.8. Как всегда, вы можете установить обе сборки из Microsoft Store, а также со страницы выпусков GitHub.

Среди новинок:

  • Дефолтный терминал

  • Quake mode

  • Обновления Cascadia Code

  • Обновления интерфейса настроек

  • Другие улучшения

Подробнее здесь.

2. Представляем Visual Studio 2019 v16.10 и v16.11 Preview 1

Мы рады объявить о выпуске Visual Studio 2019 v16.10 GA и v16.11 preview 1. Этот выпуск делает нашу тему продуктивности и удобства разработчиков общедоступной для пользователей Visual Studio! Мы добавили функции C ++ 20, улучшили интеграцию с Git, улучшили инструменты профилирования и множество функций, повышающих продуктивность.

Подробнее здесь.

3. Представляем .NET 6 Preview 4

Мы рады выпустить .NET 6 Preview 4. Мы почти наполовину закончили выпуск .NET 6. Это хороший момент, чтобы еще раз взглянуть на .NET 6 в полном объеме, как и в первом Preview. Многие функции находятся в близкой к окончательной форме, а другие появятся в ближайшее время, когда основные блоки будут готовы к выпуску. Предварительная версия 4 создает прочную основу для выпуска в ноябре финальной сборки .NET 6 с готовыми функциями и возможностями. Она также готова к тестированию в реальных условиях, если вы еще не пробовали .NET 6 в своей среде.

Говоря о финальном выпуске, у нас теперь запланирована дата! Добавьте в календарь даты с 9 по 11 ноября и .NET Conf 2021. Мы выпустим .NET 6 9-го числа с множеством подробных докладов и демонстраций, которые расскажут вам все, что вы хотите знать о .NET 6.

Подробнее здесь.

4. Представляем .NET MAUI Preview 4

Сегодня мы рады объявить о доступности .NET Multi-platform App UI (.NET MAUI) Preview 4. Каждая предварительная версия представляет больше элементов управления и функций для этого многоплатформенного инструментария, который станет общедоступным в ноябре этого года на .NET Conf. .NET MAUI теперь имеет достаточно блоков для создания функциональных приложений для всех поддерживаемых платформ, новые возможности для поддержки запуска Blazor на настольных компьютерах и впечатляющий прогресс в Visual Studio для поддержки .NET MAUI.

Подробнее здесь.

5. Обновления ASP.NET Core в .NET 6 Preview 4

Версия .NET 6 Preview 4 уже доступна и включает много новых крутых улучшений в ASP.NET Core.

Вот что нового в этой предварительной версии:

  • Добавлены minimal APIs

  • Async streaming

  • HTTP logging middleware

  • Использование Kestrel для профиля запуска по умолчанию в новых проектах

  • IConnectionSocketFeature

  • Илучшенные шаблоны single-page app (SPA)

  • Обновления .NET Hot Reload

  • Ограничения generic type в компонентах Razor

  • Blazor error boundaries

  • Компиляция Blazor WebAssembly ahead-of-time (AOT)

  • Приложения .NET MAUI Blazor

  • Другие улучшения производительности

Подробнее здесь.

6. Представляем Entity Framework Core 6.0 Preview 4: Performance Edition

Группа Entity Framework Core анонсировала четвертый предварительный выпуск EF Core 6.0. Основная тема этого выпуска - производительность.

Что нового:

  • Производительность EF Core 6.0 теперь на 70% выше в стандартном для отрасли тесте TechEmpower Fortunes по сравнению с 5.0.

  • Улучшение производительности полного стека, включая улучшения в тестовом коде, среде выполнения .NET и т. д. Сам EF Core 6.0 на 31% быстрее выполняет запросы.

  • Heap allocations уменьшены на43%.

Подробнее здесь.

7. Представляем .NET Hot Reload для редактирования кода во время выполнения

Рады представить вам возможность горячей перезагрузки .NET в Visual Studio 2019 версии 16.11 (предварительная версия 1) и с помощью инструментария командной строки dotnet watch в .NET 6 (предварительная версия 4). В полной статье коллеги познакомят вас с тем, что такое .NET Hot Reload, как вы можете начать использовать эту функцию, каково наше видение будущих запланированных улучшений и проснят, какой тип редактирования и языки в настоящее время поддерживаются.

Подробнее здесь.

8. SecretManagement Module v1.1.0

Следующая версия SecretManagement 1.1.0 содержит ряд мелких исправлений, а также два значительных изменения, одно из которых потенциально критично для авторов расширений. Для получения дополнительной информации об изменениях в этом выпуске см. документ CHANGELOG. В статье ниже обсуждаются основные изменения, почему они потенциально очень важны и особенно актуальны для владельцев хранилищ расширений, которые могут захотеть протестировать свое хранилище и внести какие-либо изменения, пока эти обновления находятся в состоянии предварительной версии.

Подробнее здесь.

9. Новый бесплатный курс: создание бессерверных приложений с полным стеком в Azure

Независимо от того, новичок вы или опытный в облаке, разработке и SQL, создание и проектирование приложений в облаке стало необходимым навыком для многих ролей. Сегодня мы рады объявить о новом пути обучения, который поможет разработчикам с любым уровнем подготовки научиться быстро и эффективно создавать приложения с помощью Azure. Новый путь обучения - создание бессерверных полнофункциональных приложений в Azure.

Подробнее здесь.

10. .NET Framework May 2021

Выпущена предварительная версия накопительного обновления для .NET Framework за май 2021 года.

Подробнее здесь.

11. Представляем сборку OpenJDK от Microsoft

Объявлена общая доступность сборки OpenJDK от Microsoft, нового бесплатного дистрибутива OpenJDK с открытым исходным кодом, доступного бесплатно для всех, с возможностью развертывания его где угодно. Корпорация Майкрософт активно использует Java, внутри компании работает более 500 000 JVM. Группа разработчиков Java очень гордится тем, что вносит свой вклад в экосистему Java и помогает управлять такими рабочими нагрузками, как LinkedIn, Minecraft и Azure!

Сборка включает двоичные файлы для Java 11, основанные на OpenJDK 11.0.11 + 9 x64 server и настольных средах в macOS, Linux и Windows. Мы также публикуем новый двоичный файл раннего доступа для Java 16 для Linux и Windows на ARM, основанный на последней версии OpenJDK 16.0.1 + 9.

Этот новый выпуск Java 16 уже используется миллионами игроков Minecraft с последней версией Minecraft Java Edition Snapshot 21W19A, которая была обновлена для объединения среды выполнения Java 16 на основе сборки Microsoft OpenJDK.

Посетите страницу, чтобы узнать подробности.

Подробнее здесь.

Подробнее..

Jupyter в Visual Studio Code июньский релиз

17.06.2021 10:17:44 | Автор: admin

Мы рады сообщить, что стал доступен июньский релиз расширения Jupyter для Visual Studio Code. Если вы работаете с Python, мы рекомендуем загрузить расширение Python из Marketplace или установить его прямо из галереи расширений в Visual Studio Code. Если у вас уже установлено расширение Python, вы также можете получить последнее обновление, перезапустив Visual Studio Code. Узнайте больше о поддержке Python в Visual Studio Code в документации.

В этом релизе основное внимание уделялось:

  • Усилению мер безопасности

  • Дополнительным настройкам макета Native Notebook

  • Улучшению средств Data Viewer и Variable Explorer

Если вам интересно, вы можете изучить полный список улучшений в нашем журнале изменений.

Подробнее о самых интересных новинках под катом.

Workspace Trust

Команда Visual Studio Code серьезно относится к безопасности. Функция Workspace Trust позволяет определить, каким папкам и содержимому проекта вы доверяете, а какие остаются в ограниченном режиме.

Что это значит для notebooks?

При открытии папки в VS Code вас спросят, доверяете ли вы авторам и содержимому папок.

Если вы доверяете папке, любые notebooks и их выходные данные будут отображаться и смогут запускать код. Если вы не доверяете папке с notebooks в них, вы будете в ограниченном режиме. Если вы хотите сменить режим с ограничениями на доверенный, щелкните шестеренку в левом нижнем углу и выберите Управление доверием рабочей области.

** Примечание. Важно понимать, что notebooks могут содержать вредоносный код, встроенный в их выходные данные, и могут работать без выполнения вами ячеек. VS Code будет подавлять выходные данные до тех пор, пока вы явно не доверяете записной книжке. Важно определить, доверяете ли вы notebooks, загруженным из внешних источников.

Дополнительные сведения и сведения о доверии рабочей области см. в разделе Visual Studio Code - доверие рабочей области.

Улучшенная фильтрация в средстве просмотра данных

Средство просмотра данных теперь имеет улучшенные возможности для фильтрации строковых значений с добавленной поддержкой символа подстановки *. В приведенном ниже примере столбец, по которому выполняется фильтрация, содержит записи мужской и женский. Поиск значений мужской теперь будет возвращать только точные совпадения. Чтобы найти все значения, оканчивающиеся на мужской, просто введите * мужской в поле фильтра. Подстановочный знак * соответствует любому количеству символов и может использоваться в любом месте строки.

Сортировка в проводнике переменных

По многочисленным просьбам переменные в вашем notebook теперь можно сортировать. Щелкните заголовок Имя или Тип в проводнике переменных для сортировки. Направление стрелки в заголовке будет указывать, по какому заголовку сортируются переменные и в каком порядке выполняется сортировка: в алфавитном или обратном алфавитном порядке.

Новый взгляд на нативные notebooks

Чтобы опробовать нативные notebooks сегодня, загрузите VS Code Insiders и расширение Jupyter. Расширение Python настоятельно рекомендуется для работы с записными книжками Python.

  • Панель инструментов notebook теперь находится в верхнем левом углу со всеми вашими любимыми действиями и функциями, связанными с notebook

  • Средство выбора ядра переместилось обратно в верхний правый угол, что упрощает переключение между средами

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

Кастомизируемые нативные notebooks

Хотя приведенные выше основные моменты показывают, что уже работает в notebooks из коробки, вы всегда можете настроить все по своему вкусу. Мы добавили ряд настроек, чтобы по-настоящему сделать ваш notebook идеальным. Чтобы изучить настройки макета notebook, щелкните значок Дополнительные действия в конце панели инструментов и выберите Настроить макет notebook.

Вы попадете на страницу настроек со всеми настройками макета, относящимися к notebook, где вы сможете создать идеальный макет, который вам больше нравится.

Полный список настроек компоновки notebook:

  • notebook.insertToolbarLocation

  • notebook.consolidatedRunButton

  • notebook.cellFocusIndicator

  • notebook.cellToolbarVisibility

  • notebook.compactView

  • notebook.consolidatedOutputButton

  • notebook.dragAndDropEnabled

  • notebook.globalToolbar

  • notebook.showCellStatusBar

  • notebook.showFoldingControls

  • notebook.editorOptionsCustomizations

Прочие изменения и улучшения

Мы также добавили небольшие улучшения и исправили проблемы, запрошенные пользователями, которые должны улучшить ваш опыт работы с notebooks в Visual Studio Code. Некоторые заметные изменения включают:

  • Ограничение количества языков, отображаемых в средстве выбора языка ячейки, языками, поддерживаемыми ядром

  • Добавление ABCMeta и ввод в список исключений проводника переменных

  • Настройка размера и вида переменных в соответствии с VS Code

  • Скрытие ядер, принадлежащих удаленным средам Python, из средства выбора ядра

Загрузите расширение Python и расширение Jupyter для Visual Studio Code сейчас, чтобы опробовать вышеуказанные улучшения. Если у вас возникнут какие-либо проблемы или у вас есть предложения, сообщите о проблеме на странице Jupyter VS Code GitHub.

Подробнее..

Как Microsoft Analysis Services финансовым аналитикам жизнь упростил

07.04.2021 16:22:59 | Автор: admin
Как мало пройдено дорог как много сделано отчетов

Введение


Василий, мы установили новый BI продукт, наш САМЙ ГЛАВНЙ от него просто в восторге!
Да, но я не знаю, как выгрузить данные для анализа из этой системы?! Он, похоже, только в html может что-то показывать.
Ничего, я думаю ты справишься, сам понимаешь, чем шире улыбка шефа, тем выше премия.
Но, Иван Васильевич, этот продукт в качестве источника данных использует только PDF файлы.
Зато он показывает шикарные разноцветные графики, у него анимация как в Звездных войнах, а руководство просто в восторге от его интерактивных возможностей. Там ещё и пасхалочка есть. Если три раза кликнуть в правом нижнем углу, появится Дарт Вейдер и споёт Марсельезу. Да и в целом, Вася, будь оптимистом! Хочешь анекдот в тему?

Что у вас запланировано на 1 января?
Катание на санках
А если снег не выпадет?
Это нас огорчит, но не остановит.

Не грусти Вася, принимайся за работу, а мне пора спешить утренняя планерка, эээ Daily Standup Meeting точнее, всё никак не могу запомнить.

Вася садится за свой рабочий стол и с грустью смотрит в монитор. Да уж, красивые графики, только толку от них? В Excel не выгрузить, с формулами не сверить, хоть бери тетрадку с ручкой и делай всё на бумаге. Плюс ещё как-то KPI на основе этого надо посчитать. Зато в ИТ отдел, говорят, художника взяли, чтобы он красивые отчеты для руководства оформлял. Глядя на новый продукт, Вася загрустил. В голове у него крутились пару строк из стихотворения C.А. Есенина Мне грустно на тебя смотреть:
Так мало пройдено дорог,
Так много сделано ошибок.

Ну что ж, оставим Васю на едине со своей болью и посмотрим на проблему шире. Видя переделку строк C.А. Есенина, которая вынесена в цитату к этой статье, мне кажется, что он не одинок в своих мыслях. Сложно понять, как работают современные BI системы и для кого их пишут то ли для аналитиков, то ли для руководителей. Очень много теории и информации, причём, в зависимости от источника, эта информация может противоречить самой себе. К этому стоит добавить обилие научных терминов и трудный для понимания язык описания. Сложно угадать с выбором, а цена ошибки велика, так как системы дорогие и работа с ними часто требует определенной квалификации. Понимая всё это, я решил поделиться своим опытом в BI сфере. Попытаюсь написать об этом простым языком и не вдаваться глубоко в теорию. Речь пойдет о Microsoft Analysis Services и о том, как он может решить часть проблем связанных с аналитической отчетностью. Другую часть этих проблем, я решил, написав специальную программу, которая позволяла формировать отчеты непосредственно в Excel, минуя HTML формы и минимизируя нагрузку на Web сервер, но о ней я уже писал тут http://personeltest.ru/aways/habr.com/ru/post/281703/, а тут даже видео снял: https://youtu.be/_csGSw-xyzQ. Приятного вам чтения.
Если лень читать, то есть кортокое видео (11 минут)
Создание OLAP-куба в Microsoft Analysis Services: https://youtu.be/f5DgG51KMf8
Но в этом видео далеко не всё то, о чём пойдёт речь далее!!!


Отчетность и её проблемы


Все началось с задачи, поставленной финансовым отделом крупного банка. Надо было создать систему отчетности, которая бы позволяла быстро и оперативно оценивать текущую ситуацию в организации. Для решения этой задачи мы взяли базу данных. Организовали в ней Хранилище (Data Warehouse), настроили процессы загрузки данных и установили систему отчетности. В качестве которой мы взяли SQL Server Reporting Services, так как этот продукт входил в MS Sharepoint, использовавшийся в тот момент в банке. В принципе всё работало, но у заказчика были претензии:

  • Претензия 1. HTML -> MS Excel: отчеты изначально формируются в HTML, а аналитики работают с MS Excel. Надо постоянно делать экспорт из одного формата в другой. При этом часто сбивается разметка и в Excel часто подгружается множество дополнительной информации, большой объём которой, в некоторых случаях, существенно влияет на производительность.
  • Претензия 2. Параметры для отчета: данные в отчетах зависят от параметров, причём при их изменении формируется новый отчет, который надо опять выгружать в Excel, что не всегда удобно.
  • Претензия 3. Добавление изменений в отчет: для того, чтобы что-то изменить в отчете, добавить новую колонку или создать группировку, надо обращаться к специалисту, который может поправить этот отчет на сервере.
  • Претензия 4. Анализ данных: отчеты получаются статическими и когда нужно посмотреть различные разрезы, поменять строки с колонками, отфильтровать или добавить, либо удалить какие-то значения, надо делать все эти манипуляции в Excel, что не всегда удобно, а порой и сложно, из-за проблем с производительностью компьютеров, на которых работают аналитики.

Стоит отметить, что сотрудники банка не рассматривали для себя никакого другого инструмента в качестве замены MS Excel. И на то были веские основания. Весь его функционал сложно чем-то заменить. К примеру, аналитики очень часто:

  • сверяли данные из базы по формулам, которые можно добавить в Excel,
  • хранили одни и те же срезы данных, сделанные в разные дни, с целью обнаружить ошибки,
  • добавляли туда свои данные,
  • писали различные скрипты

В общем использовали его на все 100%. Хотя были те, кто предлагал им что-то другое, точнее не столько предлагал, сколько заставлял. Как итог таких предложений, у нас в системе появились SAP BO, Oracle Reports Services и ряд других BI инструментов. Возможно, они в чем-то превосходили SQL Server Reporting Services, но суть работы с ними кардинально не изменилась:

  1. формируем отчет в HTML,
  2. экспортируем его в Excel,
  3. начинаем заниматься бесконечными танцами вокруг данных.

Требовалось что-то более кардинальное, не просто отчет, а некий набор данных, с которым удобно было бы работать.

Выход из ситуации


К найденному решению подтолкнули PivotTable в Excel



и PivotGrid от фирмы DevExpress ( https://demos.devexpress.com/blazor/PivotGrid).

Детально изучив эти решения вышли на MS Analysis Services и решили попробовать. Его можно использовать в Excel, и он может работать с Oracle, как с источником данных, что нас на тот момент устраивало. С точки зрения архитектуры, источником данных для него может служить что угодно, был бы нужный провайдер. Суть его в том, что он способен хранить в себе большие объемы данных со всеми их агрегациями и выдавать их клиенту максимально быстро. К Excel его можно легко подключить и манипулировать данными в Pivot Table.



В MS Analysis Services есть возможность партиционирования данных (хранение их в виде множества отдельных частей) и так же инкрементальное обновление данных. Это даёт ему возможность загружать данные из внешних систем небольшими кусочками и хранить их во множестве партиций. С точки зрения максимальных объемов, у него есть ограничения, но они довольно большие https://docs.microsoft.com/en-us/analysis-services/multidimensional-models/olap-physical/maximum-capacity-specifications-analysis-services?view=asallproducts-allversions.

MS Analysis Services является OLAP системой, которая использует отдельный сервер для хранения данных, либо части данных. Его плюсом является то, что он способен довольно быстро работать с миллионами записей, будучи установленным на обычный, современный компьютер. Так же он позволяет анализировать данные непосредственно в Excel и может заменить собой десятки отчетов на MS Reporting Services или ему подобных. Причем при работе с ним не надо писать и править различные запросы типа SQL, хотя при желании можно, только вместо SQL он использует MDX.

Правда есть тут и ложка дегтя. В Excel можно запросить разом очень большой объём данных и OLAP их вернет, но отобразить такой объем Excel не сможет, либо сможет, но работать при этом будет очень медленно. На первых порах это раздражало аналитиков, но поняв причину и настроив фильтры в Pivot Table эту проблему решили.

Секрет быстродействия MS Analysis Services, как и любой другой OLAP системы, кроется в архитектуре хранения данных. В нем все храниться в максимально подготовленном и оптимизированном для запросов виде. Такая подготовка требует времени и запись вновь пришедших данных в OLAP происходит не быстро, но, с другой стороны, чтение данных получается очень быстрым. Выходит долго пишем быстро читаем.

Немного теории


Чаще всего, когда анализируют данные их объединяют в группы, а сами группы так же объединяют в иерархии. Для примера возьмём торговую точку. С точки зрения бизнеса, интерес представляют продажи. То есть сколько товара было продано за день (1-группа), за месяц (2-ая) и за год (3-я). Где день месяц и год это разные уровни одной иерархии. Получается, что продажи за месяц это сумма всех продаж за все дни в месяце, а продажи за год это сумма продаж за все месяцы в этом году. Отсюда получается, что для получения максимального быстродействия, можно заранее собрать данные в группы и рассчитать агрегаты (в нашем примере суммы продаж) для каждого уровня иерархи. Вот на этом принципе и работают MS Analysis Services. Им достаточно сказать что надо считать, по какой формуле и на какие группы это можно разбить. Остальную работу они сделают сами. Тут немного о том как они это делают: http://citforum.ru/consulting/BI/molap_overview/node7.shtml. Стоит отметить, что в современных OLAP системах все агрегаты, чаще всего, не рассчитываются заранее. Это всё делается на лету, в момент запроса.

Теперь о терминах:


MS Analysis Services это одна из OLAP систем, где OLAP это аббревиатура online analytical processing. Дословно это означает интерактивная (online) аналитическая обработка данных. Со временем данная формулировка утратила свой первоначальный смысл, так как появились системы, способные обрабатывать данные с большой скоростью и передавать их пользователю без использования подходов, декларируемых в OLAP. Поэтому, сейчас есть более полное описание требований к системам, которые могут называться OLAP, это:


По своему опыту, могу сказать, что чем больше ваш OLAP куб удовлетворяет описанию Е.Ф. Кодда, тем лучше, как с точки зрения работы с ним, так и с точки зрения его создания.

Вкратце, OLAP это система хранения, организованная таким образом, чтобы данные в ней:

  • были взаимосвязаны,
  • собирались в иерархии,
  • имели функции агрегации по всему множеству иерархий

Конечно же, главной целью такого хранения является высокая скорость ответов на запросы, но SSAS отчасти заботится об этом сам, если все делать по инструкции.

При построении OLAP выделяют Факты и Измерения. Факты это цифровые значения измеряемых величин. Измерения это сами измеряемые величины. Совокупность всех связанных между собой измерений, фактов и функций для их агрегации называют OLAP-кубом. Факты и Измерения связанны между собой. По типу связи выделяют 2 схемы организации хранения данных Звезда и Снежинка. Звезда это когда все измерения напрямую связаны с фактом, снежинка это когда есть измерения, которые связанны с фактом через другие измерения. Эти схемы можно создавать и просматривать в разделе Data Source Views в SSAS.







Создание OLAP-куба в Microsoft Analysis Services


Построение OLAP кубов делается через проект в Visual Studio. По большей части там реализована технология визуального программирования перетащить, кликнуть мышкой, настроить. Отсюда это проще показать, чем описать. Что я и сделал в моем видео: https://youtu.be/f5DgG51KMf8. Так же стоит отметить то, что Microsoft, в ознакомительных целях, предоставляет свои продукты бесплатно. Отсюда, посмотреть, как он работает можно на любом компьютере с ОС Windows 10, удовлетворяющем следующим требованиям: https://docs.microsoft.com/en-us/sql/sql-server/install/hardware-and-software-requirements-for-installing-sql-server-ver15?view=sql-server-ver15. Требования по ссылке к MS SQL Server, так как MS Analysis Services являются его частью.

Заключение


OLAP это относительно простой способ повысить скорость и удобство работы с данными. В данный момент существует множество решений, основанных на этой технологии. Я работал с MS Analysis Services (SSAS) и вот что мне в нём понравилось:

  • теоретически он позволяет работать с любым источником данных, не требуя при этом существенных затрат с точки зрения оборудования.
  • хранит данные на выделенном сервере, что снижает вероятность их потри, в отличие от систем, хранящих такие данные в памяти.
  • интегрирован с MS Excel, что облегчает работу с ним для тех, кто привык работать с данным продуктом.

В заключение, хочу сказать, что мне MS Analysis Services, в свое время, очень сильно помог и я надеюсь, что знания, которыми я поделился в этой статье, так же кому-то помогут.
Подробнее..

Использование libpq в VisualStudio (Windows)

29.01.2021 10:18:54 | Автор: admin

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

Я столкнулся с рядом проблем при попытке подключить libpq в VS 2017: начиная с несоответствия документации по данной API с инструкциями по подключению, заканчивая умолчанием некоторых ключевых моментов.

В общем по порядку.

Для использования данного API нужны следующие библиотеки и файлы:

  • libpq.dll и libpq.lib - собственно само API Последнее упоминание в документации о возможности сборки ее для Windows находиться в 9й версии. В 10+ этого уже нет. Таким образом проще всего сделать так: ставим postgresql нужной версии и берем оттуда папку PostgreSQL\{номер версии}\lib. Копируем куда нужно и в VS указываем в свойствах проекта Свойства конфигурации>Каталоги VC++> Каталоги библиотек. Далее указываем libpq.lib в Свойства конфигурации>Компоновщик> Ввод >Дополнительные зависимости.

  • libpq-fe.h - заголовочный файл для API. В месте со всеми остальными заголовочными файлами находиться в исходниках postgresql. Качаем с офф сайта (https://ftp.postgresql.org/pub/source/v12.0/postgresql-12.0.tar.gz ) нужную версию postgresql. Заголовочные лежат в postgresql-{номер версии}\src\interfaces\libpq. Эту папку подключаем в Свойства конфигурации>Каталоги VC++> Включаемые каталоги. Так же, я подключил сюда и эти каталоги : "\src\include" "\include\libpq" "\src\interfaces" (скажем так, на всякий).

  • libintl-8.dll, libiconv-2.dll - лежат в папке с установленным postgres ("PostgreSQL\{номер версии}\bin"). Нужно скопировать в Windows\system32 либо в папку с собранным exe программы.

  • libcrypto-1_1-x64.dll, libssl-1_1-x64.dll - библиотеки OpenSSL. Либо ставим его (выбирая при установке, копирование библиотек в папку system32), либо берем эти библиотеки с уже установленного openssl (C:\Program Files\OpenSSL-Win64\bin) и копируем в папку программы или system32 сами.

    Далее еще один момент. В моем случае, платформу проекта пришлось выбрать x64.

    На этом все. Добавляем #include <libpq-fe.h> в программу и работаем

Подробнее..

Оживляем деревья выражений кодогенерацией

02.01.2021 00:07:07 | Автор: admin

Деревья выражений System.Linq.Expressions дают возможность выразить намерения не только самим кодом, но и его структурой, синтаксисом.

Их создание из лямбда-выражений это, по сути, синтаксический сахар, при котором пишется обычный код, а компилятор строит из него синтаксическое дерево (AST), которое в том числе включает ссылки на объекты в памяти, захватывает переменные. Это позволяет манипулировать не только данными, но и кодом, в контексте которого они используются: переписывать, дополнять, пересылать, а уже потом компилировать и выполнять.

Run-time компиляция порождает производительные делегаты, которые часто быстрее тех, что компилируются во время сборки (за счет меньшего оверхеда). Однако сама компиляция происходит до десятков тысяч раз дольше, чем вызов результата компиляции.

(бенчмарк)

Действие

Время, нс

Cached Compile Invoke

0.5895 0.0132 ns

Compile and Invoke

83,292.3139 922.4315 ns

Это особенно обидно, когда выражение простое, например содержит только доступ к свойству (в библиотеках для маппинга, сериализации, дата-байндинга), вызову конструктора или метода (для IoC/DI решений).

Скомпилированные делегаты обычно кэшируют, чтобы переиспользовать, но это не спасает в сценариях, когда первый доступ происходит к большому количеству за раз. В таких случаях время run-time компиляции выражений становится значимым и оттягивает запуск приложения или отдельных окон.

Для уменьшения времени получения делегатов из деревьев выражений используют:

  • Встроенную интерпретацию.
    Необходимость использования интерпретатора вместо компилятора указывается соответствующим флагом:

    Expression.Compile(preferInterpretation: true)
    

    Происходит через рефлексию, но с накладными расходами на формирование стека инструкций.

    Для платформ Xamarin.iOS, Xamarin.watchOS, Xamarin.tvOS, Mono.PS4 и Mono.XBox стандартная компиляция через генерацию IL (System.Reflection.Emit) долгое время была недоступна и на данный момент под капотом всегда откатывается к этому варианту.

  • FastExpressionCompile от @dadhi.
    Ускоряет компиляцию за счет оптимизиpованной генерации IL и с меньшим количеством проверок совместимости.

    На платформах без поддержки JIT компиляции может использоваться только с включенным Mono Interpreter.

  • Ручную интерпретацию.
    Используется для оптимизации вызовов рефлексии под специальные сценарии использования, например для добавления кэширования отдельных вызовов.

    Интерпретируя вручную, уже можно воспользоваться способами ускорения рефлексии. Самые эффективные из них, например Fasterflect, используют System.Reflection.Emit и на некоторых платформах так же могут требовать включения Mono Interpreter.

Для случаев, когда производительности указанных методов недостаточно, напрашивается решение:

Компилировать выражения или какие-то их части во время написания кода (design-time) или сборки (compile-time).

Для compile-time компиляции делегатов к фрагментам деревьев выражений требуется сгенерировать соответствующий код.

API доступа к делегатам не стоит генерировать вместе с ними, лучше держать его в отдельной сборке. Причина заключается в том, что анализ и использование деревьев выражений часто происходит в проектах, отдельных от их инициализации. Фреймворки для дата-байндинга и DI это сторонние библиотеки, да и сами программы часто разбиваются на несколько сборок из соображений архитектуры.

От самого API требуется только давать нужный делегат по ключу, как в словаре. У интересующих нас фрагментов кода: методов, конструкторов и свойств на стыке run-time и compile-time естественный идентификатор это сигнатура. По ней генерируемый код будет класть делегаты в словарь, а клиенты забирать.

Например, для класса со свойством

namespace Namespace{  public class TestClass  {    public int Property { get; set; }  }}

используемым внутри System.Linq.Expressions.Expression<T> лямбды

Expression<Func<TestClass, int>> expression = o => o.Property;

делегатами чтения и записи в общем виде являются

Func<object, object> _ = obj => ((Namespace.TestClass)obj).Property;Action<object, object> _ => (t, m) => ((Namespace.TestClass)t).Property  = (System.Int32)m;

и генерируемый код для их регистрации будет примерно таким:

namespace ExpressionDelegates.AccessorRegistration{  public static class ModuleInitializer  {    public static void Initialize()    {      ExpressionDelegates.Accessors.Add("Namespace.TestClass.Property",        getter: obj => ((Namespace.TestClass)obj).Property,        setter: (t, m) => ((Namespace.TestClass)t).Property = (System.Int32)m);    }  }}

Генерация

Наиболее известные решения для кодогенерации, на мой взгляд, это:

Отдельная область применения есть у каждого решения, и только Roslyn Source Generators умеет анализировать исходный C# код даже в процессе его набора.

Кроме того, именно Roslyn Source Generators видятся более или менее стандартом для кодогенерации, т. к. были представлены как фича основного компилятора языка и используют Roslyn API, используемый в анализаторах и code-fix.

Принцип работы Roslyn Source Generators описан в дизайн-документе (местами не актуален!) и гайде.

Вкратце: для создания генератора требуется создать реализацию интерфейса

namespace Microsoft.CodeAnalysis{  public interface ISourceGenerator  {    void Initialize(GeneratorInitializationContext context);    void Execute(GeneratorExecutionContext context);  }}

и подключить ее к проекту как анализатор.

Метод Initialize пригодится для выполнения какой-либо единоразовой логики. GeneratorInitializationContext на данный момент может быть полезен только для подключения посетителя узлов синтаксиса кода.

В Execute имеется контекст, из которого можно как собрать информацию по существующему коду, так и, собственно, добавить новый.

Для каждого файла исходного кода Roslyn предоставляет синтаксическое дерево в виде объекта SyntaxTree:

GeneratorExecutionContext.Compilation.SyntaxTrees

а так же семантическую модель:

semanticModel =  GeneratorExecutionContext.Compilation.GetSemanticModel(SyntaxTree)

Последняя нужна, чтобы по участку кода (узлу синтаксиса) понять его связи с другими частями программы, типами, другими сборками.

Среди всех узлов синтаксических деревьев сборки нам нужно найти только интересующие нас лямбда-выражения типа System.Linq.Expressions.Expression<T> и отобрать из их узлов-потомков выражения, описывающие доступ к членам классов, создание объектов и вызов методов:

По семантике узла, так называемому символу (Symbol), можно определять:

  • типы, используемые выражением;

  • область видимости;

  • IsStatic, IsConst, IsReadOnly и другие характеристики.

На основе такой информации и будем генерировать подходящий код.

В Roslyn API (Microsoft.CodeAnalysis) построить сигнатуру намного проще, чем c API рефлексии (System.Reflection). Достаточно сконвертировать символ в строку при помощи методаISymbol.ToDisplayString(SymbolDisplayFormat) c подходящим форматом:

Зная сигнатуры свойства/поля, его типа и обладателя формируем строки для добавления делегатов:

Оформляем код добавления делегатов в класс и отдаем компилятору:

var sourceBuilder = new StringBuilder(@"namespace ExpressionDelegates.AccessorRegistration{  public static class ModuleInitializer  {    public static void Initialize()    {");      foreach (var line in registrationLines)      {        sourceBuilder.AppendLine();        sourceBuilder.Append(' ', 6).Append(line);      }      sourceBuilder.Append(@"    }  }}");GeneratorExecutionContext.AddSource(  "AccessorRegistration",  SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));

Этот код обязательно будет добавлен в сборку ...если генератор сможет отработать :)

Дело в том, что хоть Source Generators технически и не фича языка, поддерживаются они только в проектах с C# 9+. Позволить такую роскошь без костылей и ограничений на данный момент могут только проекты на .NET 5.

Совместимость

Поддержку Roslyn Source Generators API для .NET Standard, платформ .NET Core, .NET Framework и даже Xamarin поможет организовать Uno.SourceGeneration.

Uno.SourceGeneration предоставляет собственные копии интерфейса ISourceGenerator и атрибута [Generator], которые при миграции на С# 9 меняются на оригинальные из пространства имен Microsoft.CodeAnalysis простым удалением импортов Uno:

using Uno.SourceGeneration;using GeneratorAttribute = Uno.SourceGeneration.GeneratorAttribute;using ISourceGenerator = Uno.SourceGeneration.ISourceGenerator;
Для подключения достаточно добавить несколько строк в файл проекта.

В проект, где генератор будет использоваться:

<ItemGroup>  <SourceGenerator Include="PATH\TO\GENERATOR.dll" /></ItemGroup>

Например, распространяя генератор через nuget, подключение можно осуществлять вложением MSBuild props файла со следующим путём:

Инициализация

Так как API для доступа к делегатам у нас в одной сборке, а код деревьев выражений и соответственно сгенерированные для них делегаты в других, необходим механизм их автоматической инициализации.

Для этих целей отлично подходит Module Initializer. Это конструктор сборки (а точнее ее модуля), который запускается сразу после ее загрузки и до вызовов к остальному коду. Он давно есть в CLR, но к сожалению, в C# его поддержка c атрибутом [ModuleInitializer] добавлена только в 9 версии.

Решение по добавлению конструктора в сборку с более широкой поддержкой платформ есть у Fody плагин Fody.ModuleInit. После компиляции добавляет классы с именами ModuleInitializer в конструктор сборки. В такой класс и будем оборачивать инициализацию сгенерированных делегатов.

Подключение Fody.ModuleInit через MSBuild свойства вместо FodyWeavers.xml исключит конфликты с другими Weaver-ами Fody в проекте клиента.

Использование

Таким образом, при сборке проекта:

  1. Source Generator добавит в сборку код, регистрирующий делегаты для деревьев выражений, в обертке класса ModuleInitializer.

  2. Fody.ModuleInit добавит ModuleInitializer в конструктор сборки.

  3. Во время работы приложения при подгрузке сборки выполнится ModuleInitializer, и сгенерированные делегаты будут добавлены к использованию.

Проверяем:

Expression<Func<string, int>> expression = s => s.Length;MemberInfo accessorInfo = ((MemberExpression)expression.Body).Member;Accessor lengthAccessor = ExpressionDelegates.Accessors.Find(accessorInfo);var length = lengthAccessor.Get("17 letters string");// length == 17

При декомпиляции сборки видно, что сгенерированный код и инициализатор модуля на месте:

Бенчмарки

Сгенерированные делегаты выполняются немного медленнее, чем обычные из-за приведения типов и возможной упаковки параметров значимых типов.

Действие

Время, нс

Вызов простого делегата конструктора

4.6937 0.0443

Вызов сгенерированного делегата конструктора

5.8940 0.0459

Поиск и вызов сгенерированного делегата конструктора

191.1785 2.0766

Компиляция выражения и вызов конструктора

88,701.7674 962.4325

Вызов простого делегата доступа к свойству

1.7740 0.0291

Вызов сгенерированного делегата доступа к свойству

5.8792 0.1525

Поиск и вызов сгенерированного делегата доступа к свойству

163.2990 1.4388

Компиляция выражения и вызов геттера

88,103.7519 235.3721

Вызов простого делегата метода

1.1767 0.0289

Вызов сгенерированного делегата метода

4.1000 0.0185

Поиск и вызов сгенерированного делегата метода

186.4856 2.5224

Компиляция выражения и вызов метода

83,292.3139 922.4315

Полный вариант таблицы, с бенчмарками интерпретации.

А судя по результату профилирования поиска сгенерированного делегата, самое долгое построение сигнатуры, ключа для поиска.

Flame-график бенчмарка поиска и вызова сгенерированного делегата доступа к свойствуFlame-график бенчмарка поиска и вызова сгенерированного делегата доступа к свойству

Идеи насчёт оптимизации построения сигнатур по System.Reflection.MemberInfo приветствуются. Реализация на момент написания.

Заключение

По итогу получилось современное решение для кодогенерации с актуальной совместимостью и автоматической инициализацией.

Полный код можно посмотреть на: github/ExpressionDelegates, а подключить через nuget.

Для тех, кто будет пробовать Source Generators хотелось бы отметить несколько полезностей:

  • Source Generator Playground (github).
    Позволяет экспериментировать с Roslyn Source Generators в браузере, онлайн.

  • Окно визуализации синтаксиса для Visual Studio.
    Удобный инструмент для знакомства с Roslyn Syntax API на собственном коде.

  • Отлаживается Source Generator вызовом отладчика из его кода. Пример.
    Для этого нужен компонент Visual Studio Just-In-Time debugger и включенная настройка Tools -> Options -> Debugging -> Just-In-Time Debugging -> Managed.

  • В сгенерированных *.cs файлах срабатывают брейкпоинты, проверено в Visual Studio16.8.
    При генерации через Uno.SourceGeneration файлы размещаются по пути: \obj\{configuration}\{platform}\g\.
    С Roslyn Source Generators их появление включается через MSBuild свойство EmitCompilerGeneratedFiles.
    Стандартный путь: \obj\{configuration}\{platform}\generated\, переопределяется в свойстве CompilerGeneratedFilesOutputPath.

  • Source Generators можно конфигурировать свойствами MSBuild.
    При использовании Uno.SourceGeneration значение получают вызовом

    GeneratorExecutionContext.GetMSBuildPropertyValue(string)
    

    Для Roslyn Source Generators требуемые свойства необходимо сперва отдельно обозначить в MSBuild группе CompilerVisibleProperty и только после вызывать:

    GeneratorExecutionContext.AnalyzerConfigOptions.GlobalOptions  .TryGetValue("build_property.<PROPERTY_NAME>", out var propertyValue)
    
  • Из генератора можно кидать предупреждения и ошибки сборки.

    //Roslyn Source GeneratorsGeneratorExecutionContext.ReportDiagnostic(Diagnostic)//Uno.SourceGeneration:GeneratorExecutionContext.GetLogger().Warn/Error().
    
Подробнее..

Работаем с notebook в VS Code с помощью расширения dotnet interactive

20.02.2021 14:06:35 | Автор: admin
Скриншот notebook'a из VS CodeСкриншот notebook'a из VS Code

Сегодня я хочу рассказать вам о таком замечательном инструменте как "dotnet interactive". Я покажу на своём примере как и для чего я начал его использовать, и вкратце опишу с чего начать.

Проблема

Моя работа связана с разработкой программы, предназначенной для оценки эффективности средств физической охраны. Данный продукт в своём ядре содержит имитационную модель, результатом которой является файл протокола, в котором описаны события моделируемого эксперимента. Это могут быть такие события как нарушитель попал в зону камеры или группа реагирования ведет преследование нарушителя и прочие подобные события, которые могут происходить при моделировании.

По итогам протокола считаются различные статистические метрики, которые потом уходят в отчёт. Сейчас формулы, как считать нужную нам статистику, разбросаны по различным этапам ТЗ, поэтому, когда я вчера узнал о "dotnet-interactive" мне сразу пришла мысль о создании notebook'a в формате "Описание метрики"-"Формула"-"Код"-"График", в котором можно будет загрузить любой файл протокола и в интерактивном формате проходить и считать интересующие нас метрики.

Приступаем к созданию notebook'a

Прежде всего, у вас должен быть установлен .net5 sdk и последняя версия VS Code. Далее, нужно лишь установить расширение ".NET Interactive Notebooks". Данное расширение сейчас имеет статус "Preview", однако уже сейчас там можно делать много интересных вещей.

Когда мы установили расширение, можем создать рабочую директорию, в которой будут лежать нужные библиотеки, скрипты и файлы. Открываем её в VS Code и окне команд вбиваем ".NET Interactive: Create new blank notebook" и начинаем наполнять наш notebook.

В первом блоке кода я определил загрузку файла протокола:

#load "Load.fsx"open Loadlet Experiment = loadSep "2021.02.03_15.55.58_gen.sep"

Здесь я на F# подключил скрипт, который инкапсулирует в себе логику открытия файла и xml-сериализацию:

#r "nuget: System.Text.Encoding.CodePages"#r "AKIM.Protocol.dll"open System.IOopen AKIM.Protocolopen System.Xml.Serializationopen System.Textlet loadSep path=        let deserializeXml (xml : string) =        let toBytes (x : string) = Encoding.UTF8.GetBytes x        let xmlSerializer = XmlSerializer(typeof<Experiment>)        use stream = new MemoryStream(toBytes xml)        xmlSerializer.Deserialize stream :?> Experiment    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance)        deserializeXml (File.ReadAllText(path, Encoding.GetEncoding(1251)))

В этом скрипте я подключаю nuget пакет для кодировки и свою библиотеку с dto-классами, написанную на C#.

Во втором блоке notebook'a уже в c#-intaractive я подключаю нужные для работы с экспериментом пространства имён и шарю объект в с# из f#, определенного в первом блоке

#r "AKIM.Protocol.dll"using AKIM.Protocol;using AKIM.Protocol.Events;using AKIM.Protocol.Events.OperatorSvn;using AKIM.Protocol.Events.OperSb;using AKIM.Protocol.Events.RespUnits;using AKIM.Protocol.Events.Intruders;using AKIM.Protocol.Events.Sens;using AKIM.Protocol.Events.System;#!share --from fsharp Experiment

Собственно дальше мы можем в произвольном порядке описывать и считать нужные нам метрики, используя для этого объект эксперимента. Например, следующий блок выводит общее количество проникновений на объект и количество отказов нарушителя от проникновения

var allTests = Experiment.Tests.Count;var penetrations = Experiment.Tests.Where(t => t.Events.Last() is PenetrationEvent).Count();var nonPenetrations = Experiment.Tests.Where(t => t.Events.Last() is NonPenetEvent).Count();var eve = Experiment.Tests.First().Events.FirstOrDefault(t => t is VisContactEvent);Console.WriteLine(eve?.GetDescription());Console.WriteLine($"Количество проникновений {penetrations} из {allTests}")

Нажав на запуск выполнения кода мы получаем следующий вывод:

А дальше я могу использовать полученные значения для построения красивой диаграммы или графика, например:

#r "nuget: XPlot.Plotly"#!share --from csharp penetrations #!share --from csharp nonPenetrations#!share --from csharp allTestsopen XPlot.PlotlyChart.Pie(seq {("Кол-во проникновений",penetrations);               ("Нейтролизовали",allTests- penetrations-nonPenetrations);               ("Отказ от проникновения",nonPenetrations)}) |> Chart.Show

При выполнении график открывается у меня в браузере, хотя я видел, как в некоторых туториалах он открывается снизу блока с кодом.

Итоговая диаграммаИтоговая диаграмма

Что дальше

В дальнейшем, есть идея описать язык взаимодействия с событиями на F# в виде отдельной библиотеки или скрипта, как это было описано, например, тут. Так как, на мой взгляд, подобный notebook должен заполнять аналитик проекта, а не программист.

Что не работает?

Мне не удалось загрузить файл скрипта на С# с расширениями "*.csx" в с#-interactive. Возможно еще не завезли, возможно не правильно готовлю. Плюс не удалось решить, почему графики открываются в браузере, а не снизу блока с кодом. Также в markdown блоке не хотят отображаться формулы в формате $$...$$.

Выводы

Я считаю, что этот инструмент должен попробовать каждый .net разработчик. Вариантов использования масса: обработка результатов, прототипирование каких-то идей, изучение F# или C#, скриптинг для работы с операционной системой, например, чтобы manage'ить какие-то файлы. Лично я, когда случайно узнал вчера об этом инструменте, был в диком восторге, что и побудило меня сделать этот пост, так как мало, кто об этой штуке слышал (но это не точно).

Хочу поблагодарить своего подписчика на ютубе, Arkadiy Kuznetsov, который подсказал мне о существовании такого инструмента.

Жду отзывов об использовании этой штуки в комментариях + возможно, кто-то даст подсказки на решение проблем, которые у меня возникли с графиками и загрузкой c# скриптов.

Спасибо за внимание.

Полезные ссылки

Официальная репа, в которой есть также документация
.NET Interactive + ML.NET
Новые фичи f#(в начале видео использует dotnet-intaractive)

Подробнее..

8 анонсов конференции Microsoft Build 2021

26.05.2021 10:15:20 | Автор: admin

В рамках глобальной технологической конференции Miсrosoft Build 2021, которая проходит с 25 по 27 мая в онлайн-формате, компания продемонстрировала новые решения для разработчиков, а также совместно с партнерами анонсировала инициативу в области устойчивого развития.

Это 8 анонсов конференции Microsoft Build, которые подобрала наша бизнес-команда. Ну а подборку от команды разработки ждите завтра!

Главные новости:

  • Анонспервого продуктаMicrosoftна базе GPT-3.Одна из самых мощных моделей естественного языка в мире GPT-3 от OpenAI будет интегрирована в платформу для low-code разработки Microsoft Power Apps. Благодаря искусственному интеллекту пользователи теперь смогут создавать приложения без глубоких знаний кода или формул, используя диалоговые команды. GPT-3 работает в облаке Microsoft Azure, а для ее дообучения был использован сервис Azure Machine Learning. Интеграция станет одним из первых применений модели в решении прикладных бизнес-задач.

  • ЗапускФонда экологичного ПОGreenSoftwareFoundation.Учредители фонда Microsoft, GitHub, Accenture и ThoughtWorks при поддержке Linux Foundation намерены приложить усилия к популяризации экологичного подхода к разработке ПО, для того чтобы компании ИТ-сектора могли внести свой вклад в снижение уровня углеродных выбросов. Также они будут инициировать создание отраслевых стандартов и стимулировать инновационные разработки в данной области в сотрудничестве с некоммерческими и научными организациями.

  • ЗапусксервисовAzure Applied AI.Новая категория сервисов позволит разработчикам существенно ускорить создание решений на базе ИИ для распространенных бизнес-сценариев, таких как обработка документов, обслуживание клиентов, извлечение информации из материалов и т.д.

  • ИнтеграцияAzure Security CenterиGitHub.Функция позволит отслеживать результаты сканирования контейнеров, полученные с помощью GitHub Actions. Благодаря этому команды SecOps (Security Operations) смогут быстрее реагировать и оповещать о проблемах, что обеспечит более продуктивную коллаборацию между ними и разработчиками.

  • Возможностьзапускать сервисыAzureна базеKubernetesв любом месте с помощьюAzureArc.Теперь у разработчиков появилась возможность запускать различные службы приложений Azure (Azure App Service, Azure Functions, Azure Logic Apps, Azure API Management, Azure Event Grid) где угодно включая облака от разных производителей, таких как Amazon и Google, локальные серверы и устройства граничных вычислений.

  • Новые возможностидля разработчиков вMicrosoftTeams. Нововведения позволят разработчикам реализовывать еще больше сценариев использования Teams. Например, выступление нескольких спикеров одновременно, автоматизация различных функций во встречах с помощью API (к примеру, ее начала и окончания), создание собственных фонов для режима Together mode, а также доступ к аудио и видеопотокам в режиме реального времени для расшифровки, перевода, ведения заметок и многого другого.

  • РасширениеVisual StudioдляPower Platform.Оно позволит разработчикам использовать знакомые инструменты Visual Code в платформе Power Platform. Это откроет новые возможности для совместной работы разработчиков и сотрудников из бизнес-подразделений.

  • Поддержкаприложений графического интерфейса пользователя (GUI) Linux в подсистеме Windows для Linux (WSL).WSL позволяет пользователям запускать свои любимые инструменты, утилиты и приложения Linux. Теперь она также включает поддержку приложений GUI. Они работают из коробки, что позволяет тестировать, разрабатывать и запускать полноценные приложения Linux GUI на устройстве под управлением Windows без настройки традиционной виртуальной машины.

Подробнее..

Гарантированная локализациярусификация консоли Windows

03.03.2021 20:06:54 | Автор: admin

Введение

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

В целом, локализация консоли Windows при наличии соответствующего языкового пакета не представляется сложной. Тем не менее, полное и однозначное решение этой проблемы, в сущности, до сих пор не найдено. Причина этого, главным образом, кроется в самой природе консоли, которая, являясь компонентом системы, реализованным статическим классом System.Console, предоставляет свои методы приложению через системные программы-оболочки, такие как командная строка или командный процессор (cmd.exe), PowerShell, Terminal и другие.
По сути, консоль находится под двойным управлением - приложения и оболочки, что является потенциально конфликтной ситуацией, в первую очередь в части использования кодировок.

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

Виды консолей

В общем случае функции консоли таковы:

  • управление операционной системой и системным окружением приложений на основе применения стандартных системных устройств ввода-вывода (экран и клавиатура), использования команд операционной системы и/или собственно консоли;

  • запуск приложений и обеспечение их доступа к стандартным потокам ввода-вывода системы, также с помощью стандартных системных устройств ввода-вывода.

Основная консоль Windows - командная строка или иначе командный процессор (CMD). Большие возможности предоставляют оболочки PowerShell (PS), Windows PowerShell (WPS) и Terminal. Отдельным видом консоли можно считать консоль отладки Visual Studio (CMD-D).

Конфликт кодировок

Полностью локализованная консоль в идеале должна поддерживать все мыслимые и немыслимые кодировки приложений, включая свои собственные команды и команды Windows, меняя "на лету" кодовые страницы потоков ввода и вывода. Задача нетривиальная, а иногда и невозможная - кодовые страницы DOS (CP437, CP866) плохо совмещаются с кодовыми страницами Windows и Unicode.

История кодировок здесь: О кодировках и кодовых страницах / Хабр (habr.com)

Исторически кодовой страницей Windows является CP1251 (Windows-1251, ANSI, Windows-Cyr), уверенно вытесняемая 8-битной кодировкой Юникода CP65001 (UTF-8, Unicode Transformation Format), в которой выполняется большинство современных приложений, особенно кроссплатформенных. Между тем, в целях совместимости с устаревшими файловыми системами, именно в консоли Windows сохраняет базовые кодировки DOS - CP437 (DOSLatinUS, OEM) и русифицированную CP866 (AltDOS, OEM).

Совет 1. Выполнять разработку текстовых файлов (программных кодов, текстовых данных и др.) исключительно в кодировке UTF-8. Мир любит Юникод, а кроссплатформенность без него вообще невозможна.

Совет 2. Периодически проверять кодировку, например в текстовом редакторе Notepad++. Visual Studio может сбивать кодировку, особенно при редактировании за пределами VS.

Поскольку в консоли постоянно происходит передача управления от приложений к собственно командному процессору и обратно, регулярно возникает "конфликт кодировок", наглядно иллюстрируемый таблица 1 и 2, сформированных следующим образом:

Были запущены три консоли - CMD, PS и WPS. В каждой консоли менялась кодовая страница с помощью команды CHCP, выполнялась команда Echo c двуязычной строкой в качестве параметра (табл. 1), а затем в консоли запускалось тестовое приложение, исходные файлы которого были созданы в кодировке UTF-8 (CP65001): первая строка формируется и направляется в поток главным модулем, вторая вызывается им же, формируется в подключаемой библиотеке классов и направляется в поток опять главным модулем, третья строка полностью формируется и направляется в поток подключаемой библиотекой.

Команды и код приложения под катом

команды консоли:

  • > Echo ffffff фффффф // в командной строке

  • PS> Echo ffffff фффффф // в PowerShell

  • PS> Echo ffffff ?????? // так выглядит та же команда в Windows PowerShell

код тестового приложения:

using System;using ova.common.logging.LogConsole;using Microsoft.Extensions.Logging;using ova.common.logging.LogConsole.Colors;namespace LoggingConsole.Test{    partial class Program    {        static void Main2(string[] args)        {            ColorLevels.ColorsDictionaryCreate();            Console.WriteLine("Hello World! Привет, мир!");     //вывод строки приветствия на двух языках            LogConsole.Write("Лог из стартового проекта", LogLevel.Information);            Console.WriteLine($"8. Active codepage: input {Console.InputEncoding.CodePage}, output {Console.OutputEncoding.CodePage}");            Console.ReadKey();        }     }}

Командную часть задания все консоли локализовали практически без сбоев во всех кодировках, за исключением: в WPS неверно отображена русскоязычная часть команды во всех кодировках.

Табл. 1. Результат выполнения команды консоли Echo ffffff ффффффТабл. 1. Результат выполнения команды консоли Echo ffffff фффффф

Вывод тестового приложения локализован лишь в 50% испытаний, как показано в табл.2.

Табл. 2. Результат запуска приложения LoggingConsole.TestТабл. 2. Результат запуска приложения LoggingConsole.Test

Сoвет 3. Про PowerShell забываем раз и навсегда.

По умолчанию Windows устанавливает для консоли кодовые страницы DOS. Чаще всего CP437, иногда CP866. Актуальные версии командной строки cmd.exe способны локализовать приложения на основе русифицированной кодовой страницы 866, но не 437, отсюда и изначальный конфликт кодировок консоли и приложения. Поэтому

Совет 4. Перед запуском приложения необходимо проверить кодовую страницу консоли командой CHCP и ей же изменить кодировку на совместимую - 866, 1251, 65001.

Совет 5. Можно установить кодовую страницу консоли по умолчанию. Кратко: в разделе реестра \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor добавить или изменить значение параметра Autorun на: chcp <номер кодовой страницы>. Очень подробно здесь: Изменить кодовую страницу консоли Windows по умолчанию на UTF-8 (qastack.ru)

Проблемы консолей Visual Studio

В Visual Studio имеется возможность подключения консолей, по умолчанию подключены командная строка для разработчика и Windows PowerShell для разработчика. К достоинствам можно отнести возможности определения собственных параметров консоли, отдельных от общесистемных, а также запуск консоли непосредственно в директории разработки. В остальном - это обычные стандартные консоли Windows, включая, как показано ранее, установленную кодовую страницу по умолчанию.

Отдельной опцией Visual Studio является встроенная односеансная консоль отладки, которая перехватывает команду Visual Studio на запуск приложения, запускается сама, ожидает компиляцию приложения, запускает его и отдает ему управление. Таким образом, отладочная консоль в течение всего рабочего сеанса находится под управлением приложения и возможность использования команд Windows или самой консоли, включая команду CHCP, не предусмотрена. Более того, отладочная консоль не воспринимает кодовую страницу по умолчанию, определенную в реестре, и всегда запускается в кодировке 437 или 866.

Совет 6. Тестирование приложения целесообразно выполнять во внешних консолях, более дружелюбных к локализации.

Анализ проблем консолей был бы не полон без ответа на вопрос - можно ли запустить консольное приложение без консоли? Можно - любой файл ".exe" запустится двойным кликом, и даже откроется окно приложения. Однако консольное приложение, по крайней мере однопоточное, по двойному клику запустится, но консольный режим не поддержит - все консольные вводы-выводы будут проигнорированы, и приложение завершится

Локализация отладочной консоли Visual Studio

Отладочная консоль - наиболее востребованная консоль разработчика, гораздо более удобная, чем внешняя консоль, поэтому резонно приложить максимум усилий для ее локализации.

На самом деле, правильнее говорить о локализации приложения в консоли - это важное уточнение. Microsoft по этому поводу высказывается недвусмысленно: "Programs that you start after you assign a new code page use the new code page.However, programs (except Cmd.exe) that you started before assigning the new code page will continue to use the original code page". Иными словами, консоль можно локализовать когда угодно и как угодно, но приложение будет локализовано в момент стабилизации взаимодействия с консолью в соответствии с текущей локализацией консоли, и эта локализация сохранится до завершения работы приложения. В связи с этим возникает вопрос - в какой момент окончательно устанавливается связь консоли и приложения?

Важно! Приложение окончательно стабилизирует взаимодействие с консолью в момент начала ввода-вывода в консоль, благодаря чему и появляется возможность программного управления локализацией приложения в консоли - до первого оператора ввода-вывода.

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

F:\LoggingConsole.Test\bin\Release\net5.0>chcpActive code page: 1251F:\LoggingConsole.Test\bin\Release\net5.0>loggingconsole.testCodepages: current 1251:1251, setted 437:437,  5  -: =Codepages: current 437:437, setted 65001:65001,  5  -: =Codepages: current 65001:65001, setted 1252:1252,  5  -: =Codepages: current 1252:1252, setted 1251:1251, вводим 5 символов по-русски: йцуке=йцукеCodepages: current 1251:1251, setted 866:866, ттюфшь 5 ёшьтюыют яю-Ёёёъш: щъх=щъхCodepages: current 866:866, setted 1251:1251, вводим 5 символов по-русски: йцуке=йцукеCodepages: current 1251:1251, setted 1252:1252,  5  -: =F:\LoggingConsole.Test\bin\Release\net5.0>chcpActive code page: 1252
  • приложение запущено в консоли с кодовыми страницами 1251 (строка 2);

  • приложение меняет кодовые страницы консоли (current, setted);

  • приложение остановлено в консоли с кодовыми страницами 1252 (строка 11, setted);

  • по окончании работы приложения изменения консоли сохраняются (строка 14 - Active codepage 1252);

  • Приложение адекватно локализовано только в случае совпадения текущих кодовых страниц консоли (setted 1251:1251) с начальными кодовыми страницами (строки 8 и 10).

Код тестового приложения под катом
using System;using System.Runtime.InteropServices;namespace LoggingConsole.Test{    partial class Program    {        [DllImport("kernel32.dll")] static extern uint GetConsoleCP();        [DllImport("kernel32.dll")] static extern bool SetConsoleCP(uint pagenum);        [DllImport("kernel32.dll")] static extern uint GetConsoleOutputCP();        [DllImport("kernel32.dll")] static extern bool SetConsoleOutputCP(uint pagenum);                static void Main(string[] args)        {            Write(437);            Write(65001);            Write(1252);            Write(1251);            Write(866);            Write(1251);            Write(1252);         }        static internal void Write(uint WantedIn, uint WantedOut)        {            uint CurrentIn = GetConsoleCP();            uint CurrentOut = GetConsoleOutputCP();            Console.Write($"current {CurrentIn}:{CurrentOut} - текущая кодировка, "); /*wanted {WantedIn}:{WantedOut},*/            SetConsoleCP(WantedIn);            SetConsoleOutputCP(WantedOut);            Console.Write($"setted {GetConsoleCP()}:{GetConsoleOutputCP()} - новая кодировка, ");            Console.Write($"вводим 3 символа по-русски: ");            string str = "" + Console.ReadKey().KeyChar.ToString();            str += Console.ReadKey().KeyChar.ToString();            str += Console.ReadKey().KeyChar.ToString();            Console.WriteLine($"={str}");        }              static internal void Write(uint ChangeTo)        {            Write(ChangeTo, ChangeTo);        }    }}

Программное управление кодировками консоли - это единственный способ гарантированной адекватной локализацией приложения в консоли. Языки .Net такой возможности не предоставляют, однако предоставляют функции WinAPI: SetConsoleCP(uint numcp) и SetConsoleOutputCP(uint numcp), где numcp - номер кодовой страницы потоков ввода и вывода соответственно. Подробнее здесь: Console Functions - Windows Console | Microsoft Docs. Пример применения консольных функций WInAPI можно посмотреть в тестовом приложении под катом выше.

Совет 7. Обязательный и повторный! Функции SetConsoleCP должны размещаться в коде до первого оператора ввода-вывода в консоль.

Стратегия локализации приложения в консоли

  1. Удалить приложение PowerShell, заменив его Windows PowerShell;

  2. Установить в качестве кодовую страницу консоли по умолчанию CP65001 (utf-8 Unicode) или CP1251 (Windows-1251-Cyr), см. совет 5;

  3. Разработку приложений выполнять в кодировке utf-8 Unicode;

  4. Контролировать кодировку файлов исходных кодов, текстовых файлов данных, например с помощью Notepad++;

  5. Реализовать программное управление локализацией приложения в консоли, пример ниже под катом:

Пример программной установки кодовой страницы и локализации приложения в консоли
using System;using System.Runtime.InteropServices;namespace LoggingConsole.Test{    partial class Program    {      static void Main(string[] args)        {          [DllImport("kernel32.dll")] static extern bool SetConsoleCP(uint pagenum);        [DllImport("kernel32.dll")] static extern bool SetConsoleOutputCP(uint pagenum);            SetConsoleCP(65001);        //установка кодовой страницы utf-8 (Unicode) для вводного потока            SetConsoleOutputCP(65001);  //установка кодовой страницы utf-8 (Unicode) для выводного потока             Console.WriteLine($"Hello, World!");        }    }}
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru