clr profiler api: безопасен ли ICorProfilerCallback ::ExceptionThrown GC

#.net #clr #coreclr #clr-profiling-api

#.net #среда clr #coreclr #clr-profiling-api

Вопрос:

Мне было интересно, в профилировщике .net framework, является ExceptionThrown ( https://learn.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/icorprofilercallback-exceptionthrown-method ) гарантированно не перекрывается с GC?

Просматривая документацию, это выглядит так: «Если профилировщик блокируется здесь и выполняется попытка сборки мусора, среда выполнения будет блокироваться до тех пор, пока этот обратный вызов не вернется»

Тем не менее, я запустил свой профилировщик, прикрепленный к paint.net (https://www.getpaint.net / — версия 4.1.6) и увидел конкретный случай, когда я получил GC во время ExceptionThrown. (но это было очень редко — происходило только при запуске и только один раз примерно за каждые 20 запусков) — это привело к изменению данных прямо при чтении, поскольку gc переместил их.

По крайней мере, в версии .net core —https://github.com/dotnet/coreclr/blob/master/Documentation/botr/profiling.md в нем явно указано, какие обратные вызовы безопасны для выноски GC. ExceptionThrown не является одним из них. ExceptionUnwindFunctionEnter — это, например. Однако вернемся к .NET framework — https://learn.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/icorprofilercallback-exceptionunwindfunctionenter-method — в документации .NET framework замечание о GC идентично замечанию ExceptionThrown.

Я это знаю.СЕТЕВОЕ ядро != .NET framework. Однако я чувствую, что код их профилировщиков довольно похож и имеет те же гарантии. Я не смог найти похожий ресурс о безопасности GC.Обратные вызовы NET framework.

Итак, после всего этого вступления, мой вопрос таков:

  1. Должен .Обратный вызов ExceptionThrown для профилировщика NET framework clr безопасен для GC. И если да, то как может быть, что я видел, как вызов GC запускается и заканчивается во время ExceptionThrown (возможная ошибка в среде clr или ожидаемое поведение)?

  2. Если это не ошибка, могу ли я, по крайней мере, на 100% полагаться на обратный вызов UnwindExceptionFunctionEnter профилировщика .NET framework clr, быть безопасным для GC на основе аналогичной документации по core-clr?

Спасибо

Ответ №1:

Да, GC разрешено запускать. Интерфейс .NETCore принципиально не отличается от .Сетевой интерфейс, документация github точна.

Это довольно легко увидеть, если посмотреть на исходный код CLR. Хотя тестировщик, по-видимому, работал на пике Баллмера, утверждения его контракта должны быть точными. Скопируйте / вставьте соответствующий код:

     // Preemptive mode would be bad, dude.  There's an objectId in the param list!
    MODE_COOPERATIVE;
  

MODE_COOPERATIVE Макрос указывает, что GC включен. MODE_PREEMPTIVE Макрос сообщает, что сбор данных отложен.

Комментарии:

1. Я думаю, это нуждается в дальнейшем объяснении: пока поток находится в режиме MODE_PREEMPTIVE, во время выполнения может произойти все, что угодно. Сбор данных не задерживается. Функция вытеснения в основном сообщает среде CLR, что текущий поток никак не обрабатывает управляемые объекты, поэтому этот поток никогда не заблокирует GC. Пока поток находится в режиме СОТРУДНИЧЕСТВА, GC может выполняться только тогда, когда этот поток соглашается на это (или запускает его). Более подробную информацию можно найти на github.com/dotnet/coreclr/blob/master/Documentation /…

2. В дополнение к вышесказанному, GC действительно может произойти — но вам гарантируется, что идентификатор объекта, который вы получаете при обратном вызове, не будет перемещен / удален