Чем запуск приложения C # внутри профилировщика кода отличается от запуска одного внешнего профилировщика кода?

Я пытаюсь понять, как профилировщик кода (в данном случае Drone Profiler) запускает. NET иначе, чем просто запустить его напрямую. Причина, по которой мне нужно это знать, заключается в том, что у меня очень странная проблема / повреждение с установкой .NET на моем компьютере разработчика, которая проявляется вне профилировщика, но очень странно не внутри, и если я могу понять, почему я, вероятно, могу исправить проблему с моим компьютером.

Проблема ТОЛЬКО, похоже, влияет на вызовы методов System.Net.NetworkInformation (и только в .NET 3.5–2.0, если я построю что-то против 4, все в порядке). Я создал небольшое тестовое приложение, которое делает только одно - вызывает System.Net.NetworkInformation.IsNetworkAvailable (). Вне профилировщика я получаю «Неустранимая ошибка механизма выполнения» в System.dll, и это вся информация, которую он дает. Насколько я понимаю, эта ошибка обычно возникает из-за вызовов собственных методов, которые предположительно возникают, когда System.dll позволяет некоторой собственной DLL выполнять логику IsNetworkAvailable ().

  • Я попытался выяснить внутреннюю и внешнюю разницу профилировщика с помощью Process Monitor , записывая события из обеих ситуаций и сравнивая их. Оба журнала были одинаковыми до тех пор, пока не были вызваны iphlpapi.dll и winnsi.dll, и непосредственно перед тем, как запускаемый профилировщиком код под названием dnsapi.dll и код, не являющийся профилировщиком, начали загружать материалы, связанные с отчетами о сбоях. В тот момент, когда казалось, что что-то пошло не так, код запуска профилировщика создал 4-6 новых потоков, а код непрофилировщика (сбой) создал только 1 или 2. Я не знаю, что это означает, во всяком случае.

Возможно ненужный фон

Моя Windows 7 включала установку .NET (от 3.5 до 2.0), работала нормально, пока мой жесткий диск не испортился, и checkdisk не начал находить плохие кластеры. Я скопировал диск на новый, и все работает нормально, кроме одной проблемы с .NET.

Мне нужно решить эту проблему, переустановив Windows или вернувшись к резервному копированию образов.

Вот некоторые вещи, которые я изучил:

  • Я сравнил файлы / каталоги, которые казались наиболее важными (файлы .NET под Windows и Program Files) до и после проблем с диском, и не обнаружил никаких изменений там, где я не ожидал (отсутствие очевидного повреждения файла).
  • Я различал программное обеспечение и кусты системного реестра до и после проблем с диском и не обнаружил никаких изменений, которые казались бы важными.
  • Я создал новую учетную запись пользователя и очистил все переменные среды на случай, если среда была связана. Без изменений.
  • Я сделал "sfc / scannow" и не обнаружил проблем с целостностью.
  • Я попробовал "ngen update" восстановить предварительно скомпилированный код на случай, если я пропустил что-то, что могло быть повреждено, и ничего не изменилось.
  • Я удалил свой антивирусный сканер, чтобы посмотреть, не мешает ли он, без разницы.
  • Я попытался запустить тестовый код в безопасном режиме, та же проблема сбоя.

Я предполагаю, что мне нужно восстановить мою установку .NET, но поскольку Windows 7 включала .NET 3.5–2.0, вы не можете просто повторно запустить установщик .NET, чтобы повторить его. У меня нет доступа к дискам Windows, чтобы попытаться переустановить Windows поверх себя (на компьютере есть раздел восстановления, но он непригоден для использования); Кроме того, в диске используется решение для шифрования всего диска, и повторная установка будет затруднена.

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

Учитывая все это ... есть ли у кого-нибудь полезный совет? Мне нужна .NET 3.5–2.0, поскольку я разработчик, и мне нужно построить и протестировать ее.

Спасибо!

Quinxy


person Quinxy von Besiex    schedule 23.08.2012    source источник


Ответы (2)


Короткий ответ: мой файл System.ni.dll был поврежден, я заменил его, и все в порядке.

Длинный ответ может помочь кому-то еще в своем подходе к решению ...

Моя проблема связана с тем, что .Net был поврежден таким образом, что приложения не запускались, кроме как через профилировщик. Я загрузил исходный код для профилировщика с открытым исходным кодом SlimTune, построил его локально и установил точку останова прямо перед вызовом Process.Start (). Затем я сравнил все параметры, необходимые для успешного запуска приложения с помощью профилировщика, и вручную. Единственное существенное отличие, которое я обнаружил, - это добавление параметров профиля .NET к переменным среды:

  • cor_enable_profiling = 1
  • cor_profiler = {38A7EA35-B221-425a-AD07-D058C581611D}

Затем я попытался установить их в среде своего собственного пользователя, и вуаля! Теперь любое приложение, которое я запускал вручную, будет работать. (На самом деле я пытался сделать то же самое несколькими часами ранее, но я использовал GUID, который был включен в пример и который не указывал на настоящий профилировщик, и, очевидно, .NET знал, что я дал ему поддельный GUID и не запустить в режиме профилирования.)

Теперь я вернулся и начал читать о том, как исполняется PE-файл в среде CLR, в надежде выяснить, почему важно, чтобы мое приложение запускалось с включенным профилированием. Я многому научился, но ничего не подходящего.

Однако я вспомнил, что должен перепроверить журнал chkdsk, в котором перечислены файлы, которые были повреждены в результате сбоя диска. После сбоя я превратил все перечисленные идентификаторы файлов в пути / имена файлов, и я заменил все 100+ файлов, которые мог из резервной копии, но, конечно же, когда я вернулся и посмотрел, я обнаружил примечание, что, хотя я заменил 4 или 5 файлов, связанных с .NET, был один такой файл, который я не смог заменить, потому что он «использовался». Этот файл? System.ni.dll !!! Теперь я смог заменить этот файл из резервной копии, и вуаля моя установка .NET вернулась в нормальное состояние, приложения работают независимо от того, профилированы они или нет.

Расстраивает то, что, когда этот инцидент впервые произошел, я полностью ожидал, что проблема будет связана с поврежденным файлом, и в частности с файлом с именем System.dll, в котором размещены методы, которые потерпели неудачу. Итак, я различил и переопределил все файлы с именем System.dll. Но в то время я не понимал, что System.ni.dll является собственной скомпилированной версией System.dll (или чего-то подобного). И поскольку я изменил и переопределил каталоги, связанные с .NET, и не заметил этого (не знаю, как я это пропустил), я отказался от этого подхода.

В любом случае ... Короче говоря, причиной моих проблем был поврежденный System.ni.dll, содержимое одного или нескольких кластеров в нем было заменено на 0x0, и это проявилось как странная проблема, которую я заметил.

person Quinxy von Besiex    schedule 25.08.2012

Это похоже на проблему с синхронизацией, которую профилировщик «исправил», сделав ее немного медленнее.

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

Из вашего описания я попытаюсь догадаться, как это можно исправить:

Попробуйте найти в источнике, откуда запускаются новые потоки. Затем после их создания добавьте туда строку System.Threading.Thread.Sleep(500);, чтобы приостановить основной поток и дать новым потокам время для запуска.

Без исходного кода и нескольких следов сбоев в стеке это довольно много догадок.

person Louis Somers    schedule 23.08.2012
comment
Я искренне ценю эту мысль и комментарий. Это очень интересная гипотеза. Я считаю, что часть того, что вы говорите, неприменима в этом случае, учитывая, что моя демонстрационная программа, которая демонстрирует эту проблему, представляет собой буквально одну строку (с формой проекта Windows Forms по умолчанию), вызывающую функцию Ping (), и все работало отлично до проблема с диском у меня была. Но та часть, которую вы упомянули об инструментах, может быть очень важной, в частности, потому что, когда я сравнивал реестр между рабочим и нерабочим состояниями, я заметил некоторые изменения, связанные с мониторами производительности и т. Д. - person Quinxy von Besiex; 24.08.2012
comment
Поэтому я думаю, что мне следует более внимательно изучить изменения реестра, связанные со счетчиками производительности, и посмотреть, влияют ли они на какие-либо изменения. - person Quinxy von Besiex; 24.08.2012