Over the course of the last few months, I've really put lots of effort into understanding and utilizing WinDbg. As a primarily C# developer, this meant also becoming intimately familiar with the SOS extension. Though a bit tedious, this exercise has already paid rich dividends in my debugging experience. As powerful and handy as SOS is, however, it has some annoying limitations and quirks. My personal peeves with SOS, combined with my desire to learn to write a WinDbg extension, led me to develop SOSEX, a debugging extension for managed code that begins to alleviate some of my frustrations with SOS. SOSEX (available in x86 and x64 versions) provides 8 easy-to-use commands: !dumpgen (dumps the contents of a GC generation), !gcgen (indicates the GC generation of a given object), !refs (lists all references to and from the specified object), !bpsc (breakpoint, source code), !bpmo (breakpoint, method offset), !vars (dump all args and local variables), !isf (inspect static field) and !dlk (deadlock detection). The rest of this post will provide a bit more detail about each command and how they can save you time. Use the !help command for a list of commands and !help <command name> for the syntax and usage of each command.
!dumpgen and !gcgenWith SOS, you can dump the contents of the heap like so:0:000> !dumpheap -short
00000642787c7370
00000642787c7388
00000642787c73b0
00000642787c7410
00000642787c7440
00000642787c7498
00000642787c74f0...The problem with this is that there is no easy way to tell from the output which generation each object belongs to. You can follow up the call to !dumpheap with !eeheap -gc, which will provide the necessary information to determine generations. However, determining the contents of, say, generation 2 using this method is very tedious. Here's the output of !eeheap -gc for a dual-processor system in server GC mode: 0:000> !eeheap -gc
Number of GC Heaps: 2
------------------------------
Heap 0 (0000000002264180)
generation 0 starts at 0x000000007fff0098
generation 1 starts at 0x000000007fff0080
generation 2 starts at 0x000000007fff0068
ephemeral segment allocation context: none
segment begin allocated size
0000000002271b80 00000642787c7370 0000064278809088 0x0000000000041d18(269592)
000000007fff0000 000000007fff0068 0000000080002fe8 0x0000000000012f80(77696)
Large object heap starts at 0x00000000ffff0068
segment begin allocated size
00000000ffff0000 00000000ffff0068 00000000ffff80c8 0x0000000000008060(32864)
Heap Size 0x5ccf8(380152)
------------------------------
Heap 1 (0000000002264e00)
generation 0 starts at 0x00000000bfff0098
generation 1 starts at 0x00000000bfff0080
generation 2 starts at 0x00000000bfff0068
ephemeral segment allocation context: none
segment begin allocated size
00000000bfff0000 00000000bfff0068 00000000bfff00b0 0x0000000000000048(72)
Large object heap starts at 0x000000010fff0068
segment begin allocated size
000000010fff0000 000000010fff0068 000000010fff0080 0x0000000000000018(24)
Heap Size 0x60(96)
------------------------------
GC Heap Size 0x5cd58(380248) As you can see, you have a lot of work to do in order to pick through the output of !dumpheap and compare object addresses to the segment addresses provided by !eeheap -gc. Enter SOSEX's !dumpgen command. Read more: Steve's Techspot, SOSEX v4.0 Now Available
!dumpgen and !gcgenWith SOS, you can dump the contents of the heap like so:0:000> !dumpheap -short
00000642787c7370
00000642787c7388
00000642787c73b0
00000642787c7410
00000642787c7440
00000642787c7498
00000642787c74f0...The problem with this is that there is no easy way to tell from the output which generation each object belongs to. You can follow up the call to !dumpheap with !eeheap -gc, which will provide the necessary information to determine generations. However, determining the contents of, say, generation 2 using this method is very tedious. Here's the output of !eeheap -gc for a dual-processor system in server GC mode: 0:000> !eeheap -gc
Number of GC Heaps: 2
------------------------------
Heap 0 (0000000002264180)
generation 0 starts at 0x000000007fff0098
generation 1 starts at 0x000000007fff0080
generation 2 starts at 0x000000007fff0068
ephemeral segment allocation context: none
segment begin allocated size
0000000002271b80 00000642787c7370 0000064278809088 0x0000000000041d18(269592)
000000007fff0000 000000007fff0068 0000000080002fe8 0x0000000000012f80(77696)
Large object heap starts at 0x00000000ffff0068
segment begin allocated size
00000000ffff0000 00000000ffff0068 00000000ffff80c8 0x0000000000008060(32864)
Heap Size 0x5ccf8(380152)
------------------------------
Heap 1 (0000000002264e00)
generation 0 starts at 0x00000000bfff0098
generation 1 starts at 0x00000000bfff0080
generation 2 starts at 0x00000000bfff0068
ephemeral segment allocation context: none
segment begin allocated size
00000000bfff0000 00000000bfff0068 00000000bfff00b0 0x0000000000000048(72)
Large object heap starts at 0x000000010fff0068
segment begin allocated size
000000010fff0000 000000010fff0068 000000010fff0080 0x0000000000000018(24)
Heap Size 0x60(96)
------------------------------
GC Heap Size 0x5cd58(380248) As you can see, you have a lot of work to do in order to pick through the output of !dumpheap and compare object addresses to the segment addresses provided by !eeheap -gc. Enter SOSEX's !dumpgen command. Read more: Steve's Techspot, SOSEX v4.0 Now Available
0 comments:
Post a Comment