Partager via


CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT

Le CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT a été introduit dans .NET Framework version 2.0. .NET Framework 4 retourne ce HRESULT dans deux scénarios :

  • Quand un profileur de détournement réinitialise de force le contexte de registre d’un thread à un moment arbitraire afin que le thread tente d’accéder aux structures qui sont dans un état incohérent.

  • Quand un profileur tente d’appeler une méthode informationnelle qui déclenche le garbage collection à partir d’une méthode de rappel qui interdit le garbage collection.

Ces deux scénarios sont décrits dans les sections suivantes.

Profileurs de détournement

(Ce scénario correspond principalement à un problème lié aux profileurs de détournement, même s’il existe des cas où des profileurs d’un autre type peuvent voir ce HRESULT.)

Dans ce scénario, un profileur de détournement réinitialise de force le contexte de registre d’un thread à un moment arbitraire afin que le thread puisse entrer le code du profileur ou entrer à nouveau le Common Language Runtime (CLR) par le biais d’une méthode ICorProfilerInfo.

De nombreux ID que l’API de profilage fournit pointent vers des structures de données dans le CLR. De nombreux appels à ICorProfilerInfo se contentent de lire les informations de ces structures de données et de les repasser. En revanche, le CLR peut apporter des modifications dans ces structures au moment de son exécution et il peut utiliser des verrous pour cela. Supposons que le CLR possédait déjà (ou tentait d’acquérir) un verrou au moment où le profileur a détourné le thread. Si le thread entre à nouveau le CLR et tente de prendre d’autres verrous ou d’inspecter des structures qui étaient en cours de modification, ces structures risquent d’être dans un état incohérent. Des interblocages et des violations d’accès peuvent facilement se produire dans de telles situations.

En règle générale, quand un profileur qui n’est pas un profileur de détournement exécute du code à l’intérieur d’une méthode ICorProfilerCallback et appelle une méthode ICorProfilerInfo avec des paramètres valides, il a peu de chances d’entraîner un interblocage ou de recevoir une violation d’accès. Par exemple, le code du profileur qui s’exécute à l’intérieur de la méthode ICorProfilerCallback::ClassLoadFinished peut demander des informations sur la classe en appelant la méthode ICorProfilerInfo2::GetClassIDInfo2. Le code peut recevoir un HRESULT CORPROF_E_DATAINCOMPLETE pour indiquer que ces informations ne sont pas disponibles. Néanmoins, il ne va pas entraîner d’interblocage ni recevoir une violation d’accès. Ces appels dans ICorProfilerInfo sont considérés comme synchrones, car ils sont effectués à partir d’une méthode ICorProfilerCallback.

Toutefois, un thread managé qui exécute du code qui n’est pas dans une méthode ICorProfilerCallback est considéré comme un thread qui effectue un appel asynchrone. Dans .NET Framework version 1, il était difficile de déterminer ce qui pouvait se produire dans un appel asynchrone. L’appel pouvait entraîner un interblocage, un incident ou donner une réponse non valide. .NET Framework version 2.0 a introduit des vérifications simples pour vous aider à éviter ce problème. Dans .NET Framework 2.0, si vous appelez une fonction ICorProfilerInfo non sécurisée de façon asynchrone, elle échoue avec un HRESULT CORPROF_E_UNSUPPORTED_CALL_SEQUENCE.

En règle générale, les appels asynchrones ne sont pas sécurisés. Néanmoins, les méthodes suivantes sont sécurisées et prennent particulièrement en charge les appels asynchrones :

Pour plus d’informations, consultez l’entrée Pourquoi nous avons CORPROF_E_UNSUPPORTED_CALL_SEQUENCE dans le blog de l’API de profilage CLR.

Déclenchement de garbage collections

Ce scénario implique un profileur qui s’exécute à l’intérieur d’une méthode de rappel (par exemple, l’une des méthodes ICorProfilerCallback) qui interdit tout garbage collection. Si le profileur tente d’appeler une méthode informationnelle (par exemple, une méthode sur l’interface ICorProfilerInfo) susceptible de déclencher un garbage collection, la méthode informationnelle échoue avec un HRESULT CORPROF_E_UNSUPPORTED_CALL_SEQUENCE.

Le tableau suivant présente les méthodes de rappel qui interdisent les garbage collections, ainsi que les méthodes informationnelles susceptibles de déclencher des garbage collections. Si le profileur s’exécute à l’intérieur de l’une des méthodes de rappel listées et appelle l’une des méthodes informationnelles listées, cette méthode informationnelle échoue avec un HRESULT CORPROF_E_UNSUPPORTED_CALL_SEQUENCE.

Méthodes de rappel qui interdisent les garbage collections Méthodes informationnelles qui déclenchent des garbage collections
ThreadAssignedToOSThread

ExceptionUnwindFunctionEnter

ExceptionUnwindFunctionLeave

ExceptionUnwindFinallyEnter

ExceptionUnwindFinallyLeave

ExceptionCatcherEnter

RuntimeSuspendStarted

RuntimeSuspendFinished

RuntimeSuspendAborted

RuntimeThreadSuspended

RuntimeThreadResumed

MovedReferences

ObjectReferences

ObjectsAllocatedByClass

RootReferences2

HandleCreated

HandleDestroyed

GarbageCollectionStarted

GarbageCollectionFinished
GetILFunctionBodyAllocator

SetILFunctionBody

SetILInstrumentedCodeMap

ForceGC

GetClassFromToken

GetClassFromTokenAndTypeArgs

GetFunctionFromTokenAndTypeArgs

GetAppDomainInfo

EnumModules

RequestProfilerDetach

GetAppDomainsContainingModule

Voir aussi