[Windbg Script] Connections from Pool


If you are like me, you may forget the classes and namespaces you need to find out some specific information. Or maybe you forget the field names you need to look for.


It happens to me when I need to take a peek at information from System.Data.SqlClient namespace, for example.


This script retrieves specific information from connections.


 


It’s also easy to extend it, so you can use the same approach to extract information from other namespaces and fields.


 


Personally, I prefer the approach based on DML (Debug Markup Language) because I can use hyperlinks and the default script call: $$><. The DML approach requires more work and more low-level programming, but offers better results as you can see in most the scripts I create.


 


You need to run it using $$< not $$><


 


 


 


Source code for CONNECTIONS_POOL.TXT:


 


$$


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


$$ Verify Connections from Pool.


$$


$$ Compatilibity: Win32, should work on Win64.


$$


$$ Attention! For .Net Framework 2.0, edit the script and remove the clr10\\ from it so it can use the


$$ sos.dll version 2.0


$$


$$ Usage: $$< to run the script. (note: Just $$< not $$><)


$$


$$ Requirements: Public symbols.


$$


$$ Roberto Alexis Farah


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


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


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


$$


.shell -i – -ci “.foreach ( obj {!clr10\\sos.dumpheap -type System.Data.SqlClient.SqlInternalConnection -short} ) {!do ${obj} }” FIND  “_fInPool”


.shell -i – -ci “.foreach ( obj {!clr10\\sos.dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl -short} ) {!do ${obj} }” FIND  “_fResetConnection”


.shell -i – -ci “.foreach ( obj {!clr10\\sos.dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl -short} ) {!do ${obj} }” FIND  “_maxPool”


$$


$$ Number of Connection Objects


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


$$


!clr10\\sos.dumpheap -type System.Data.OleDb.OleDbConnection -stat


$$


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


 


 


Read me.

Comments (12)

  1. nativecpp says:

    I have a winform app that is using ADO.NET and have some questions:

    1)After getting the symbol and setting the path, I attached my app to WinDbg.

    2) When I execute the script, I got yhe following error:

    0:000> $$<c:myscriptsconnections_pool.txt

    0:000> $$

    0:000> $$ =============================================================================

    0:000> $$ Verify Connections from Pool.

    0:000> $$

    0:000> $$ Compatilibity: Win32, should work on Win64.

    0:000> $$

    0:000> $$ Usage: $$< to run the script. (note: Just $$< not $$><)

    0:000> $$

    0:000> $$ Requirements: Public symbols.

    0:000> $$

    0:000> $$ Roberto Alexis Farah

    0:000> $$ Blog: http://blogs.msdn.com/debuggingtoolbox/

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

    0:000> $$ =============================================================================

    0:000> $$

    0:000> .shell -i – -ci ".foreach ( obj {!clr10\sos.dumpheap -type System.Data.SqlClient.SqlInternalConnection -short} ) {!do ${obj} }" FIND  "_fInPool"

    .shell: Process exited

    0:000> .shell -i – -ci ".foreach ( obj {!clr10\sos.dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl -short} ) {!do ${obj} }" FIND  "_fResetConnection"

    .shell: Process exited

    0:000> .shell -i – -ci ".foreach ( obj {!clr10\sos.dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl -short} ) {!do ${obj} }" FIND  "_maxPool"

    .shell: Process exited

    0:000> $$

    0:000> $$ Number of Connection Objects

    0:000> $$ ============================

    0:000> $$

    0:000> !clr10\sos.dumpheap -type System.Data.OleDb.OleDbConnection -stat

    Cannot get the ThreadStore, do you have symbols for the mscorwks/mscorsvr files?

    0:000> $$

    0:000> $$ ===================================================================

    Why is that ? :-(

    I then tried to execute sos command !clrstack and got similar error:

    0:000> !clrstack

    Thread 0

    Cannot get the ThreadStore, do you have symbols for the mscorwks/mscorsvr files?

    Not a managed thread.

    I checked the symbol path and looks like it it OK:

    Symbol search path is: C:WINDOWSSymbols;C:WINDOWSSymbolsdll

    My mscorwks DLL & PDB info is as follow:

    DLL => 9/23/2005 @7:28am

    PDB => 8/3/2004 @ 10:12pm

    Is my PDB out of date ? If so, where do I get the matching PDB ?

    Thanks

  2. Hi,

    Let’s try it first:

    1- Make sure you are using our public symbols. Your Windbg Symbol path should be something like:

    SRV*c:windowssymbols*http://msdl.microsoft.com/download/symbols

    Reference: http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx

    2- Before running the script, use this command:

    .reload /f

    It forces all symbols for the application to be loaded.

    3- Use this command:

    !clr10sos.dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl

    Or:

    .load sos

    !dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl

    If your process is using it, then you should get something, otherwise nothing will be displayed. Anyway you shouldn’t get an error message.

    4- Run the script. If the process is using the SqlConnectionPoolControl then the script should show you the information.

  3. nativecpp says:

    Hi,

    For some reason, I am having problem executing the script. However, if I just executed the individual sos command (e.g.!dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl), I have no problems. At any rate, it is OK since I still can get the connection pool info from the individual command.

    Thanks

  4. Hum… are you using the SOS version that comes with Windbg? I guess I know what it is… the SOS version that comes with Windbg has some additional features. It accepts the -short argument, for example.

    Just to prove the point use the following command:

    !dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl -short

    If you get a message like: “Unknown option: -short” it means you are using the version from Microsoft .NETFramework.

    Now use the CLR10sos and the same command.

    The script should use the CLR10 version, but just to make sure, unload the regular sos and let it uses the CLR10 version.

    Please, let me know if it works. I’m curious here :)

  5. nativecpp says:

    If I executed w/o clr10, it seems OK. But if I executed with clr10, it complained as shown below:

    :011> !dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl -short

    0:011> !clr10\sos.dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl -short

    Cannot get the ThreadStore, do you have symbols for the mscorwks/mscorsvr files?

    Once the error occurs, I will get error even I executed w/o clr10. I am confused :-(( as shown below:

    0:007> !dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl -short

    Cannot get the ThreadStore, do you have symbols for the mscorwks/mscorsvr files?

    0:007> !dumpheap -type System.Data.SqlClient.SqlInternalConnection

    Cannot get the ThreadStore, do you have symbols for the mscorwks/mscorsvr files?

    Thanks

  6. Ok, it seems you are using .NET Framework 2.0 and the SOS for 2.0. (my mistake, I didn’t consider it before)

    Just edit the script and remove the CLR10 from the source code.

    Please, let me know if it worked.

  7. nativecpp says:

    Hi,

    I removed the clr10 and it doesn’t complain anymore. However, it raises more questions for me and may be you can help to shed some light:

    1)I have to execute .load sos for the extension. Your src seems to indicate that you can execute directly (even though hard-coded)by prefix clr10. Is my observation correct ? If so, how do I prefix 2.0 ?

    2)Even though the script does NOT produce syntax error, it didn’t produce any output as shown below:

    0:009> .shell -i – -ci ".foreach ( obj {!dumpheap -type System.Data.SqlClient.SqlInternalConnection -short} ) {!do ${obj} }" FIND  "_fInPool"

    .shell: Process exited

    0:009> .shell -i – -ci ".foreach ( obj {!dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl -short} ) {!do ${obj} }" FIND  "_fResetConnection"

    .shell: Process exited

    0:009> .shell -i – -ci ".foreach ( obj {!dumpheap -type System.Data.SqlClient.SqlConnectionPoolControl -short} ) {!do ${obj} }" FIND  "_maxPool"

    .shell: Process exited

    However, if I manually execute the sos command, it produced the output as expected. I could even execute !do as shown below:

    0:009> !dumpheap -type System.Data.SqlClient.SqlInternalConnection -short

    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:WINDOWSMicrosoft.NETFrameworkv2.0.50727mscorwks.dll –

    PDB symbol for mscorwks.dll not loaded

    0161644c

    0161e270

    01625c10

    0162b170

    0:009> !do (0161644c)

    Name: System.Data.SqlClient.SqlInternalConnectionTds

    MethodTable: 653cbfdc

    EEClass: 6540d578

    Size: 132(0x84) bytes

    (C:WINDOWSassemblyGAC_32System.Data2.0.0.0__b77a5c561934e089System.Data.dll)

    Fields:

         MT    Field   Offset                 Type VT     Attr    Value Name

    790fed1c  4000ed0       1c         System.Int32  0 instance        4 _objectID

    79104f64  4000ed3       28       System.Boolean  0 instance        0 _allowSetConnectionString

    79104f64  4000ed4       29       System.Boolean  0 instance        1 _hidePassword

    I am not an expert on scripts but from what I can see, the script seems ok by using for loop and !do. So, I am not sure why it didn’t produce any results.

    4)It seems that once I executed clr10\.. command, the !dumphead that used to work doesn’t work again. I tried to load sos again but it still doesn’t work as shown below:

    0:009> !clr10\sos.dumpheap -type System.Data.SqlClient.SqlInternalConnection -short

    Cannot get the ThreadStore, do you have symbols for the mscorwks/mscorsvr files?

    0:009> .load C:WINDOWSMicrosoft.NETFrameworkv2.0.50727sos

    0:009> !dumpheap -type System.Data.SqlClient.SqlInternalConnection -short

    Cannot get the ThreadStore, do you have symbols for the mscorwks/mscorsvr files?

    How do I reset so that the !dumpheap (w/o clr10)will work again.

    Thanks for your help. It is real fun reading your blog.

  8. Hi,

    I use clr10\sos just to avoid using .load sos. The SOS version that comes with Windbg isn’t working because it is for version 1.1 (http://blogs.msdn.com/aaronba/archive/2006/05/17/600589.aspx)  and you are using .NET Framework 2.0

    You can use any extension command doing that:

    .load extension.dll

    !command

    or just:

    !extension.command

    That said, try it:

    – Remove clr10\sos from the source.

    – Load the dump file or process using Windbg.

    – Use .reload /f

    – Use .load SOS  

    – Run the script.

    Another approach:

    – Remove clr10\ from the source. Keep the !sos

    – Load the dump file or process using Windbg.

    – Use .reload /f

    – Run the script.

    For the next scripts I’ll assume SOS v2.0 as the default SOS.

    Here I use PSSCOR/PSSCOR2 that are our internal SOS version then I change the calls to SOS and do a quick test using just public symbols before publishing the article.

    Thus, your feedbacks are very useful to adapt the scripts to SOS. I really appreciate them!

  9. salih says:

    Hi,

    I am new at WinDbg and I edited your script as follow

    .shell -i – -ci".foreach ( obj {x module_name!*key_to_search*} ) {!do ${obj} }" FIND "filter_str"

    However when I run this, the command window opens and closes immediately so I couldn’t see the output. And the  WinDbg commnad output only says ".shell: Process exited"

    1) How can I print the FIND output to WinDbg command window as shown above on the image?

    2) What is the !do command. I coudn’t find in documantation.

    I am sorry if they are too simple questions, as I mentioned I am new at both windbg and scripting.

  10. Hi salih,

    Good news for you: soon the .shell command is going to be in a new article under Special Commands section. :)

    Your command is executing so fast because it is doing nothing.

    Look:

    .shell -i – -ci".foreach ( obj {x module_name!*key_to_search*} ) {!do ${obj} }" FIND "filter_str"

    module_name must be one of the modules names that are in your process or dump.

    key_to_search must have a valid value replacing it.

    filter_str must have a valid value replacing it.

    Also, don’t forget to load the SOS extension before using it.

    Now the answers for your questions:

    1- Using valid values the output should appear in your WinDbg window.

    2- !do is !dumpobject. This command is part of the SOS extension that comes with the .NET Framework. Version 1.1 also comes with WinDbg and should be in the clr10 folder.

    Tip: When you have to "debug" a script that is failing, try to break it in separated commands and execute each part separately. After making sure each part is working you put them together, little by little.

    In my next article I’ll talk about a command that shows you all commands being used by WinDbg scripts or the scripts based on the PowerDbg tool.

    Let me know if you have more questions and have fun with WinDbg :)

  11. Thank you for your detailed explanation.

    My intention was totaly wrong.

    .shell -i – -ci "x module!*key_to_search*" FIND "filter_str"

    would be enough for me. But this tutorial let me learn how to use .shell command.

    Thank you for your kind concern.