microsoft / CLRInstrumentationEngine

The CLR Instrumentation Engine is a cooperation profiler that allows running multiple profiling extensions in the same process.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

The difference between BeforeInstrumentMethod & InstrumentMethod

robertpi opened this issue · comments

Hello all,

I'm unclear on the difference between BeforeInstrumentMethod, InstrumentMethod. It seems both are called if ShouldInstrumentMethod sets pbInstrument to true, the signatures are the same and both can be used for rewriting methods. So, it's unclear which I used use for my rewrites. I noticed the "Nagler" example / test uses both to preform different kinds of instrumentation, but it's unclear why it does this.

Also, is this the correct forum for design questions? I'll probably have some more questions.

Thanks,
Robert

The recommended way to instrument is to use InstrumentMethod. BeforeInstrumentMethod is used for whole method body replacement. In this scenario, one InstrumentationMethod will replace the entire method body (along with new IL offset maps) while other instrumentation methods will make incremental changes. See

// Called on instrumentation methods that return true to ShouldInstrumentMethod. This gives them the opportunity
// to replace the method body using the CreateBaseline api on the instruction graph. Only one instrumentation
// method can create the baseline. BeforeInstrumentMethod is called on instrumentation methods in priority order.
// Instrumentation methods should not perform any other instrumentation in this callback as a lower priority instrumentation
// method may replace the method body later
HRESULT BeforeInstrumentMethod([in] IMethodInfo* pMethodInfo, [in] BOOL isRejit);
and
// Removes all existing instructions from the graph and replaces them with a complete method body. The original instructions are preserved in a disjoint
// graph. Note that this changes the behavior of API's such as GetInstructionAtOriginalOffset; these will now retrieve the baseline instruction instead.
// This can only be called during the BeforeInstrumentMethod phase of the instrumentation and can only be called once
HRESULT CreateBaseline(
[in] LPCBYTE pCodeBase,
[in] LPCBYTE pEndOfCode,
[in] DWORD originalToBaselineCorIlMapSize,
[in, size_is(originalToBaselineCorIlMapSize)] COR_IL_MAP originalToBaselineCorIlMap[],
[in] DWORD baselineSequencePointSize,
[in, size_is(baselineSequencePointSize)] DWORD baselineSequencePointList[]
);

Please feel free to post more questions in this repo.

Thanks, that's really helpful!