Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting... Please check out the Community Guidelines in the
Announcements and Administration Category, below.

Difference in WinDBG "!analyze -v" stack formatting

Is there anyway to alter the "kb" statement that "!analyze -v" executes
into a "kvn" or to get kb to also show FPO data?

I think most users would consider the second format much more informative.
It should be the default.

All results shown for this version of WinDBG:
Microsoft (R) Windows Debugger Version 10.0.10586.567 X86
and they come from the same minidump.

When I process a minidump with the "!analyze -v" I get a result like this:
=========================================
STACK_TEXT:
00918d18 768b4740 oleaut32!SysAllocString+0x15
00918d20 77d3c4fc sp3deqpcadhelper!ATL::CComBSTR::CComBSTR+0x2c
00918d34 77d2210d
sp3deqpcadhelper!CCADServices::CheckMemberConditional+0x53d
00918f44 17cdff75 sp3dpullpitasm!PullPitDef::CMConditionalPullBoxSolid+0x86
00918fa8 768ccc68 oleaut32!DispCallFunc+0x165
00918fc8 4ff03c67 msvbvm60+0x63c67
00919924 4ff03975 msvbvm60+0x63975
00919980 186f1fe1 imssymbolentities!PerformMethodViaAutomation+0x3e1
00919a78 186ea61f imssymbolentities!PerformActiveXMethod+0x1bf
00919af4 1865627d imssymbolentities!CSblDefinition::InvokeMethod+0x8bd
00919c74 52353d4e
customassembly!CDMemberDescription::InvokeCMConditional+0x2de
=========================================

Luckily, years ago I noticed that if I execute "kvn20" after the results of
"!analyze -v" are printed, I get a much more informative stack, with FPO
data:
=========================================
EXCEPTION_STACK_TEXT:
0:000> kvn20
# ChildEBP RetAddr Args to Child
00 00918d18 77d3c4fc cdcdcdcd 00918d38 00918ebc
oleaut32!SysAllocString+0x15 (FPO: [Non-Fpo])
01 00918d2c 77d2210d cdcdcdcd 21747db9 00000000
SP3DEqpCADHelper!ATL::CComBSTR::CComBSTR+0x2c (FPO: [Non-Fpo]) (CONV:
thiscall) [c:\program files (x86)\microsoft visual studio
14.0\vc\atlmfc\include\atlcomcli.h @ 775]
02 00918f3c 17cdff75 1c0e5504 15d65c24 00918f70
SP3DEqpCADHelper!CCADServices::CheckMemberConditional+0x53d (FPO:
[Non-Fpo]) (CONV: stdcall)
[m:\equipment\middle\services\equipcadhelper\sp3deqpcadhelper\cadservices.cpp
@ 1566]
03 00918fa0 768ccc68 1053c118 15d65c24 0091bff4
SP3DPullPitAsm!PullPitDef::CMConditionalPullBoxSolid+0x86
[M:\SharedContent\Src\Equipment\Symbols\SP3DPullPitAsm\PullPitDef.cls @
1082]
04 00918fc0 4ff03c67 1053c118 000000c0 00000004 oleaut32!DispCallFunc+0x165
WARNING: Stack unwind information not available. Following frames may be
wrong.
05 0091991c 4ff03975 1053c118 17cd2808 6003002e msvbvm60+0x63c67
06 00919978 186f1fe1 1053c118 6003002e 1886a110 msvbvm60+0x63975
07 00919a70 186ea61f cccc0003 cccccccc 6003002e
IMSSymbolEntities!PerformMethodViaAutomation+0x3e1 (FPO: [Non-Fpo]) (CONV:
cdecl) [x:\middle\symbol\src\sblentities\sdmethodapi.cpp @ 286]
08 00919aec 1865627d cccc0003 cccccccc 6003002e
IMSSymbolEntities!PerformActiveXMethod+0x1bf (FPO: [Non-Fpo]) (CONV: cdecl)
[x:\middle\symbol\src\sblentities\sdmethodapi.cpp @ 350]
09 00919c6c 52353d4e 2345b9b0 cccc0003 cccccccc
IMSSymbolEntities!CSblDefinition::InvokeMethod+0x8bd (FPO: [Non-Fpo])
(CONV: stdcall) [x:\middle\symbol\src\sblentities\sbldefinition.cpp @ 4078]
0a 00919dcc 520e60b2 15d65c24 0091bff4 b6fb244d
CustomAssembly!CDMemberDescription::InvokeCMConditional+0x2de (FPO:
[Non-Fpo]) (CONV: stdcall)
[m:\commonapp\middle\entities\customassembly\businessobject\dmemberdescription.cpp
@ 1435]
=========================================

Both of these came from same minidump, by having a script that does
"!analyze -v;.echo EXCEPTION_STACK_TEXT:;kvn20"

Obviously, you will only get source and line number information if you have
the correct PDBs for your DLLs.

Appreciate any input,
Osiris

Comments

  • Scott_NooneScott_Noone Posts: 2,989
    I just stepped through the !analyze command in the debugger. The call that
    !analyze makes to DebugClient::OutputStackTrace uses a hard coded flags
    value:

    0:001> kc
    # Call Site
    00 dbgeng!DebugClient::OutputStackTrace
    01 ext!DbgClient::OutputStackTrace
    02 ext!DebugFailureAnalysis::SetContextFollowupDetails
    03 ext!DebugFailureAnalysis::AnalyzeStackEx
    04 ext!DebugFailureAnalysis::ProcessInformationCore
    05 ext!DebugFailureAnalysis::ProcessInformation
    06 ext!BcFillAnalysis
    07 ext!BcAnalyze
    08 ext!AnalyzeBugCheck
    09 ext!analyze
    0a dbgeng!ExtensionInfo::CallA
    0b dbgeng!ExtensionInfo::Call
    0c dbgeng!ExtensionInfo::CallAny
    0d dbgeng!ParseBangCmd
    0e dbgeng!ProcessCommands
    0f dbgeng!ProcessCommandsAndCatch
    10 dbgeng!Execute
    11 dbgeng!DebugClient::ExecuteWide
    12 windbg!ProcessCommand
    13 windbg!ProcessEngineCommands
    14 windbg!EngineLoop
    15 KERNEL32!BaseThreadInitThunk
    16 ntdll!RtlUserThreadStart

    HRESULT OutputStackTrace(
    [in] ULONG OutputControl,
    [in, optional] PDEBUG_STACK_FRAME Frames,
    [in] ULONG FramesSize,
    [in] ULONG Flags
    );

    mov dword ptr [rsp+20h],0Dh <<== Flags == 0xD
    mov rax,qword ptr [rcx]
    mov rax,qword ptr [rax+108h]
    call qword ptr [ext!_guard_dispatch_icall_fptr (00007ffe`7867dd20)]

    So, doesn't look like there's a way to set this as part of running !analyze
    command.

    -scott
    OSR
  • raj_rraj_r Posts: 953
    you can employ this hack debug the debugger and pass the flags

    stack prior to hack

    0:002> dx Debugger.Utility.Control.ExecuteCommand("!analyze
    -v").SkipWhile(a=>(a.Contains("STACK_TEXT") == 0)).Take(10)
    Debugger.Utility.Control.ExecuteCommand("!analyze
    -v").SkipWhile(a=>(a.Contains("STACK_TEXT") == 0)).Take(10)
    [0x0] : STACK_TEXT:
    [0x1] : WARNING: Frame IP not in any known module.
    Following frames may be wrong.
    [0x2] : 00f1dde4 100e9b5c ffffffff 00f1de04 00f1de00 0x0
    [0x3] : 00f1e60c 100ec196 10248e54 003fe9d8 0000002e
    dbgeng+0xe9b5c
    [0x4] : 00f1e620 10147ba5 003fe9d8 00000000 00f1e6b0
    dbgeng+0xec196
    [0x5] : 00f1e688 10148730 003fe9d8 00000000 bbb100a7
    dbgeng+0x147ba5
    [0x6] : 00f1e6e8 100bda7c 003fe9d8 00000000 00000000
    dbgeng+0x148730
    [0x7] : 00f1eb5c 100bdcc4 003fe9d8 00f1ef90 00000002
    dbgeng+0xbda7c
    [0x8] : 00f1ebb4 0041e08d 003fe9e0 00000001 00f1ef90
    dbgeng+0xbdcc4
    [0x9] : 00f1ef70 0041e4e7 00000000 00000000 00000040
    windbg+0x1e08d


    issuing .dbgdbg to spawn a parent debugger that debugs the debugger
    debugging your debuggee

    0:002> .dbgdbg
    Debugger spawned, connect with
    "-remote npipe:icfenable,pipe=cdb_pipe,server=XXXX"


    now in the ntsd that is spawned

    set this conditioanl breakpoint and pass the flag 1fff (look in
    dbgeng.h for explanation of values)

    bp dbgeng!DebugClient::OutputStackTrace "ed esp+14 1fff ;gc"

    0:006> bl
    0 e 5b6b1c40 0001 (0001) 0:**** dbgeng!DebugClient::OutputStackTrace "ed e
    sp+14 1fff ;gc"

    and execute g

    now all your further analyze -v will have a verbose stack



    0:002> dx Debugger.Utility.Control.ExecuteCommand("!analyze
    -v").SkipWhile(a=>(a.Contains("STACK_TEXT") == 0)).Take(10)
    Debugger.Utility.Control.ExecuteCommand("!analyze
    -v").SkipWhile(a=>(a.Contains("STACK_TEXT") == 0)).Take(10)
    [0x0] : STACK_TEXT:
    [0x1] : # Memory ChildEBP RetAddr Args to Child
    [0x2] : WARNING: Frame IP not in any known module.
    Following frames may be wrong.
    [0x3] : 00 00f1dde4 100e9b5c ffffffff
    00f1de04 00f1de00 0x0
    [0x4] : 01 828 00f1e60c 100ec196 10248e54
    003fe9d8 0000002e dbgeng+0xe9b5c
    [0x5] : 02 14 00f1e620 10147ba5 003fe9d8
    00000000 00f1e6b0 dbgeng+0xec196
    [0x6] : 03 68 00f1e688 10148730 003fe9d8
    00000000 bbb100a7 dbgeng+0x147ba5
    [0x7] : 04 60 00f1e6e8 100bda7c 003fe9d8
    00000000 00000000 dbgeng+0x148730
    [0x8] : 05 474 00f1eb5c 100bdcc4 003fe9d8
    00f1ef90 00000002 dbgeng+0xbda7c
    [0x9] : 06 58 00f1ebb4 0041e08d 003fe9e0
    00000001 00f1ef90 dbgeng+0xbdcc4






    On 10/3/17, Scott Noone <xxxxx@osr.com> <xxxxx@lists.osr.com> wrote:
    > I just stepped through the !analyze command in the debugger. The call that
    > !analyze makes to DebugClient::OutputStackTrace uses a hard coded flags
    > value:
    >
    > 0:001> kc
    > # Call Site
    > 00 dbgeng!DebugClient::OutputStackTrace
    > 01 ext!DbgClient::OutputStackTrace
    > 02 ext!DebugFailureAnalysis::SetContextFollowupDetails
    > 03 ext!DebugFailureAnalysis::AnalyzeStackEx
    > 04 ext!DebugFailureAnalysis::ProcessInformationCore
    > 05 ext!DebugFailureAnalysis::ProcessInformation
    > 06 ext!BcFillAnalysis
    > 07 ext!BcAnalyze
    > 08 ext!AnalyzeBugCheck
    > 09 ext!analyze
    > 0a dbgeng!ExtensionInfo::CallA
    > 0b dbgeng!ExtensionInfo::Call
    > 0c dbgeng!ExtensionInfo::CallAny
    > 0d dbgeng!ParseBangCmd
    > 0e dbgeng!ProcessCommands
    > 0f dbgeng!ProcessCommandsAndCatch
    > 10 dbgeng!Execute
    > 11 dbgeng!DebugClient::ExecuteWide
    > 12 windbg!ProcessCommand
    > 13 windbg!ProcessEngineCommands
    > 14 windbg!EngineLoop
    > 15 KERNEL32!BaseThreadInitThunk
    > 16 ntdll!RtlUserThreadStart
    >
    > HRESULT OutputStackTrace(
    > [in] ULONG OutputControl,
    > [in, optional] PDEBUG_STACK_FRAME Frames,
    > [in] ULONG FramesSize,
    > [in] ULONG Flags
    > );
    >
    > mov dword ptr [rsp+20h],0Dh <<== Flags == 0xD
    > mov rax,qword ptr [rcx]
    > mov rax,qword ptr [rax+108h]
    > call qword ptr [ext!_guard_dispatch_icall_fptr (00007ffe`7867dd20)]
    >
    > So, doesn't look like there's a way to set this as part of running !analyze
    >
    > command.
    >
    > -scott
    > OSR
    >
    >
    > ---
    > WINDBG is sponsored by OSR
    >
    > OSR is hiring!! Info at http://www.osr.com/careers
    >
    >
    > MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
    > drivers!
    > Details at <http://www.osr.com/seminars>;
    >
    > To unsubscribe, visit the List Server section of OSR Online at
    > <http://www.osronline.com/page.cfm?name=ListServer>;
    >
  • raj_rraj_r Posts: 953
    sorry hit enter too soon so following up

    if you are issuing a kvn20 after analyze -v wouldn't that print the
    windbg's stack in the top rather than the dumps exception stack ??

    iirc !analyze -v detects that part and skips all the dump analysis
    logic stack and only prints the exception stack



    On 10/4/17, raj r <xxxxx@gmail.com> wrote:
    > you can employ this hack debug the debugger and pass the flags
    >
    > stack prior to hack
    >
    > 0:002> dx Debugger.Utility.Control.ExecuteCommand("!analyze
    > -v").SkipWhile(a=>(a.Contains("STACK_TEXT") == 0)).Take(10)
    > Debugger.Utility.Control.ExecuteCommand("!analyze
    > -v").SkipWhile(a=>(a.Contains("STACK_TEXT") == 0)).Take(10)
    > [0x0] : STACK_TEXT:
    > [0x1] : WARNING: Frame IP not in any known module.
    > Following frames may be wrong.
    > [0x2] : 00f1dde4 100e9b5c ffffffff 00f1de04 00f1de00 0x0
    > [0x3] : 00f1e60c 100ec196 10248e54 003fe9d8 0000002e
    > dbgeng+0xe9b5c
    > [0x4] : 00f1e620 10147ba5 003fe9d8 00000000 00f1e6b0
    > dbgeng+0xec196
    > [0x5] : 00f1e688 10148730 003fe9d8 00000000 bbb100a7
    > dbgeng+0x147ba5
    > [0x6] : 00f1e6e8 100bda7c 003fe9d8 00000000 00000000
    > dbgeng+0x148730
    > [0x7] : 00f1eb5c 100bdcc4 003fe9d8 00f1ef90 00000002
    > dbgeng+0xbda7c
    > [0x8] : 00f1ebb4 0041e08d 003fe9e0 00000001 00f1ef90
    > dbgeng+0xbdcc4
    > [0x9] : 00f1ef70 0041e4e7 00000000 00000000 00000040
    > windbg+0x1e08d
    >
    >
    > issuing .dbgdbg to spawn a parent debugger that debugs the debugger
    > debugging your debuggee
    >
    > 0:002> .dbgdbg
    > Debugger spawned, connect with
    > "-remote npipe:icfenable,pipe=cdb_pipe,server=XXXX"
    >
    >
    > now in the ntsd that is spawned
    >
    > set this conditioanl breakpoint and pass the flag 1fff (look in
    > dbgeng.h for explanation of values)
    >
    > bp dbgeng!DebugClient::OutputStackTrace "ed esp+14 1fff ;gc"
    >
    > 0:006> bl
    > 0 e 5b6b1c40 0001 (0001) 0:**** dbgeng!DebugClient::OutputStackTrace
    > "ed e
    > sp+14 1fff ;gc"
    >
    > and execute g
    >
    > now all your further analyze -v will have a verbose stack
    >
    >
    >
    > 0:002> dx Debugger.Utility.Control.ExecuteCommand("!analyze
    > -v").SkipWhile(a=>(a.Contains("STACK_TEXT") == 0)).Take(10)
    > Debugger.Utility.Control.ExecuteCommand("!analyze
    > -v").SkipWhile(a=>(a.Contains("STACK_TEXT") == 0)).Take(10)
    > [0x0] : STACK_TEXT:
    > [0x1] : # Memory ChildEBP RetAddr Args to Child
    > [0x2] : WARNING: Frame IP not in any known module.
    > Following frames may be wrong.
    > [0x3] : 00 00f1dde4 100e9b5c ffffffff
    > 00f1de04 00f1de00 0x0
    > [0x4] : 01 828 00f1e60c 100ec196 10248e54
    > 003fe9d8 0000002e dbgeng+0xe9b5c
    > [0x5] : 02 14 00f1e620 10147ba5 003fe9d8
    > 00000000 00f1e6b0 dbgeng+0xec196
    > [0x6] : 03 68 00f1e688 10148730 003fe9d8
    > 00000000 bbb100a7 dbgeng+0x147ba5
    > [0x7] : 04 60 00f1e6e8 100bda7c 003fe9d8
    > 00000000 00000000 dbgeng+0x148730
    > [0x8] : 05 474 00f1eb5c 100bdcc4 003fe9d8
    > 00f1ef90 00000002 dbgeng+0xbda7c
    > [0x9] : 06 58 00f1ebb4 0041e08d 003fe9e0
    > 00000001 00f1ef90 dbgeng+0xbdcc4
    >
    >
    >
    >
    >
    >
    > On 10/3/17, Scott Noone <xxxxx@osr.com> <xxxxx@lists.osr.com> wrote:
    >> I just stepped through the !analyze command in the debugger. The call
    >> that
    >> !analyze makes to DebugClient::OutputStackTrace uses a hard coded flags
    >> value:
    >>
    >> 0:001> kc
    >> # Call Site
    >> 00 dbgeng!DebugClient::OutputStackTrace
    >> 01 ext!DbgClient::OutputStackTrace
    >> 02 ext!DebugFailureAnalysis::SetContextFollowupDetails
    >> 03 ext!DebugFailureAnalysis::AnalyzeStackEx
    >> 04 ext!DebugFailureAnalysis::ProcessInformationCore
    >> 05 ext!DebugFailureAnalysis::ProcessInformation
    >> 06 ext!BcFillAnalysis
    >> 07 ext!BcAnalyze
    >> 08 ext!AnalyzeBugCheck
    >> 09 ext!analyze
    >> 0a dbgeng!ExtensionInfo::CallA
    >> 0b dbgeng!ExtensionInfo::Call
    >> 0c dbgeng!ExtensionInfo::CallAny
    >> 0d dbgeng!ParseBangCmd
    >> 0e dbgeng!ProcessCommands
    >> 0f dbgeng!ProcessCommandsAndCatch
    >> 10 dbgeng!Execute
    >> 11 dbgeng!DebugClient::ExecuteWide
    >> 12 windbg!ProcessCommand
    >> 13 windbg!ProcessEngineCommands
    >> 14 windbg!EngineLoop
    >> 15 KERNEL32!BaseThreadInitThunk
    >> 16 ntdll!RtlUserThreadStart
    >>
    >> HRESULT OutputStackTrace(
    >> [in] ULONG OutputControl,
    >> [in, optional] PDEBUG_STACK_FRAME Frames,
    >> [in] ULONG FramesSize,
    >> [in] ULONG Flags
    >> );
    >>
    >> mov dword ptr [rsp+20h],0Dh <<== Flags == 0xD
    >> mov rax,qword ptr [rcx]
    >> mov rax,qword ptr [rax+108h]
    >> call qword ptr [ext!_guard_dispatch_icall_fptr
    >> (00007ffe`7867dd20)]
    >>
    >> So, doesn't look like there's a way to set this as part of running
    >> !analyze
    >>
    >> command.
    >>
    >> -scott
    >> OSR
    >>
    >>
    >> ---
    >> WINDBG is sponsored by OSR
    >>
    >> OSR is hiring!! Info at http://www.osr.com/careers
    >>
    >>
    >> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
    >> software
    >> drivers!
    >> Details at <http://www.osr.com/seminars>;
    >>
    >> To unsubscribe, visit the List Server section of OSR Online at
    >> <http://www.osronline.com/page.cfm?name=ListServer>;
    >>
    >
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!