Is there a way to iterate through all frames in windbg? (or to run dv for each stack frame)
For example: ~*e !mk -cc will iterate through all threads and call !mk -cc
What I want is basically:
For each thread: switch to thread:
~0s
For each frame in that thread:
.frame 00
dv
Just wondering if there is a way to automate this?
Currently I am able to generate a script to do:
~0s
.frame 00
dv
.frame 01
dv
.frame 02
...
But this is a multistep process, and I want to automate it all.
You can use the ~e command to execute a command per-thread. Then you can use !for_each_frame to execute a command for each call frame. For example:
~*e .echo Thread Frames and Locals:; !for_each_frame dv
The .echo command is included simply to mark where one thread ends and the next begins.
Related
I am analyzing a lot of crash dumps with Pykd and I would like to get the process ID (PID) from the crash dump.
In WinDbg, I'd use the command | and use my brain to figure it out. Some time later, I'd come up with a command like
.foreach /pS 3 /ps 999 ( pid {|}) {.echo ${pid}}
which extracts the process ID for me.
Just a little bit smarter and I'd use a pseudo register instead:
.printf "%p", $tpid
How would I use PyKD to get the process ID from a user mode crash dump file (.dmp)?
Of course I can always do a pykd.dbgCommand(), but I'd like to use a more robust built-in way.
I have tried
pykd.getCurrentProcessId() but it returns 0.
pykd.reg("tpid") but it says "Invalid register name"
0:000> dx Debugger.Sessions.First().Processes
Debugger.Sessions.First().Processes
[0x294c] : wait.exe
0:000> .shell -ci ".echo " type f:\src\wait\pid.py
from pykd import *
print(hex(expr("#$tpid"))).shell: Process exited
0:000> !py f:\src\wait\pid.py
0x294c
0:000> |
. 0 id: 294c examine name: F:\src\wait\wait.exe
0:000>
The pseudo reguster idea was not that bad:
pykd.expr("$tpid")
gives the process ID as a number. Format it as hexadecimal if it's needed in the same format as |.
try to use pykd.getProcessSystemID
https://githomelab.ru/pykd/pykd/-/wikis/API%20Reference#function-getprocesssystemid
getCurrentProcessId has sense if you are debugging several processes and need to switch they contexts ( like | command )
I'm using windbg like the following:
bp XXX!XXXX::Init ".printf \"init tid=%d, XXX=0x%x\", ##c++(#$teb->ClientId.UniqueThread), #rdx; .echo; g;"
Is there a way to avoid the \" and the one-liner here? I'm trying to be more elegant.
avoid .printf as much as you can it has certain limitation on format string length
resume from conditional breakpoint with gc (go from conditional ) instead of g (go)as you do
one alternate way to accomplish what you are doing could be like
0:000> bp 00007ff8`854ec941 "dx #$teb->ClientId.UniqueThread;r #rdx;gc"
0:000> pc
#$teb->ClientId.UniqueThread : 0x23cc [Type: void *]
rdx=0000020996d22868
00007ff8`854ec941 call fastprox!CWbemSvcWrapper::XWbemServices::WrapBSTR
How do I get the q script output to be displayed in QPad64's (QInsightPad's) output window. I am presently starting q and QPad 64 with the following .bat file :
set QHOME=C:\Q\q
set QINIT=C:\code\server.q
set PATH=%PATH%;%QHOME%;%QHOME%\w32
START C:\QInsightPad-2.2_FREE-x64\qpad64.exe
Result: q opens in cmd window, but all output from scipts run in Qpad show up there ( in cmd ) instead of in Qpad's output window. How do I fix this ?
Qpad isn't really designed to be used like that. You could redirect the stdout and read it in to view in qpad.
\1 qproc.log
Your scripts could then have output to the log as certain things are done like so:
1"tables_loaded"
// \n for new line
1"\nfuncs_loaded"
read0 `:qproc.log
"tables_loaded"
"funcs_loaded"
I'm trying to do automatic detect chapter with blackdetect with ffmpeg.
When I use blackdetect I get result but what is the result? Its not frames? Also. Is it possible to do a script/bat-file (for windows 10, powershell or cmd) to convert the result to a "mkv xml-file" so It can be imported with mkvtoolnix?
ffmpeg -i "movie.mp4" -vf blackdetect=d=0.232:pix_th=0.1 -an -f null - 2>&1 | findstr black_duration > output.txt
result:
black_start:2457.04 black_end:2460.04 black_duration:3
black_start:3149.46 black_end:3152.88 black_duration:3.41667
black_start:3265.62 black_end:3268.83 black_duration:3.20833
black_start:3381.42 black_end:3381.92 black_duration:0.5
black_start:3386.88 black_end:3387.38 black_duration:0.5
black_start:3390.83 black_end:3391.33 black_duration:0.5
black_start:3824.29 black_end:3824.58 black_duration:0.291667
black_start:3832.71 black_end:3833.08 black_duration:0.375
black_start:3916.29 black_end:3920.29 black_duration:4
Please see the documentation on this function here. Specifically this line:
Output lines contains the time for the start, end and duration of the detected black interval expressed in seconds.
If you read further down the page you will see another function blackframe which does a similar thing but outputs the frame number rather than seconds.
If the mkvtoolnix xml file has a chapter definition facility you will be able to create a script that takes the ffmpeg output and dumps it into the correct format in any language of your choice.
I'm trying to create a script that runs thread specific commands to output information for each thread into a separate file. Is there a way to get thread ID that I can run in the command similar to this: ~${threadId} e!clrstack.
Ultimately here is what I'm shooting for:
.foreach(tid {!threads})
{
.logopen c:\temp\${tid}.txt;
~${tid}e !dumpstack;
~${tid}e !clrstack;
~${tid}e !dso;
~${tid}e kb 200;
.logclose
}
Here is what I got so far:
.foreach /pS 1 /pS2 /pS3 /pS4 /pS5 /ps 3 (l {!runaway})
{
.printf "${l}\n";
}
The issue with this that it has the value I'm looking for with OSID. Looks like this <wantedID>:<OSID>.
How can I separate the part I need or is there an easier way to get thread ID from a memory dump?
I'm a bit confused about the use of .foreach together with ~e, because that's somehow duplicate (just the fact that you're limiting ~e to one thread doesn't result in a nested loop).
Is the command
~*e .logopen /t d:\debug\log.txt; !dumpstack; !clrstack; !dso; kb 200; .logclose
sufficient for you? The log file name will not have the thread ID.
Regarding your skip tokens of .foreach, I think you can only use /pS and /ps once. Your statement is equivalent to
.foreach /pS 5 /ps 3 (l {!runaway}) { ... }
If the thread ID really matters
It seems that the OS thread IDs are really important.
As using .foreach directly on any command like !threads, ~ or !runaway seems not flexible and reliable enough, I propose to use .shell find to get at least some consistency in output.
I'll use !teb to get the thread ID, because it is separated by a space and therefore the output of .shell find can be used as input for .foreach.
The complete command I come up with:
~*e .foreach /pS 3 /ps 20 (tid {.shell -ci "!teb" find "ClientId"}) { .logopen d:\debug\logs\log${tid}.txt; !dumpstack; !clrstack; !dso; kb 200; .logclose}
Using pykd as an extension
Using PyKd - Python extension for WinDbg, the result can be achieved like this:
Create a file tid.py, put it next to the pykd.pyd extension and give it the following content:
from pykd import *
threads = getProcessThreads()
for t in threads:
print(hex(ptrPtr(t+0x24))[2:-1])
getProcessThreads() gives you the addresses of the TEBs. At offset 0x24 you can find the thread ID. ptrPtr() reads a memory address, hex() is self-explaining, [2: removes the 0x head and :-1] removes the trailing L (don't ask me why it has a trailing L).
In WinDbg
.load pykd.pyd
!py tid.py; *** Gives one thread ID per line, nice for .foreach
.foreach (tid {!py tid.py}) { .logopen d:\debug\logs\log_${tid}.txt; ~~[${tid}]s; !dumpstack; !clrstack; !dso; kb 200; .logclose}