Monday, June 30, 2014

Как отлаживать .NET Framework Source

В этой статье мы поговорим о том, как можно дебажить сами библиотеки .NET Framework в своих программах. Возможно бывали случаи, когда вам было интересно как работает внутри StringBuilder, или как построен класс Task, что происходит внутри библиотек, которые идут в поставке и которые мы добавляем, как ссылки в свой проект, воспринимая это как должное и не зная, как это работает изнутри. 
Недавно во время разговора с коллегами мы затронули тот факт, что процесс отладки самих библиотек описан Microsoft ("How to: Debug .NETFramework Source"), но с ним могут возникнуть сложности. Но поскольку недавно компания Microsoft анонсировала исходники .NET Framework 4.5.1 (referencesource.microsoft.com), процесс отладки стает еще более простым. Ниже представлен скриншот того, что собой представляет тот или иной класс без запуска среды программирования.
Давайте пошагово пройдемся по варианту, который идет в MSDN, а затем воспользуемся новыми возможностями отладки, используя referencesource.microsoft.com. Первым делом запустим нашу среду разработки Visual Studio (у меня это Visual Studio 2013) и откроем меню Tools->Options.
Затем перейдем в категорию Debugging.
Как видите, у меня для простоты работает поиск. Если у вас более старая версия студии поиска у вас может не быть. Затем переходим в пункт меню General и ставим галочку на Enable .NET Framework source stepping.
После этого выскочит окно предупреждения, просто нажмите дважды на кнопку OK. После этого переходим в категорию Symbols.
Затем изменяем путь в Cache symbols in this directory.
Если вы хотите загрузить сразу все .pdb файлы, можете поставить галочку Microsoft Symbol Servers и нажать на кнопку Load all symbols, которая на предыдущем рисунке неактивна. Давайте проверим, что у нас из этого получилось. Для этого создадим новое консольное приложение и назовем его DebuggingSourceSample.
У вас при запуске приложения произойдет загрузка ваших .pdb-файлов.
Затем напишем простенький пример, который будет использовать для теста.
class Program
{
    static void Main(string[] args)
    {
        var xml = XElement.Parse(@"<Author>John</Author>");
        var a = xml.ToString();
        Console.ReadLine();
    }
}
При первом запуски необходимые для отладки файлы будут подгружены автоматически в проект.
Давайте запустим наш проект и посмотрим, что из этого получилось. Для того чтобы перейти непосредственно в сам метод, нам нужно воспользоваться клавишей F11. 
Затем снова нажимаем на F11.
И мы уже внутри метода. Неплохо, не правда ли? Еще раз нажимаем на клавишу F11.
Погружаемся глубже и глубже, и так далее до конца метода, либо до того момента, до которого нам нужно. Теперь несколько нюансов, рекомендуемых для отладки .NET Framework в Visual Studio 2013. Если у вас не 2013 студия, вы можете пропустить данный пункт. Во-первых, сами настройки дебаггера должны иметь следующий вид:
Для Debugging->Symbols добавим новый путь referencesource.
Теперь небольшой бонус, который я подсмотрел в блоге Скотта Хансельмана в статье ".NETFramework Library Source Code available for viewing" и "Announcing the new Roslyn-powered .NET Framework Reference Source". Не всё, к сожалению, можно дебажить с помощью pdb-файлов. Например, такие части кода, как работа со списком, со StringBuilder, не позволят нам посмотреть, как это работает. Но благодаря возможностям, которые нам предоставляет Roslyn, мы можем понять код, который мы вызываем. Например, в таком коде у нас не сработает навигация на F11, и мы не сможем посмотреть, что происходит внутри.
static void Main(string[] args)
{
    var sb = new StringBuilder("Hello World");
    var a = sb.ToString();
    Console.ReadLine();
}
Но мы можем посмотреть, как построена логика по ссылке http://referencesource.microsoft.com/.
Но можно скачать расширение для Visual Studio Ref12, которое будет делать эту навигацию вместо нас, используя для этого горячую клавишу F12.
Если мы посмотрим в правую сторону окна браузера, то мы можем увидеть такие кнопки:
Document Outline

Project Explorer

Namespace Explorer


Функция Document Outline позволяет просмотреть список типов и методов в файле.
Функция Project Explorer позволяет просмотреть отображение в виде дерева файлов в текущем проекте / сборке. Ссылки и список папок, в зависимости сборки (недоступно для mscorlib):
И, наконец, Namespace Explorer показывает пространство имен и типы в текущем проекте / сборке. 
Кстати, вы можете использовать в offline режиме. Для этого вам придётся закачать исходники .NET Framework 4.5.1, которые доступны по ссылке referencesource.
В распакованном виде исходники занимают ~ 300 MB.
Теперь плохие новости, с которыми вы можете столкнуться, но которых мне довелось избежать. Например, Скотту Хансельману нужно было поставить hot fix для 64-битной Windows. Вот ссылка на оригинальную статью: ".NET Framework Library Source Code available for viewing". Теперь те ошибки, которые связаны с Visual Studio 2013, известны компании Microsoft и описаны в Configure Visual Studio 2013 for debugging .NET framework, в пункте под названием Troubleshooting. В целом процесс отладки .NET Framework библиотек довольно-таки увлекательный и несложный. Для этого вам нужны будут, по сути, два вспомогательных окна: Call Stack, которое вы можете вызвать с помощью горячих клавиш Ctrl+Alt+C и которое показывает загруженные сборки, стек потока и многое другое, а также окно Modules, для которого также есть горячие клавиши Ctrl+Alt+U и которое показывает список загруженных сборок. На рисунке ниже показано, откуда эти окна можно вызвать.
С помощью того же окна Modules вы сможете убедиться в том, что ваши .pdb-файлы успешно загружены по тому пути, который вы указали в настройках. На рисунке ниже показано мое окно Modules с путем к загруженным .pdb-файлам.
На этой ноте буду завершать данную статью. Если у вас остались какие-то вопросы, буду рад на них ответить. Счастливой отладки.

Sunday, June 29, 2014

Краткий обзор Visual Studio "14" CTP

В этой статье мы рассмотрим предварительный выпуск (Community Technology Preview − CTP) новой версии Visual Studio под кодовым названием Visual Studio "14". Поскольку дата релиза − 3 июня 2014, то есть в том месяце, когда я решил написать этот краткий обзор, думаю данная тема будет актуальной для многих обладателей текущей или этой новой версии IDE. Компания Microsoft сбавила свою агрессивную ценовую политику по поводу Visual Studio 2013, которая на момент написания статьи являлась последней актуальной версией данного продукта. Компания Майкрософт предлагала купить Professional версию данной идеи за 499 $ (ссылка на официальный источник).

К сожалению, Ultimate версия с каждым годом становится дороже и дороже. На момент написания статьи ее стоимость достигла 13, 299 $.

Для обычных разработчиков вроде меня цена кусается, ее могут себе позволить разве что фирмы, для которых покупка Ultimate является оправданной, например, использованием TFS или кто использует Microsoft Test Manager для генерации UI тестов, например, для приложений, написанных на WPF. Вряд ли такую стоимость можно отдать за те утилиты и метрики, которые добавили в студию. В общем, рассчитывать на то, что Visual Studio "14" будет дешевле, чем версия 2013 студии, не стоит. Разве что Professional версия немного упадет в цене. Но из-за тех новых возможностей, которые Майкрософт добавляет в студию, цену она автоматически также тянет вверх. Так что же все-таки интересного нас ждет в этой студии и почему Microsoft впервые за долгое время решила сделать такой подарок для разработчиков? Предполагаю, что это их шаги в рамках открытости и доступности своих продуктов, часть из которых они сделали open source (хотя Майкрософт называет их не 'open source' проектами, а 'openness' – "открытость"). Полный список того, что доступно в новой студии, можно посмотреть по ссылке. Ниже приведен детальный список нововведений, которые вошли в поставку.

·   ASP.NET vNext: This release of Visual Studio supports creating and developing ASP.NET vNext applications. ASP.NET vNext is a lean and composable .NET stack for building modern web applications for both cloud and on-premises servers. It includes the following features:
o    ASP.NET MVC and Web API have been unified into a single programming model. 
o    A no-compile developer experience.
o    Dependency injection out-of-the-box.
o    Side-by-side: Deploy the runtime and framework by using your application.
o    NuGet everything, even the runtime itself.
o    All open source is on the .NET Foundation and takes contributions.
For more information about ASP.NET vNext in Visual Studio, go to the ASP.NET vNext website.
·        This release of Visual Studio also includes all the current ASP.NET and web development features that are released as parts of Visual Studio 2013 Update 2. Learn more here.
·        The core IDE and editing experiences for C# and Visual Basic have been replaced with new experiences that are built on the .NET Compiler Platform "Roslyn." Generally, the experience should be unchanged. However, there are numerous small improvements.
·    C# refactoring support has been completely revamped. There are two new core refactorings: Inline Temporary Variable and Introduce Explaining Variable. Additionally, refactoring support for Visual Basic has been added for the first time.
·        You can use specific code-aware guidance for the Microsoft platforms and NuGet packages that you're targeting to obtain live code analysis and automatic fixes as you type.
·       Generalized lambda capture: You can assign the result of evaluating an expression to a variable in the capture clause of a lambda. This allows an instance of a move-only type to be captured by value.
·         User-defined literals in the language and standard library: You can append numeric and string literals with meaningful suffixes to give them suitable semantics. The compiler transforms these suffixes into calls to appropriate UDL-operator functions. The <chrono>, <string>, and <complex> headers now provide literal operators for convenience. For example, "1729ms" means std::chrono::milliseconds(1729), "meow"s meansstd::string("meow"), and 3.14i means std::complex<double>(0.0, 3.14).
·   Completed noexcept: You can check whether an expression will throw an exception by using the noexceptoperator. For example, noexcept(func()) will return "true" if func was specified as noexcept.
·         Inline namespaces: You can specify a nested namespace as "inline" to make its contents accessed from its parent namespace.
·        Thread-safe "magic" statics: Static local variables are initialized in a thread-safe way, removing the need for manual synchronization. Be aware that usage of these variables other than initialization is still not protected. Thread safety can be disabled by using /Zc:threadSafeInit- to avoid a dependency on the CRT.
·         Unrestricted unions: You can define unions that contain types with non-trivial constructors. Constructors for such unions have to be manually defined.
·         Finally, all new C++ 11 and C++ 14 language features that are released in the November 2013 compiler CTP for Visual Studio 2013 are also included in this preview. For more information about these features, read thisannouncement. Briefly, these include the following:
o    __func__, extended sizeof, implicit move generation, ref-qualifiers ("&" and "&&" for member functions),alignof and alignas, and inheriting constructors.
o    auto function return type deduction, decltype(auto), and generic lambdas with a limitation of not using [=]/[&] default capture together with generic lambdas. This will be enabled also for generic lambdas in a future release.
o    Resumable functions and awaitproposed for the C++ Concurrency Technical Specification.
·      Null forward iterators: The Standard Library's forward iterators (and stronger) now guarantee that value-initialized iterators compare as equal. This makes it possible to pass an empty range without a parent container. Be aware that generally, value-initialized iterators still cannot be compared to iterators from a parent container.
·         quoted(): These manipulators let iostreams preserve strings that contain spaces.
·  Heterogeneous associative lookup: When it is Enabled by special comparators (such as the less<> and greater<>transparent operator functors), the ordered associative containers gain templated lookup functions. This lets them work with objects that are comparable to keys, without actually constructing keys.
·         integer_sequence: Compile-time integer sequences are now supported to make template metaprogrammingeasier.
·         exchange(): This small utility function makes it convenient to assign a new value to an object and retrieve the old value.
·         get<T>(): This lets a tuple element be accessed by its type (when unique) instead of by its index.
·         Dual-range equal(), is_permutation(), mismatch(): C++98's "range-and-a-half" algorithms that are taking (first1, last1, first2) are difficult to use correctly. While they are still provided, C++14 has added overloads taking (first1, last1, first2, last2) which are significantly easier and safer to use.
·         tuple_element_t: This alias template is added for convenience and consistency with the type traits alias templates.
·         Filesystem "V3" Technical Specification (TS): The interface and implementation of <filesystem> are overhauled to follow this TS, which is likely to be incorporated into C++17.
·         Library Issues: 24 resolutions have been implemented (for example, is_final, make_reverse_iterator()), not including the resolutions that were already implemented in Visual C++ 2013. Notice that a library issue is a bug report for the Standard. It can be resolved by fixing a specification problem or even adding a small feature.
·         <chrono> fixes: The clocks are rewritten to be conformant and precise.
·         Minimal allocator fixes: Several library components (including basic_string and std::function) did not work with user-defined allocators implementing C++11's minimal allocator interface, instead requiring C++03's verbose allocator interface. All occurrences of this problem are fixed.
·         C99 library features: Most of the remaining C99 library features are implemented.
o    snprintf is implemented.
o    The printf and scanf families of functions now support the new C99 format string improvements.
o    The strtod and scanf families of functions now support hexadecimal floating-point.
o    Library conformance is better improved by software updates and adjustments.
·         __restrict: The __restrict keyword is now supported on reference types in addition to pointer types.
·         Improved diagnostics: The compiler will now emit warnings about suspicious code that previously would not have resulted in warnings. For example, shadowed variables will now cause warnings. Warnings have also been made clearer.
·         The /Wv flag: You can use /Wv:XX.YY.ZZZZ to disable warnings that are introduced after compiler version XX.YY.ZZZZ. Notice that the emitted warnings may still differ from those emitted by the specified version.
·         Compiler software updates: We have fixed more than 400 bugs in the compiler. 179 of these were submitted by users through Microsoft Connect.
·         Refactored C Runtime (CRT): This CTP contains the first preview of the substantially refactored CRT.
o    msvcr140.dll no longer exists. It is replaced by a trio of DLLs: vcruntime140.dll, appcrt140.dll, and desktopcrt140.dll.
·         stdio performance: Many performance improvements are made in the stdio library, notably in the sprintf andsscanf families of functions.
·         Object file size reductions: Working together with compiler fixes, the STL's headers are changed to significantly reduce the sizes of object files and static libraries (that is after compilation but before linking. The sizes of linked EXEs/DLLs are unaffected). For example, when you compile a source file that includes all C and C++ Standard Library headers and does nothing else with them, for x86 with /MD /O2, Visual C++ 2013 generated a 731 KB object file. This is improved to be less than 1 KB.
·         Debug checking fixes: The STL's debug checks rejected null pointers that are passed as iterators, even when the Standard guaranteed that they should work (for example, merging two [null, null) ranges to a null output). Every algorithm is inspected and fixed.
·         Create declaration or definition: You can quickly create a function’s declaration or definition in relation to its neighbors. To do this, right-click the declaration or definition, or use SmartTags.
·         Debugger visualizers: Natvis debugger visualization files can be added to a Visual C++ project for easy management and source control integration. Natvis files that are added to a project will take evaluation precedence over visualizers outside the project.
·         Native memory diagnostics:
o    You can start a memory diagnostic session (Alt+F2) that monitors the live memory usage of your native application. This supports Windows Desktop.
o    You can capture heap snapshots of the running process in memory to see the types and instances for native allocations.
o    You can view the difference in memory allocations between two memory snapshots.
o    You can dive into the memory contents of a process snapshot by using the debugger for deeper analysis of the heap.


А теперь опишем то же самое вкратце, с картинками, которые я одолжил у лидера сообщества MVP С. Сомасегар (Somasegar).

C# и VB.NET с .Net Compiled Platform ("Roslyn")

Как и обещал нам Андерс Хейлсберг, папа языка C# (всегда было интересно, кого в данном случае можно считывать мамой), а также Мадс Торгерсен (Mads Torgersen), являющийся одним из разработчиков спецификации языка C#, это наконец-то случилось. В Visual Studio "14" компиляторы C# и VB.NET, а также поддержка IDE полностью построены на платформе Roslyn. Был переделан рефакторинг кода, с использованием возможностей, которые нам предлагает Roslyn.

Также небольшое нововведение, которое было анонсировано Microsoft немного ранее, – это то, что теперь даже .NET Framework будет поставляться отдельно через NuGet Package. Так мы плавно подошли к новой версии ASP.NET MVC 6, что доступно в данной студии под названием ASP.NET vNext.

ASP.NET vNext

Новость о выходе ASP.NET vNext в сети распространилась достаточно быстро вместе с анонсом наиболее интересных новшеств, предложенных в обновлении. ASP.NET MVC 6 получил новое имя и позиционируется как что-то действительно новое в среде web фреймворков Microsoft (MS). В данной версии добавлена поддержка запуска на платформе Mono. Так же новый стек оптимизирован под облачные платформы, а инструментарий разработки позволяет вносить изменения в код без перекомпиляции и перезапуска.

Изменения касаются также MVC, Web API, Web Pages, SignalR и EF. MVC, Web API и Web Pages теперь придерживаются единой програмной модели, например, используется один и тот механизм маршрутизации, а базовый контроллер один на всех, с одного адреса можно возвращать как вьюшки, так и ответы WebAPI. Оптимизация под облака по большей части заключается в том, что механизмы типа кеширования прозрачно переключают свою реализацию, в зависимости от того, где запущено приложение. Более детально об этом всем вы можете посмотреть в блоге Скотта Хансельмана Introducing ASP.NET vNext.

Также значительных изменений добавлено в язык С++, что не может не радовать разработчиков данного языка. Более детальнее об этом вы можете посмотреть в C++ blog, так как я давно уже не работал плотно с языком С++ и не смогу рассказать о нововведениях так, как это сделают те люди, которые в этом понимают намного лучше меня.

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

There are known issues when you install Visual Studio "14" CTP 14.0.21730.1 DP on the same computer as Visual Studio 2013. While we expect that an uninstallation of Visual Studio "14" and then a repair of Visual Studio 2013 should fix these issues, our safest recommendation is to install Visual Studio "14" in a VM, a VHD, a fresh computer, or another non-production test-only computer that does not have Visual Studio 2013 on it. All of these Visual Studio side-by-side issues are expected to be fixed soon.

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

Сам ISO образ занимает приблизительно 4 Гб, поэтому запаситесь терпением, потому что качает немного долго. Окно установки аналогично версиям Visual Studio 2012/2013, так то в этом плане компания Майкрософт не изобретала ничего нового.

При первом запуске отличия от Visual Studio 2013 я не заметил.

Поэтому решил посмотреть и создать тестовое консольное приложение на языке C#, чтобы посмотреть, как выглядят изменения, связанные с Roslyn. Во-первых, в глаза бросилось то, что немного изменился редактор (таби).

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

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

Вернемся к рефакторингу. Для того чтобы вызвать рефакторинг с Visual Studio "14" используется словосочетание клавиш "Alt+.". Сам рефакториг недоработан. Например, с тем кодом, который был приведен для примера, единственное, что можно было сделать, – это вынести в отдельный метод. О классах, свойствах даже речи быть не может. Надеюсь, со временем это поправят, но на данный момент продукт сыроват. В вебе у нас уже добавлены некоторые бланки для ASP.NET vNext. Список бланков, которые были доступны мне после установки, можно посмотреть ниже.

Немного жаль, что Microsoft убрала сразу WebPages и ASP.NET MVC, возможно, это один из рекламных ходов, которым хотят привлечь новых разработчиков, ну и, естественно, для заработка на продукте.

Итоги

В данной статье мы рассмотрели CTP релиз Visual Studio "14" и возможности, которые она нам дает. На данный момент студия выглядит несколько сыровато. Но у нее может быть блестящее будущее благодаря добавленным возможностям Roslyn. Думаю, что Microsoft дала хороший толчок разработчикам для создания инструмента для рефакторинга, который может покрывать часть функционала, которую сейчас предоставляет нам Resharper. Вполне вероятно, что в ближайшее время выйдет рад расширений для студии, которые позволят благодаря Roslyn перетащить в среду Visual Studio множество дополнительных возможностей. А пока, если вы не активный пользователь в жизненном цикле продуктов компании Microsoft, то можете подождать нормальный релиз; если же вы активный пользователь (имеется в виду, что вы пробуете предварительные выпуски продуктов компании Майкрософт, рассказываете о найденных ошибках и помогаете сделать их продукты еще лучше), то можете поработать с данной студией и помочь совместно с другими разработчиками сделать этот продукт лучше, сообщая о найденных проблемах в Microsoft например через тот же Stackoverflow


.NET Compiler Platform ("Roslyn") for the Rest of Us – краткий видеообзор новых возможностей Visual Studio "14".