none
.Net Profiler - Fetching Value from Return statement RRS feed

  • Question

  • In my .NET instrumentation profiler code on the IL rewriting part i inject necessary helper function call opcodes. 

    As the arguments of the helper functions i pass the argument value of the function in which i am going to inject. 

    For example,

    If i am going to inject in a Function

    int OpenSession(String var1,Session var2) {

    // Inject entry point helper function .. .. ..

    // Inject exit point helper function return 1; }

    My entry point injection will be like 

    pNewInstr = pilr->NewILInstr();
    pNewInstr->m_opcode = CEE_LDARG_1;
    pNewInstr->m_Arg32 = nVersion;
    pilr->InsertBefore(pInsertProbeBeforeThisInstr, pNewInstr);
    
    pNewInstr = pilr->NewILInstr();
    pNewInstr->m_opcode = CEE_CALL;
    pNewInstr->m_Arg32 = mdSplProbeRef;
    pilr->InsertBefore(pInsertProbeBeforeThisInstr, pNewInstr);

    mdSplProbeRef will be the member reference of the helper function. So this passes the value of the first argument (string) of "OpenSession" to my helper function.

    Likewise, how can i get the Return value by this approach? Is there any way to get the return value?

    The ilrewrite code does iterate the opcodes of the application method body and search for CEE_RET and inject the opcodes before that to call my helper function during function exit. My guess is to make some changes in this part. But how to do that?

    Thursday, December 14, 2017 12:33 PM

Answers

  • The ret opcode will return the only value on the evaluation stack (unless the method returns void, in which case the evaluation stack will be empty and this question becomes moot), so you could duplicate the value.

    // begin inserted
    dup
    call void LogReturnValue(object)
    // end inserted
    ret
    • This assumes that the first argument of the helper method is the return value, if the return value is not the first argument of a static helper method, then you will need a local to temporarily hold the return value while you load other arguments.
    • If the return type is a value type, you will either need to either box the value or call a different overload specific to that value type.
    • No instructions can appear between a tail call and a return method, so you may need to strip the tailcall prefix instruction.


    • Edited by Brian Reichle Thursday, December 14, 2017 9:08 PM
    • Marked as answer by Selva VS Tuesday, December 19, 2017 4:12 AM
    Thursday, December 14, 2017 9:07 PM

All replies

  • The ret opcode will return the only value on the evaluation stack (unless the method returns void, in which case the evaluation stack will be empty and this question becomes moot), so you could duplicate the value.

    // begin inserted
    dup
    call void LogReturnValue(object)
    // end inserted
    ret
    • This assumes that the first argument of the helper method is the return value, if the return value is not the first argument of a static helper method, then you will need a local to temporarily hold the return value while you load other arguments.
    • If the return type is a value type, you will either need to either box the value or call a different overload specific to that value type.
    • No instructions can appear between a tail call and a return method, so you may need to strip the tailcall prefix instruction.


    • Edited by Brian Reichle Thursday, December 14, 2017 9:08 PM
    • Marked as answer by Selva VS Tuesday, December 19, 2017 4:12 AM
    Thursday, December 14, 2017 9:07 PM
  • Thanks for ur reply Brian,

    I am 90% done from your response. I am getting error as "CLR detected an Invalid code". 

    I am trying to get an integer return value from a function A1().

    int A1()
    {
    ..
    ..
    ..
    return 4;
    }

    The opcode of the function(without instrumentation) is 

    1f  a  19  b  2b  7  17  58  b  6  17  58  a  6  20  32  72  c  8  28  74  d  9  16  6a  6f  1a  0  2a  

    After injecting the helper function calls at front and end of function, the opcodes becomes,

    21  20  28  1f  a  19  b  2b  7  17  58  b  6  17  58  a  6  20  32  72  c  8  28  74  d  9  16  6a  6f  1a  0 25 28  2a  

    from the above opcodes ".. .. .. 1a  0  25  28  2a  " decoded as "4(integer value)  NOP  DUP  CALL  RET"

    This gives me the error as invalid code detected. What is the opcode i am missing inbetween DUP and CALL ? I tried CEE_STOBJ and LDOBJ, dint help. What should i use here to get that integer value.?

    Thanks



    • Edited by Selva VS Monday, December 18, 2017 11:40 AM
    Monday, December 18, 2017 10:57 AM
  • The first set of bytes seems to be truncated.

    1F 0A 19 0B  2B 07 17 58  0B 06 17 58  0A 06 20 32
    72 0C 08 28  74 0D 09 16  6A 6F 1A 00  2A ??
    
      ldc.i4.s        10
      ldc.i4.3
      stloc.1
      br.s            IL_000D // +7
    
      ldc.i4.1
      add
      stloc.1
      ldloc.0
      ldc.i4.1
      add
      stloc.0
    IL_000D  
      ldloc.0
      ldc.i4          135033394
      call            16090D74
      conv.i8
      callvirt        ??2A001

    The second set of bytes does not appear to have anything inserted before the return, instead its prepended with the ldc.i8 instruction. This instruction requires 8 bytes of argument, but only 2 were provided, causing it to consume 6 bytes of what would otherwise have been other instructions.

    21 20 28 1F  0A 19 0B 2B  07 17 58 0B  06 17 58 0A
    06 20 32 72  0C 08 28 74  0D 09 16 6A  6F 1A 00 25
    28 2A
    
      ldc.i8          516518784435955744
      ldc.i4.1
      add
      stloc.1
      ldloc.0
      ldc.i4.1
      add
      stloc.0
      ldloc.0
      ldc.i4          135033394
      call            16090D74
      conv.i8
      callvirt        2825001A
      ret
    
    

    Monday, December 18, 2017 9:13 PM
  • Sorry Brian, I dint notice there was a incorrect signature in injecting Entry function. I commented the Injection in entry of function. 

    Now it worked perfectly.. I was able to catch the integer value and tested with strings too.! 

    Thanks .!


    • Edited by Selva VS Tuesday, December 19, 2017 4:12 AM
    Tuesday, December 19, 2017 4:07 AM