Мы используем System.Reflection.Emit для генерации кода во время выполнения из исходного кода (да, как в компиляторе). Мы предоставляем правильную информацию о символах в ILGenerator с помощью MarkSequencePoint и т. д. и включаем все флаги отладки в AssemblyBuilder. Сборка хранится в памяти в том же процессе, который ее компилировал, и выполняется напрямую.
При использовании отладчика Visual Studio для пошагового просмотра исходного кода для динамически сгенерированного кода он на самом деле работает отлично, и Visual Studio, кажется, полностью понимает, откуда берется код с точки зрения файлов и номеров строк.
ОДНАКО. Когда исключения создаются сгенерированным кодом, объекты System.Exception содержат полностью неверные трассировки стека. Они указывают на другие (действительные, но неправильные) файлы и номера строк. Он получает правильное имя класса и метода, но указанный файл и номер строки не имеют ничего общего с путем кода, из которого на самом деле возникло исключение.
Указанные файлы настолько не связаны, что кажется, что они не могут быть связаны с встраиванием или оптимизацией. Единственная закономерность, которую я могу заметить, заключается в том, что она кажется смещенной некоторыми файлами (в воображаемом отсортированном по алфавиту списке исходных файлов, из которых была создана сборка). Однако эта закономерность не соответствует 100%, и кажется иррациональным, что это связано с источником проблемы.
Если я создаю объект System.Diagnostics.Debug из исключения, он содержит ту же ошибочную информацию.
Я предполагаю, что среда выполнения .NET использует те же метаданные для построения трассировки стека исключений, которые отладчик использует для пошагового выполнения кода, и в этом случае такое поведение действительно странно.
Я пытаюсь выяснить, является ли это известной ошибкой в .NET при работе с динамическими сборками в памяти, или кто-нибудь сталкивался с подобными проблемами в других областях.
optimize
? - person poy   schedule 13.01.2014try { // Do something } catch (Exception ex) { throw ex; }
. Если да, используйтеthrow new Exception("My message.", ex);
для переноса или просто используйте вместо этогоthrow;
для операторов throw. - person JamieSee   schedule 03.03.2014