Posts Tagged ‘perfmonitor’
Get managed call-stacks in .NET for Registry access using ETW
I was recently debugging managed code which was accessing system registry implicitly because of an external dependent library. So the first thing I asked was a Procmon log for of registry access. And then I also wanted look at the call-stacks for registry access, which Procmon does provide.
Here is a sample call-stack from Procmon for registry access. I am using linqpad as an example in this
ntoskrnl.exe CmpCallCallBacks + 0x1c0 0xfffff80002c870d0
ntoskrnl.exe ?? ::NNGAKEGL::`string’ + 0x4c81d 0xfffff80002c31116
ntoskrnl.exe KiSystemServiceCopyEnd + 0×13 0xfffff800028d4853
ntdll.dll ZwSetInformationKey + 0xa 0x779214aa
wow64.dll wow64.dll + 0x2d252 0x7399d252
wow64.dll wow64.dll + 0x1008f 0x7398008f
wow64.dll wow64.dll + 0xcf87 0x7397cf87
wow64cpu.dll TurboDispatchJumpAddressEnd + 0×24 0x7390276d
wow64.dll wow64.dll + 0xd07e 0x7397d07e
wow64.dll wow64.dll + 0xc549 0x7397c549
ntdll.dll LdrpInitializeProcess + 0x17e2 0x779184c8
ntdll.dll ?? ::FNODOBFM::`string’ + 0x2bea0 0×77917623
ntdll.dll LdrInitializeThunk + 0xe 0x7790308e
ntdll.dll NtOpenKey + 0×12 0x77acf9da
KernelBase.dll OpenRegKey + 0×134 0x772f2ef3
KernelBase.dll OpenAltSortsKey + 0×29 0x772de216
KernelBase.dll IsValidLocale + 0×127 0x772e3271
clr.dll clr.dll + 0xe4d5f 0x6be34d5f
clr.dll clr.dll + 0xe4ba8 0x6be34ba8
mscorlib.ni.dll mscorlib.ni.dll + 0x2ba2f1 0x697ba2f1
mscorlib.ni.dll mscorlib.ni.dll + 0x2ba2c1 0x697ba2c1
mscorlib.ni.dll mscorlib.ni.dll + 0x2b9faa 0x697b9faa
mscorlib.ni.dll mscorlib.ni.dll + 0x2b9e0a 0x697b9e0a
mscorlib.ni.dll mscorlib.ni.dll + 0x2ba15c 0x697ba15c
mscorlib.ni.dll mscorlib.ni.dll + 0x2ba106 0x697ba106
mscorlib.ni.dll mscorlib.ni.dll + 0x2b9db8 0x697b9db8
mscorlib.ni.dll mscorlib.ni.dll + 0x2b9d34 0x697b9d34
clr.dll clr.dll + 0x24a2a 0x6bd74a2a
clr.dll clr.dll + 0×23153 0x6bd73153
clr.dll clr.dll + 0x231cc 0x6bd731cc
clr.dll clr.dll + 0x2323b 0x6bd7323b
clr.dll clr.dll + 0×23415 0x6bd73415
clr.dll clr.dll + 0x2355a 0x6bd7355a
clr.dll clr.dll + 0×94844 0x6bde4844
<unknown> 0xb2420 0xb2420
mscorlib.ni.dll mscorlib.ni.dll + 0×255870 0×69755870
mscorlib.ni.dll mscorlib.ni.dll + 0x2557cd 0x697557cd
mscorlib.ni.dll mscorlib.ni.dll + 0×255764 0×69755764
<unknown> 0x4e00d9 0x4e00d9
clr.dll clr.dll + 0x21db 0x6bd521db
clr.dll clr.dll + 0x24a2a 0x6bd74a2a
clr.dll clr.dll + 0x24bcc 0x6bd74bcc
clr.dll clr.dll + 0x24c01 0x6bd74c01
clr.dll clr.dll + 0x24c21 0x6bd74c21
clr.dll clr.dll + 0xece82 0x6be3ce82
clr.dll clr.dll + 0xecf90 0x6be3cf90
clr.dll clr.dll + 0xecda4 0x6be3cda4
clr.dll clr.dll + 0xed199 0x6be3d199
clr.dll clr.dll + 0xed09a 0x6be3d09a
clr.dll clr.dll + 0x16af00 0x6bebaf00
mscoreei.dll mscoreei.dll + 0x55ab 0x726355ab
mscoree.dll mscoree.dll + 0x7f16 0x75077f16
mscoree.dll mscoree.dll + 0x4de3 0x75074de3
ntdll.dll __RtlUserThreadStart + 0×70 0x77ae9d72
ntdll.dll _RtlUserThreadStart + 0x1b 0x77ae9d45
It is all unmanaged call-stacks , what I was looking for was managed call-stacks. The solution to this was ETW tracing. I use Perfmonitor from the BCL teams codeplex site for getting managed call-stacks.
Here are the steps to get managed call-stacks for registry access
PerfMonitor.exe /registry /stacks /lineNumbers start
Run the process and do the steps for registry access
PerfMonitor.exe /registry /stacks /lineNumbers stop PerfMonitor.exe /stacks /lineNumbers print
The above should produce a xml file which is by default named as PerfMonitorOutput.print.xml
And here is the managed call-stacks for registry access.
<Event MSec= “3449.0880″ PID=”3356″ PName= “LINQPad” TID=”4536″ EventName=”RegistryOpen” Status=”0×00000000″ KeyHandle=”0×00000000″ ElapsedTime=”0″ KeyName=”\Registry\Machine\System\CurrentControlSet\Control\Nls\Locale\Alternate Sorts” Index=”0″ InitialTime=”1/3/1601 1:11:43 PM”>
<StackTrace>
<CodeAddress Address=”0xfffff80002c22003″ FullMethodName=”_NULL_IMPORT_DESCRIPTOR” ModuleName=”ntoskrnl”/>
<CodeAddress Address=”0xfffff80002bb5d3b” FullMethodName=”$$VProc_ImageExportDirectory” ModuleName=”ntoskrnl”/>
<CodeAddress Address=”0xfffff800028d4853″ FullMethodName=”KiDeliverApc” ModuleName=”ntoskrnl”/>
<CodeAddress Address=”0x77920e0a” FullMethodName=”ZwOpenKeyEx” ModuleName=”ntdll”/>
<CodeAddress Address=”0x7399d1f1″ ModuleName=”wow64″/>
<CodeAddress Address=”0x7398008f” ModuleName=”wow64″/>
<CodeAddress Address=”0x7397cf87″ ModuleName=”wow64″/>
<CodeAddress Address=”0x7390276d” ModuleName=”wow64cpu”/>
<CodeAddress Address=”0x7397d07e” ModuleName=”wow64″/>
<CodeAddress Address=”0x7397c549″ ModuleName=”wow64″/>
<CodeAddress Address=”0x779184c8″ FullMethodName=”LdrpInitializeProcess” ModuleName=”ntdll”/>
<CodeAddress Address=”0×77917623″ FullMethodName=” ?? ::FNODOBFM::`string'” ModuleName=”ntdll”/>
<CodeAddress Address=”0x7790308e” FullMethodName=”LdrInitializeThunk” ModuleName=”ntdll”/>
<CodeAddress Address=”0x77acf9da” FullMethodName=”NtOpenKey” ModuleName=”ntdll”/>
<CodeAddress Address=”0x772f2ef3″ ModuleName=”KernelBase”/>
<CodeAddress Address=”0x772de216″ ModuleName=”KernelBase”/>
<CodeAddress Address=”0x772e3264″ ModuleName=”KernelBase”/>
<CodeAddress Address=”0x6be34d5f” ModuleName=”clr”/>
<CodeAddress Address=”0x6be34ba8″ ModuleName=”clr”/>
<CodeAddress Address=”0x697ba2f1″ FullMethodName=”System.Globalization.CultureData.InitCultureData()” ModuleName=”mscorlib”/>
<CodeAddress Address=”0x697ba2c1″ FullMethodName=”System.Globalization.CultureData.CreateCultureData(class System.String,bool)” ModuleName=”mscorlib”/>
<CodeAddress Address=”0x697b9faa” FullMethodName=”System.Globalization.CultureData.GetCultureData(class System.String,bool)” ModuleName=”mscorlib”/>
<CodeAddress Address=”0x697b9e0a” FullMethodName=”System.Globalization.CultureInfo..ctor(class System.String,bool)” ModuleName=”mscorlib”/>
<CodeAddress Address=”0x697ba15c” FullMethodName=”System.Globalization.CultureInfo.GetCultureByName(class System.String,bool)” ModuleName=”mscorlib”/>
<CodeAddress Address=”0x697ba106″ FullMethodName=”System.Globalization.CultureInfo.InitUserDefaultCulture()” ModuleName=”mscorlib”/>
<CodeAddress Address=”0x697b9db8″ FullMethodName=”System.Globalization.CultureInfo.Init()” ModuleName=”mscorlib”/>
<CodeAddress Address=”0x697b9d34″ FullMethodName=”System.Globalization.CultureInfo..cctor()” ModuleName=”mscorlib”/>
<CodeAddress Address=”0x6bd74a2a” ModuleName=”clr”/>
<CodeAddress Address=”0x6bd73153″ ModuleName=”clr”/>
<CodeAddress Address=”0x6bd731cc” ModuleName=”clr”/>
<CodeAddress Address=”0x6bd7323b” ModuleName=”clr”/>
<CodeAddress Address=”0x6bd73415″ ModuleName=”clr”/>
<CodeAddress Address=”0x6bd7355a” ModuleName=”clr”/>
<CodeAddress Address=”0x6bde4844″ ModuleName=”clr”/>
<CodeAddress Address=”0×122420″/>
<CodeAddress Address=”0×69755870″ FullMethodName=”System.Version.TryParseVersion(class System.String,value class VersionResult&)” ModuleName=”mscorlib”/>
<CodeAddress Address=”0x697557cd” FullMethodName=”System.Version.Parse(class System.String)” ModuleName=”mscorlib”/>
<CodeAddress Address=”0×69755764″ FullMethodName=”System.Version..ctor(class System.String)” ModuleName=”mscorlib”/>
<CodeAddress Address=”0x1e00d9″ FullMethodName=”LINQPad.Loader.Main(class System.String[])” ModuleName=”LINQPad”/>
<CodeAddress Address=”0x6bd521db” ModuleName=”clr”/>
<CodeAddress Address=”0x6bd74a2a” ModuleName=”clr”/>
<CodeAddress Address=”0x6bd74bcc” ModuleName=”clr”/>
<CodeAddress Address=”0x6bd74c01″ ModuleName=”clr”/>
<CodeAddress Address=”0x6bd74c21″ ModuleName=”clr”/>
<CodeAddress Address=”0x6be3ce82″ ModuleName=”clr”/>
<CodeAddress Address=”0x6be3cf90″ ModuleName=”clr”/>
<CodeAddress Address=”0x6be3cda4″ ModuleName=”clr”/>
<CodeAddress Address=”0x6be3d199″ ModuleName=”clr”/>
<CodeAddress Address=”0x6be3d09a” ModuleName=”clr”/>
<CodeAddress Address=”0x6bebaf00″ ModuleName=”clr”/>
<CodeAddress Address=”0x726355ab” ModuleName=”mscoreei”/>
<CodeAddress Address=”0x75077f16″ ModuleName=”mscoree”/>
<CodeAddress Address=”0x75074de3″ ModuleName=”mscoree”/>
<CodeAddress Address=”0x77ae9d72″ FullMethodName=”__RtlUserThreadStart” ModuleName=”ntdll”/>
<CodeAddress Address=”0x77ae9d45″ FullMethodName=”_RtlUserThreadStart” ModuleName=”ntdll”/>
</StackTrace>
</Event>
Here I was able to get the managed as well as native call-stacks for registry access by keyname. And here is my list of posts on ETW