[Windbg Script] Retrieving queries/stored procedures from .NET application

Ok, you are debugging a .NET application. You need to find out the queries and stored procedures being executed from the threads accessing the database, but you don’t know how. . . Good news! It’s not a problem anymore!

This script shows you all the queries or stored procedures associated with a SQLCommand or OracleCommand object. Moreover, you can click on it to get more details and the threads which use it.

If you compare this script with the last one, from my previous post, you’ll understand why I prefer the DML approach and why you need more work than the previous approach.

These are the screenshots:

 

 

Source code for GET_SQLCOMMAND.TXT:

$

$$

$$ =============================================================================

$$ It shows the SQL commands from a .NET application. It gives you detailed information

$$ and the threads using the query/stored procedure you selected.

$$ Useful for Oracle and SQL Server.

$$

$$ Compatibility: Win32.

$$

$$ Usage: Use $$>< to run the program.

$$

$$ Requirements: Public symbols.

$$

$$ If necessary change the filename below to include your path and filename.

$$ By default it uses the WinDbg path and the default file name is GET_SQLCOMMAND.TXT

$$

$$ Roberto Alexis Farah

$$ Blog: https://blogs.msdn.com/debuggingtoolbox/

$$

$$ All my scripts are provided "AS IS" with no warranties, and confer no rights.

$$ =============================================================================

$$

ad /q *

r @$t0 = 0

r @$t1 = 0

.printf /D "<b>\nClick on the queries/stored procedures below to get more details and to find out the threads using it.\n\n</b>"

.block

{

    .block

    {

        as ${/v:ScriptName} MYSCRIPTS\\GET_SQLCOMMAND.TXT

    }

    .block

    {

        as SQLCommand .block

        {

            !DumpObj poi(@$t0+0x10)

            !DumpObj @$t0

            !GCRoot @$t0

        }

    }

    .block

    {

        as OracleCommand .block

        {

            !DumpObj poi(@$t0+0x14)

            !DumpObj @$t0

            !GCRoot @$t0

        }

    }

}

.foreach(obj {!dumpheap -short -type System.Data.SqlClient.SqlCommand } )

{

    r @$t1 = 1

    .printf /D "<link cmd=\"r @$t0 = ${obj}; ${SQLCommand} ;ad ${/v:ScriptName}; $$><${ScriptName}\"><b>%mu</b></link>\n\n", poi(${obj}+0x10)+0xc

}

.foreach(obj {!dumpheap -short -type System.Data.OracleClient.OracleCommand } )

{

    r @$t1 = 1

    .printf /D "<link cmd=\"r @$t0 = ${obj}; ${OracleCommand} ;ad ${/v:ScriptName}; $$><${ScriptName}\"><b>%mu</b></link>\n\n", poi(${obj}+0x14)+0xc

}

.if(0 = @$t1)

{

    .printf /D "<b>\nNo SQL commands found.\n</b>"

}

Read me.

Comments

  • Anonymous
    April 05, 2007
    Thanks for another useful script. One question on script command: Is there a way to check if poi(@$t0+0x10)is 0 ? I tried to use .if (0 != poi(@$t0+0x10) but it doesn't like it.

  • Anonymous
    April 05, 2007
    The comment has been removed

  • Anonymous
    April 06, 2007
    Thanks for the help. I solved the issue. Can't wait for your next script.

  • Anonymous
    April 06, 2007
    BTW, one comment about the dumpheap -type. It is too bad it does NOT have an exact match option. In my case, I have System.Data.SqlClient.SqlCommand & System.Data.SqlClient.SqlCommand+CachedAsyncState.

  • Anonymous
    April 18, 2007
    The script was updated. Now it works with Oracle too. :)

  • Anonymous
    September 03, 2008
    &#160; http://blogs.msdn.com/debuggingtoolbox/archive/2007/04/04/windbg-script-retrieving-queries-stored-procedures-from-net-application.aspx

  • Anonymous
    November 06, 2008
    I have the following stack: 0399ee70 07bf7460 MyFunction(System.String)    PARAMETERS:        this = 0x01bf6da0        UIRL = 0x01bae768 is there any way to extract the pointer of this? ? poi(UIRL) THanks

  • Anonymous
    November 06, 2008
    Hi Rene, Yes, you can try it: dd this L1 or the approach I prefer: dt this dt is going to give you the type, members, etc. The address is the first information and it's the same address you get using dd this L1. Try the same approach with the UIRL variable. (just after re-reading your question I've noticed the this you mentioned is not actually the 'this' pointer :) ) Thanks

  • Anonymous
    February 01, 2009
    There’s another script that gives you all queries/stored procedures from SQL Server or Oracle that are