Answered by:
How to inject code at the end of a function?

Question
-
Hi,I am trying to inject code at the end of a function just after the CEE_CALL is called in the IL code. I use the opencover's instruction class for instrumenting.This is what i do.
Instruction* lastIns = NULL; for(InstructionListReverseIter it = instMethod.m_instructions.rbegin(); it != instMethod.m_instructions.rend(); ++it) { if ((*it)->m_operation == CEE_CALL) { lastIns = (*it); } } long lastOffset = lastIns->m_offset; long finishFunctionOffset = lastOffset; InstructionList lastInstructions; lastInstructions.push_back(new Instruction(CEE_NOP)); lastInstructions.push_back(new Instruction(CEE_LDLOC_1)); lastInstructions.push_back(new Instruction(CEE_CALL, finishMemberRef)); instMethod.InsertSequenceInstructionsAtOffset(finishFunctionOffset, lastInstructions);
But it does not correctly inject code the way i want it.. It always injects before the last CEE_CALL. But it should actually be after the last CEE_CALL.Any help on how to do it the correct way would be nice.
..JPJ..Thursday, August 25, 2011 8:55 AM
Answers
-
That method inserts the code at the location (offset) supplied, shuffling any instructions further down and appears to be behaving correctly.
What you need to do is make sure that lastIns (from where you get the offset) is pointing to the instruction after the instruction you are looking for.
As you are using a reverse iterator I would try the following
Instruction* lastIns = NULL; for(InstructionListReverseIter it = instMethod.m_instructions.rbegin(); it != instMethod.m_instructions.rend(); ++it) { if ((*it)->m_operation == CEE_CALL) { break } lastIns = (*it); }
...Friday, August 26, 2011 1:07 AM
All replies
-
That method inserts the code at the location (offset) supplied, shuffling any instructions further down and appears to be behaving correctly.
What you need to do is make sure that lastIns (from where you get the offset) is pointing to the instruction after the instruction you are looking for.
As you are using a reverse iterator I would try the following
Instruction* lastIns = NULL; for(InstructionListReverseIter it = instMethod.m_instructions.rbegin(); it != instMethod.m_instructions.rend(); ++it) { if ((*it)->m_operation == CEE_CALL) { break } lastIns = (*it); }
...Friday, August 26, 2011 1:07 AM -
Hi,
Has your issue been resolved? Would you mind letting us know the result of the suggestions?
Now I will mark an answer, you can mark others that you think to be so useful to your issue.
If you still have any questions about this issue, please feel free to let me know. We will continue to work with you on this issue.
Have a nice day!
Paul Zhou [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Friday, September 2, 2011 6:53 AM -
Sorry for the late reply.. I had to take care of some personal issues(sickness in the family).
Shaun's alteration of the code worked so as to get the last call and insert code before it. Thanks Shaun.
Only thing is, if the function is returned before the last call is made then it won't work. So I have to do more checking w.r.t to that. Also when exception is handled it has to be handled differently. These are some the things i have to enhance.
I face a different problem now...
Say I have a function outerfunction(...) which I capture in jitCompilationStarted and inject code at the begin and end.
I have another function innerfunction(...).. which is inside outerfunction(...).
i.e. something like this
Outerfunction(...)
{
//InjectCodeAtStart()
InnerFunction(...)
//InjectCodeAtEnd()
}
InnerFunction(...)
{
//InjectCodeAtStart()
InnerInnerFunction(...)
//InjectCodeAtEnd()
}
I inject code at the beginning and end of OuterFunction(..). In the InnerFunction(..) i inject code the same InjectFunctions as of OuterFunction(..).
What happens is, Only the InnerFunction's InjectCodeAtEnd() is called... and the OuterFunction's InjectCodeAtEnd() is NOT called.
I Inject InjectCodeAtEnd() using the logic which I described i the above comment by Shaun. So both begin and end inject functions are done at the JitcompliactionStarted itself when the OuterFunction(..) is being jitcomplied.
I cannot understand why the OuterFunction's InjectCodeAtEnd() is not called. I use Opencover's Method class for code injection.
..JPJ..- Edited by Jasper paul Friday, September 9, 2011 6:34 AM
Friday, September 9, 2011 6:26 AM -
I assume you are inserting your code before the RET operation.
Do you have actual code or does it get repeated on sample you show above - I instrument at every sequence point and I have not seen this behaviour.
What profiler flags are you using?
If you run in debug and have debugview running you can see the before and after instrumentation IL that you can use to check your instrumentation.
Friday, September 9, 2011 8:18 AM