Как мне вставить исходный код в pdb и использовать его в отладчике? - PullRequest
15 голосов
/ 05 сентября 2011

ПРИМЕЧАНИЕ : моя цель - C # нацелить CLR с помощью регулярного MSIL на случай, если что-то будет работать, но не в более общем случае.

Некоторые примеры поддержки отладки исходного кода

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

http://lowleveldesign.wordpress.com/2011/08/26/sourcepack-released/

Для проектов с открытым исходным кодом, использование http://www.symbolsource.org/ в качестве способа упрощения получения символов и исходного текста для пользователей вашего проекта.

Задача

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

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

Цель

Кажется, что может быть проще (для определенных сборок, таких как отладка и / или только для внутреннего использования) просто поместить фактический источник в pdb (фактически просто разыменовать указатель, записанный в данный момент в PDB). Кажется, что тогда вы можете пропустить всю часть исходного сервера (по крайней мере, теоретически) и устранить несколько зависимостей от истории времени отладки. Хранить исходный код как сжатый или нет в значительной степени ортогонально, но первый проход, вероятно, не сделает этого, чтобы упростить его реализацию для существующих отладчиков.

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

Чем это отличается от поддержки «исходного сервера»?

(это было добавлено путем редактирования после комментария Тиграна, спрашивающего, какие выгоды будут)

Базовый сценарий, с которым следует сравнивать это сценарий «нормальной» отладки с использованием «нормального» экземпляра исходного сервера сегодня. В этом сценарии (AFAIK) механизм отладки получает указатель от PDB (через альтернативный поток), а затем использует зарегистрированные серверы источника, чтобы попытаться получить источник через этот указатель. Поскольку данная сборка обычно собирается включать несколько исходных файлов, существует либо один указатель, который включает в себя базовое местоположение, либо в PDB имеется несколько указателей (или что-то еще), но это должно быть ортогонально этому обсуждению.

Для проекта, в котором желательно сохранить источник скрытым / недоступным (большинство продуктов Microsoft, например, включая Windows, Office, Visual Studio и т. Д.), Тогда наличие PDB, содержащего указатели, FAR превосходит включение фактического источника (даже если бы он был зашифрован). Такие указатели не имеют смысла без необходимого доступа к сети и разрешений, поэтому такой подход означает, что вы можете отправить PDB любому человеку на планете, не беспокоясь о том, что он сможет получить доступ к вашему источнику (в худшем случае они увидят, как ваш источник Дерево устроено, я бы подумал).

Тем не менее, существует 2 больших набора проектов (и в частности, сборок), в которых не существует этого преимущества «скрыть источник».

Первая - это сборки, которые используются только людьми, которые в любом случае имеют доступ к источнику. Сборки, выполненные на вашей собственной машине, которые никогда не покинут эту машину, являются отличным примером, так как злоумышленнику в любом случае потребуется прочитать файлы из вашей файловой системы, чтобы получить источник, поэтому чтение из одного файла (.cs) против другого (. pdb) является относительно небольшой разницей с точки зрения сложности атаки / вектора. Аналогично, сборки, которые выполняются и передаются в тестовую / промежуточную среду, где люди, имеющие доступ к pdb на машине, равны или являются подмножеством людей, которые могут получить доступ к источнику «нормально».

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

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

Преимущества

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

  • Нет необходимости заниматься настройкой поддержки исходного сервера. Это просто работает (IJW), по крайней мере, когда / если отладчики знали, что искать в pdb.
    • В то же время, вы все еще можете сделать «фиксированный» исходный сервер, который был просто фиктивным, который извлекал источник и возвращал его вызывающей стороне. Такая конфигурация может быть одинаковой для всех (например, с использованием localhost), тем не менее, устраняя текущую необходимость фактической настройки исходного сервера
  • Нет необходимости, чтобы сборка включала «индексацию источника»
    • Так как сборка читает исходные файлы и в любом случае записывает файлы pdb, мы просто модифицируем то, что написано в pdb, и не принимаем перфорацию во время сборки для выполнения сетевых вызовов или чтения данных, которых у нас еще нет в память.
    • До тех пор, пока не будет встроенной поддержки сборки для добавления исходного кода, это может быть простой шаг после сборки, который, вероятно, будет реализован сначала с помощью небольшого форка проекта Sourcepack, так как уже выполняет работу по чтению / изменению файлов PDB:)
  • Нет зависимости от команды / проекта, имеющего систему контроля версий
  • Нет зависимости от конкретной версии каждого файла, который проверяется в системе контроля версий (большинство людей не регистрируются для каждой сборки, которую они делают в своей IDE)
  • Нет необходимости иметь доступ к конкретной системе контроля версий, в которой находится файл
    • в случае DVCS, например, указатель PDB может относиться к некоторому «случайному» экземпляру git или mercurial или какому-либо другому, не обязательно тому, к которому у вас есть доступ
    • инструментальные средства исходного сервера для отслеживания этой версии обратно на экземпляры сервера исходного контроля, к которым у вас есть доступ (если он там даже существует), еще не существует AFAIK)
  • Нет проблем, если проект умирает (удаляется) или перемещается
    • например, если проект переходит от одного к другому: самодостаточный, sourceforge, github, bitbucket, codeplex, code.google.com и т. Д.
  • Нет проблем, если машина, на которой вы отлаживаете, не имеет (или недостаточно) доступа к сети
    • Например, если вы выполняете «сетевой KVM» в поле для отладки проблемы, но у него либо нет сети, либо он может общаться только с отключенными сетями, так что он не может получить доступ к вашему серверу управления источниками).
  • в крайнем случае, возможность восстановить часть исходного кода проекта из сборки. ;)

ПРИМЕЧАНИЕ: другой подход будет включать в себя источник в фактической сборке (например, в качестве ресурса), но лучшим выбором будет pdb (легко доставить сборку без pdb, нет нормального перфорационного удара во время выполнения, если источник в pdb, так как сборка имеет тот же код и тот же размер и т. д.)

Как реализовать?

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

Я думаю, что-то вроде:

  1. Добавьте шаг после сборки, который будет делать что-то похожее на Sourcepack, но вместо изменения указателя он заменит его фактическим источником.
    • В зависимости от того, что должен делать исходный сервер, ему может понадобиться префикс, или фактический источник будет находиться в другом альтернативном потоке данных, а «указатель» будет обновлен до чего-то «source-in-pdb: ads-» foo.cs или что угодно. префикс или указатель может также включать способ хранения исходного файла (без сжатия, gzip, bzip2 и т. д. вместе с кодировкой файла)
  2. Реализация «исходного сервера», который фактически извлекает исходный код из рассматриваемой pdb и возвращает его обратно.
    • Не знаю, достаточно ли информации об API-интерфейсе исходного сервера для определения местоположения PDB, не говоря уже о том, будет ли у него разрешение на фактическое чтение содержимого.

Проверка работоспособности?

С вышеперечисленной болтовней в стороне, вопросы на самом деле:

  • Такое уже существует? (и если да, укажите указатели!)
  • Предполагая, что он еще не существует, имеет ли смысл приведенное выше в качестве реализации первого прохода? Есть ли подводные камни или сложности, о которых говорилось выше?
  • Если предположить "нет" и "да" для вышеизложенного, существует ли существующий проект, который имеет смысл с точки зрения принятия этого (он близок или находится в их существующей области)?

1 Ответ

4 голосов
/ 08 сентября 2011

Я прочитал это и хотел обобщить мое понимание для ясности

Сегодня отладчик использует PDB для получения пути к файлу к файлу и контрольной суммы, которая была скомпилирована для создания заданного раздела исполняемого файла. Затем отладчик пытается загрузить файл, используя как локальный диск, так и доступный сервер символов. По этому предложению мы бы пропустили посредника, просто внедрив сам файл в PDB. Эврика, больше не нужно искать источник!

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

Первое - это фактическое встраивание исходного кода в PDB. Это очень выполнимо. PDB - это, по сути, легкая файловая база данных. Существует структура того, что он кодирует, но AFAIK вы можете поместить все, что вы хотите в определенные слоты (например, значения / типы локальных переменных). Для некоторых слотов могут быть ограничения по размеру, но я уверен, что вы могли бы изобрести схему кодирования, чтобы разбить большие файлы на куски.

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

  1. Путь к файлу на диске
  2. Контрольная сумма указанного файла (используется для устранения неоднозначности файлов с одинаковым именем)

Я вполне уверен, что это единственная информация, которую он передает на сервер символов. Это делает невозможным внедрение сервера символов, потому что у него не будет доступа к PDB (если, конечно, я прав).

Я копался в надежде, что есть VS COM-компонент, который вы можете переопределить, что позволит вам перехватить загрузку файла для заданного пути, но я не смог его найти.

Один из подходов, который я думаю, был бы возможен, хотя был бы

  1. Вставить источник в PDB
  2. Иметь инструмент, который может как извлечь источник в известное место, так и переписать PDB, чтобы указать на это место.

Это не совсем то, что вы хотите.

...