Отладка вражеского кода

В моей карьере разработчика .net было несколько случаев, когда я хотел отладить чужой код. Код, к которому у меня нет исходников, только DLL. К счастью, Visual Studio позволяет дебажить код без исходинков.

Эта статья основана на вопросе на StackOverflow, где я пытался объяснить поведение Unity-контейнера.

Мое решение использует фичи Resharper.

Давайте начнем с небольшого куска кода:

var cage2 = container.Resolve<ICage>("cage2");

Я хочу отладить метод Resolve объекта container. Если у вас есть доступ к исходникам, то вы можете просто найти реализацию метода, поставить там точку остановки:

Go to implementation

Но стандартное поведение Visual Studio не дает найти реализацию метода:

No implementation

Шаг 1

Идем в настройки Resharper и меняем поведение доступа к внешним источника:

Navigate to sources

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

Source code

Выглядит так, будто бы все работает! Но…

No symbols

Уже второй раз мы видим сообщение о неких Symbol files. Эти файлы имею различные форматы, но мы будем говорить о PDB формате как о самом новом. По умолчанию, они генерируются для проектов, которые компилируются в Visual Studio, но в нашем случае у нас есть только DLL без PDB.

Без этих файлов Visual Studio не может соотнести исполняемые инструкции и исходный код.

Шаг 2

Давайте сгенерируем PDB-файлы по существующей сборке DLL.

  • Открываем Assmbly Explorer от Resharper
  • Добавляем Unity.dll

Assembly explorer

  • Генерируем PDB

Generate PDB

Теперь у нас есть PDB-файл для нашей DLL.

Шаг 3

Конфигурируем Visual Studio для отладки внешних источников.

Debug options

Две опции:

  • Отключаем Enable just my code что бы дебаггер мог взаимодействовать с внешними исходниками.
  • Включаем Suppress JIT optimization on module load (Managed only). Это важная опция, без нее вы получите непредсказуемые прыжки по исходному коду.

Это все! 3 простых шага, и мы можем отладить стороннюю DLL сборку без доступа к исходникам:

Debug external code

Точки остановки работают, Step into, Step over так же. Полный стек вызова.