none
.Net Profiler : Accessing Class properties from Object ID got from ObjectAllocated(..) call back function RRS feed

  • Question

  • Hi ,

    By setting an appropriate Event mask in icorprofiler interface i am getting the ObjectAllocated(..) call back function to my profiler. 

    From that function arguments i am able to get the object ID for the class name.

    What i am trying to do is as follows,

    1. I get the object ID for class SqlConnection.

    2. I am injecting a helper function's(managed function) call into Sqlconnection.Open() function.

    3. As a argument of the helper function i pass the Object ID which i got from ObjectAllocated(..) callback.

    Now inside the Managed helper function (when it is called) , can i access the property ConnectionString of SqlConnection Class using the ObjectID ?? 

    Is that possible ? If not please let me know some correct way to access the Connection String from SqlConnection and CommandText from SQLCommand Classes.

    Thanks,

    Selva

    Monday, February 9, 2015 6:48 AM

Answers

  • You don't need to access 'this' from the JITCompilationStarted callback, instead you insert il instructions into the method to access 'this'. 'this' is passed into instance methods as the first argument and can be pushed onto the evaluation stack using the ldarg.0 opcode.

    ldarg.0
    call void ProfilerHelperClass.OpenHelperMethod(SqlConnection)
    Note: you will probably want to make yourself familiar with ECMA-335 (particularly partitions II and III), it is a great reference when trying to understand il.
    • Marked as answer by Selva VS Monday, February 9, 2015 11:51 AM
    Monday, February 9, 2015 9:38 AM

All replies

  • It sounds like you are emitting the ObjectID from ObjectAllocated statically into the Open function, this is very dangerous:

    • ObjectIDs are not static, they can change (or even vanish) whenever the GC runs.
    • If multiple connection objects are created, which one gets injected?
    • What happens if the runtime decides to JIT SqlConnection.Open() before an instance is created?

    I don't see why you would need to use the ObjectID from ObjectAllocated, instead you should pass 'this' (argument 0) from the Open() method into your managed helper function. And yes, your managed helper method can safely access other managed methods including the property accessor methods.

    void Open()
    {
      ProfilerHelperClass.OpenHelperMethod(this);
      // regular Open() body.
    }
    
    static class ProfilerHelperClass
    {
      [SecuritySafeCritical]
      public static void OpenHelperMethod(SqlConnection connection)
      {
        calli <StaticFunctionPointerIntoProfiler> (connection, connection.ConnectionString);
        // Or whatever you are doing with the value in your managed helper method.
      }
    }

    Just in case you were thinking about it, don't try to call managed code from any callbacks, as that will introduce a very real risk of deadlock.

    Monday, February 9, 2015 8:26 AM
  • Hi Brian , I think this will really help to solve my needs. 

     ProfilerHelperClass.OpenHelperMethod(this);

    But as u quoted above, how can i get the "this" pointer inside the JITCompilationStarted(unmanaged profier api callback) from where i am changing my IL body of Open() function as 

    void Open()
    {
    //call to helper function 
    
    //original body of Open(..)
    
    }

    If there is a way to get the "this" pointer from the IL body of Open(..) function(i am not finding any proper document to knw how to get that), what will be the Opcode for it(to add as a argument for helper function call) and what will be type of it. The helper call injection is done as below from C++,

    // Add the argument for the function call

    pNewIns = ilobj->NewILInstr(); pNewIns->m_opcode = CEE_CALL; pNewIns->m_Arg32 = probeRef; pilr->InsertBefore(pInsertBeforeThisInstr, pNewInstr);

    //SetIlfunctionbody(..)

    I guess your next reply for this thread will solve my problem. 


    • Edited by Selva VS Monday, February 9, 2015 9:21 AM
    Monday, February 9, 2015 9:21 AM
  • You don't need to access 'this' from the JITCompilationStarted callback, instead you insert il instructions into the method to access 'this'. 'this' is passed into instance methods as the first argument and can be pushed onto the evaluation stack using the ldarg.0 opcode.

    ldarg.0
    call void ProfilerHelperClass.OpenHelperMethod(SqlConnection)
    Note: you will probably want to make yourself familiar with ECMA-335 (particularly partitions II and III), it is a great reference when trying to understand il.
    • Marked as answer by Selva VS Monday, February 9, 2015 11:51 AM
    Monday, February 9, 2015 9:38 AM
  • Thanks Brian. This worked just awesome.! 

    -Selva

    Monday, February 9, 2015 11:51 AM