2014-01-13 2 views
12

Мы используем System.Reflection.Emit для генерации кода во время выполнения из исходного кода (да - как в компиляторе). Мы предоставляем правильную информацию о символах в ILGenerator с помощью MarkSequencePoint и т. Д. И включаем все флаги отладки на AssemblyBuilder. Сборка хранится в памяти в том же процессе, который скомпилировал ее и выполняется непосредственно.Неверный путь к файлу и номер строки в трассировке стека исключений из динамического кода

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

ОДНАКО - Когда исключения выбрасываются в сгенерированного кода, объекты System.Exception содержат стек следы, которые совершенно неправильно. Они указывают на другие (действительные, но неправильные) файлы и номера строк. Он получает имя класса и метода правильно, но указанный номер файла и строки не имеет никакого отношения к пути кода, из которого действительно произошло исключение.

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

Если я создаю объект System.Diagnostics.Debug из Exception, он содержит ту же самую неисправную информацию.

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

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

+5

Любой шанс вы могли бы разместить небольшую и полную программу, которую мы могли бы проверить?Например, вы можете указать hardcode «язык» двух строк или что-то в этом роде, вам не нужно публиковать полный компилятор. –

+1

Вы компилируете флаг 'optimize'? – Andrew

+0

Andrew: На компиляторе или на сборщике? Я попытался установить как можно больше «да, я хочу как можно больше отладочной информации», но, возможно, я не знаю их всех. – Duckers

ответ

1

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

  1. Как я генерирование CIL байткода Я строю отдельную базу данных, которая отображает имена методов (полный путь) и IL-смещение обратно в исходных имена файлов и номера строк.

  2. При обнаружении исключений проверяется трассировка стека и используется только GetMethod() и GetILOffset() информация из объектов фрейма стека. Эта информация из CLR бывает правильной, даже если GetFileName() и GetFileLineNumber() ошибочны.

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

  4. Кадры, о которых я не могу найти в базе данных, как правило, представляют собой стековые фреймы в предварительно скомпилированных .NET-модулях, для которых информация, полученная из CLR, действительно правильная. Для этих кадров я использую GetFileName() и GetFileLineNumber() непосредственно на стеке стека.

 Смежные вопросы

  • Нет связанных вопросов^_^