The .shell command in Windbg allows to pipe the output of a debugger command to an external process and automatically print its output back inside the debugger window; a useful example is the command FIND, for example if we want to parse the stack for every thread and find every call where the word “isapi” is involved:
0:036> .shell -ci "~*kpL1000" find /i "isapi"013cff78 1004f94e ISAPI_Rewrite!TerminateFilter+0x3cef013cffb0 1004f9f3 ISAPI_Rewrite!TerminateFilter+0x4462e013cffec 00000000 ISAPI_Rewrite!TerminateFilter+0x446d30144ff78 1004f94e ISAPI_Rewrite+0x77630144ffb0 1004f9f3 ISAPI_Rewrite!TerminateFilter+0x4462e0144ffec 00000000 ISAPI_Rewrite!TerminateFilter+0x446d3.shell: Process exited
Incidentally also LogParser (one of my favorite debugging tools) can accept data to be parsed from the input stream using the STDIN keyword, so for example refactoring a script I posted some time ago we can find out if there are any duplicated assemblies in our application pool that should be moved to the GAC:
0:000> .shell -ci "!peb" logparser "select extract_filename(text) as Duplicated_Assemblies, count(Duplicated_Assemblies) as Hits from STDIN where index_of(text, 'temporary asp.net files') > 0 group by Duplicated_Assemblies having count(Duplicated_Assemblies) > 1" -i:textline -o:nat -rtp:-1Duplicated_Assemblies Hits ---------------------------- ----errormanager.dll 2winformsui.dll 2externallibraryinterface.dll 2ptshopengine.dll 2schemas.dll 2dbengine.dll 2flowservice.dll 2Statistics:-----------Elements processed: 182Elements output: 7Execution time: 0.02 seconds.shell: Process exited
Following the same principle, we can find out if there are strong named assemblies in our /bin folder as follows:
0:000> .shell -ci "!dumpdomain" find /i "shared domain"Shared Domain: 0x793f2aa8.shell: Process exited0:000> .shell -ci "!dumpdomain 0x793f2aa8" logparser "SELECT DISTINCT EXTRACT_FILENAME(text) as Strong_Named_Assemblies_In_/bin FROM STDIN WHERE INDEX_OF(to_lowercase(text), 'temporary asp.net files') > 0" -i:TEXTLINE -o:NAT -RTP:-1Strong_Named_Assemblies_In_/bin -----------------------------------------crypto.dllradplaceholder.dllscms.dllsqldac.dllscontrollibrary.dllspell.dlleditor.dllscms.resources.dllStatistics:-----------Elements processed: 164Elements output: 8Execution time: 0.01 seconds.shell: Process exited
0:000> .shell -ci "!dumpdomain" find /i "shared domain"Shared Domain: 0x793f2aa8.shell: Process exited
0:000> .shell -ci "!dumpdomain 0x793f2aa8" logparser "SELECT DISTINCT EXTRACT_FILENAME(text) as Strong_Named_Assemblies_In_/bin FROM STDIN WHERE INDEX_OF(to_lowercase(text), 'temporary asp.net files') > 0" -i:TEXTLINE -o:NAT -RTP:-1Strong_Named_Assemblies_In_/bin -----------------------------------------crypto.dllradplaceholder.dllscms.dllsqldac.dllscontrollibrary.dllspell.dlleditor.dllscms.resources.dllStatistics:-----------Elements processed: 164Elements output: 8Execution time: 0.01 seconds.shell: Process exited
Instead of typing the whole command you can save it in a text file and execute it directly within Windbg with a command like “$><c:\debuggers\snassemblies.txt”.
Carlo