Thursday, January 31, 2008

Setting multiple breakpoints via wildcard pattern

Sometimes I need a break point on a specific funtion in multiple classes. Examples are the use of templates, interfaces or inheritence.

This can be easily achived via the bm (I translate as break match).

Example:

bm /a MyModule!!CComCollectionMap*::*get_Exists*


This will set a deferred breakpoint on every function that matches the given expression.
It is a good idea to check the matches upfront with the following expression:

x MyModule!!CComCollectionMap*::*get_Exists*

In order to clear all currently set break points use:

bc *

For more details refer to the very good Online Help under "bp, bu, bm (Set Breakpoint)"

Wednesday, January 30, 2008

List source lines at current scope ip

To list the source at the currently selected frame (which can be set by either the .frame command or by clicking into the call stack window) use the lsa (List Source Lines) command:

0:000> lsa @$scopeip
578:
579: ' Setting device name
580: If (gPrintContext.strPrinter = "") Then
581: If (rpt.Printer.NDevices > 0) Then
> 582: gPrintContext.strPrinter = rpt.Printer.DeviceName
583: ' "Device Name is empty hence setting it to the default printer."
584: Else
585: ' the .PageSetup will show the system message
586: ' "No printer installed."
587: End If


Monday, January 28, 2008

Google Custom Search for WinDbg

I often came across the point where I needed to search the web for a common phrases used in very special technical manner. One example is sos or son of strike. If you simply search for sos you will get everything but not what you are interested in.

For getting help finding the needle in the hay when it comes to windbg I created a Google Custom Search Engine for windbg.

You can find the CSE here or directly on my page here:




If you have additional sites for me to add, please drop a comment here....

Thursday, January 24, 2008

CoCreateInstance: Which object in which dll

I came across a process that was consuming statically 25% CPU which I didn't understand why.
So I attached windbg and issued

0:004> !runaway
User Mode Time
Thread Time
4:328 0 days 0:07:22.015
0:2a0 0 days 0:00:25.078
5:228 0 days 0:00:00.000
3:324 0 days 0:00:00.000
2:320 0 days 0:00:00.000
1:31c 0 days 0:00:00.000

So switch to that thread

0:004> ~4 s

And issue a stack dump:

0:004> kb 100
ChildEBP RetAddr Args to Child
[...]
010be7a0 77f6946c 010bec5c 00000000 00000401 ole32!CoCreateInstance+0x37
[...]
010bfe7c 0052770f 010bfe98 010bfee0 0052773f shell32!ShellExecuteExA+0x203


So I had two questions:

1.) Which process should be launched by ShellExecute
2.) Which object should be created by CoCreateInstance

ad 1.) First param passed to ShellExecute is of type LPSHELLEXECUTEINFO
dt _SHELLEXECUTEINFO 010bfe98 didn't work for me although having symbol server setup correctly. So I needed the fifth pointer in the struct:

0:004> dda 010bfe98

did the job:
010bfe98 0000003c
010bfe9c 00000440
010bfea0 00000000
010bfea4 00527768 "open"
010bfea8 00527758 "Viewer.exe" <== 010bfeac 00000000

ad 2.) First param passed is of type REFCLSID or GUID
Then I got it via:
0:004> dt ntdll!_GUID 010bec5c
{871c5380-42a0-1069-a2ea-08002b30309d}
+0x000 Data1 : 0x871c5380
+0x004 Data2 : 0x42a0
+0x006 Data3 : 0x1069
+0x008 Data4 : [8] "???"

Now use either regedit or more elegantly:
0:005> !dreg hkcr\CLSID\{871C5380-42A0-1069-A2EA-08002B30309D}\InProcServer32\!*
Value: "" - REG_EXPAND_SZ: "%SystemRoot%\system32\shdocvw.dll"
expanded = "C:\WINDOWS\system32\shdocvw.dll"
------------------------------------------------------------------------
Value: "ThreadingModel" - REG_SZ: "Apartment"
------------------------------------------------------------------------

That's it!

Thursday, January 17, 2008

Setting a thread sensitive Breakpoint

I just came across the problem that I needed to break at a function just in case this function is executed in one specific thread.

In Visual Studio 2008 (and also earlier) you can achieve this via Breakpoint filters:
1.) Right click on the Breakpoint and click on Filter...


2.) Now specify the thread id you want to break in...


In windbg you can achieve it like this:

Instead of typing:

bp MyModule!MyClass::MyFunction+MyOffset


type:
~ 13 bp MyModule!MyClass::MyFunction+MyOffset

to break in just if this function is executed in thread with id 13

Wishlist: Writing Debugger extension program in C#

In xqiu's blog I found an interesting post about Writing Debugger extension program in C# . Unfortunately the mentioned mdbeng.dll is not public yet. I contacted the Debugger Team with the wish to get it. Let's see what comes...