Reputation: 17565
In this question, I've tried to get a Windbg script working, but maybe I could solve my issue using PYKD anyway. My problem is the following:
I Launch the command ~* k
, and I get following response (as in the mentioned question, I like to emphasize the hyperlinks, hence the image instead of simple text):
I would like to simulate a mouse-click on the line, containing CServiceModule::Run
. When I hover over the corresponding hyperlink 02
, I see following Windbg command:
dx Debugger.Sessions[0].Processes[4416].Threads[4436].Stack.Frames[2].SwitchTo();dv /t /v
Until now, I've tried re-creating this command myself, but now I realise that, if I can just get that command from the response itself, my problem is solved.
As far as I know, the PYKD DbgCommand()
only gives the text part of the response (so, not the information under the hyperlink).
Is there any way to get this hyperlink from the DbgCommand()
command?
Upvotes: 1
Views: 264
Reputation: 606
If you know frame number, you can switch frame with pykd.setFrame command. But you should remember, pykd does not support inline function frame. So a number of a frame can be different from windbg output. You can disable inline function with command 'inline 0'
The pykd script can look like that:
frames = getStack()
for frameNumber in xrange( len(frames) ):
if "ServiceModule::Run" in findSymbol(frames[frameNumber].ip):
setFrame(frameNumber)
dprintln("frame switched")
Extra edit for readability
As mentioned in following comment, an issue has been raised to PYKD, named "dbgCommand doesnt support DML command output": in other words: currently DML is not yet supported by PYKD DbgCommand()
.
Upvotes: 0
Reputation: 9007
result of kb
0:000> kb
# ChildEBP RetAddr Args to Child
00 000bf618 76fa0e00 7ffdf000 7ffda000 76ff714c ntdll!LdrpDoDebuggerBreak+0x2c
01 000bf778 76f860a7 000bf7ec 76f20000 76c245cb ntdll!LdrpInitializeProcess+0x11a9
02 000bf7c8 76f83659 000bf7ec 76f20000 00000000 ntdll!_LdrpInitialize+0x78
03 000bf7d8 00000000 000bf7ec 76f20000 00000000 ntdll!LdrInitializeThunk+0x10
when i click on the dml link 02 i get
0:000> dx Debugger.Sessions[0].Processes[2684].Threads[3736].Stack.Frames[2].SwitchTo();dv /t /v
Debugger.Sessions[0].Processes[2684].Threads[3736].Stack.Frames[2].SwitchTo()
Unable to enumerate locals, Win32 error 0n87
Private symbols (symbols.pri) are required for locals.
Type ".hh dbgerr005" for details.
as i emphasized in my earlier answers the same can be achieved by
dx @$curstack.Frames[2].SwitchTo();dv /v /t
typing this is exactly equivalent to clicking the 02 link
0:000> dx @$curstack.Frames[2].SwitchTo();dv /v /t
@$curstack.Frames[2].SwitchTo()
Unable to enumerate locals, Win32 error 0n87
Private symbols (symbols.pri) are required for locals.
Type ".hh dbgerr005" for details.
this will be meaningful only if you are debugging with source available here is an example of stack and frame 2 with source
i am using kbL to hide my src line info on the stacktrace and then clicked frame no 2 DML link and then type the command as you can see it print the same info like you click
now if you say i need to see the "RUN" string not use the number 2 you should write a script to text parse each line as i showed you in my earlier answer to the thread you linked
0:000> kbL
# ChildEBP RetAddr Args to Child
00 (Inline) -------- -------- -------- -------- mfctest!CThreadLocal<_AFX_THREAD_STATE>::GetData
01 0025fe48 012fbc2f 015bf7a8 012fd4bd ffffffff mfctest!AfxGetThreadState
02 0025fe64 0151979e 00000000 015c6360 7ffdb000 mfctest!CWinThread::Run+0xf
03 0025fe7c 014c17d5 012e0000 00000000 00322d3e mfctest!AfxWinMain+0x93
04 (Inline) -------- -------- -------- -------- mfctest!invoke_main+0x1a
05 0025fec8 76e8ed6c 7ffdb000 0025ff14 76f837eb mfctest!__scrt_common_main_seh+0xf8
06 0025fed4 76f837eb 7ffdb000 76b22d01 00000000 kernel32!BaseThreadInitThunk+0xe
07 0025ff14 76f837be 014c1892 7ffdb000 00000000 ntdll!__RtlUserThreadStart+0x70
08 0025ff2c 00000000 014c1892 7ffdb000 00000000 ntdll!_RtlUserThreadStart+0x1b
clicking link with number 2
0:000> dx Debugger.Sessions[0].Processes[620].Threads[2228].Stack.Frames[2].SwitchTo();dv /t /v
Debugger.Sessions[0].Processes[620].Threads[2228].Stack.Frames[2].SwitchTo()
@ebx class CWinThread * this = 0x015bf7a8 {h=0xfffffffe proc={...}}
<unavailable> long lIdleCount = <value unavailable>
@eax class _AFX_THREAD_STATE * pState = 0x0153b820
<unavailable> int bIdle = <value unavailable>
using command (NOT CLICKING BUT TYPING THIS )
0:000> dx @$curstack.Frames[2].SwitchTo();dv /v /t
@$curstack.Frames[2].SwitchTo()
@ebx class CWinThread * this = 0x015bf7a8 {h=0xfffffffe proc={...}}
<unavailable> long lIdleCount = <value unavailable>
@eax class _AFX_THREAD_STATE * pState = 0x0153b820
<unavailable> int bIdle = <value unavailable>
Upvotes: 0