Windbg, !heap output to .foreach - windbg

Doing some debugging in windbg, and I'd like to be able to go through each heap allocation of a given size and then do some analysis on that (just dd for now). Problem is !heap doesnt throw out stuff very cleanly.
I know I can skip the first X or every Y tokens with .foreach flags, but can't seem to get this to work.
Basically looking to do something like this:
.foreach (ADDR {!heap -flt s <size of allocation>}) {dd ADDR}
Is there a way, short of outputing to a file, doing some awking and then feeding it back in?

I was looking for the answer on the same question, and here is the easiest way I found:
Run
!heap -flt s [your alloc size]
Ctrl+A, Copy and past in some text file, for example, c:\temp\test.txt.
Delete all unnecessary rows from the file, so it looks like:
0000000011af12e0 0400 0000 [00] 0000000011af12f0 03ff0 - (busy)
0000000011af52e0 0400 0400 [00] 0000000011af52f0 03ff0 - (busy)
0000000011af92e0 0400 0400 [00] 0000000011af92f0 03ff0 - (busy)
0000000011afd2e0 0400 0400 [00] 0000000011afd2f0 03ff0 - (busy)....
Then run in WinDbg command like:
.logopen /t c:\temp\Output.txt
to save your further output to some file, as you are going to have a loooong one.
And finally, run your foreach with file as parameter:
.foreach /pS4 /ps3 /f ( obj "c:\temp\test.txt" ) { !heap -p -a obj }
Hooray! it works :)

AFAIK I don't think the !heap command has a short option to use in the .foreach. You could probably try using .shell command to grep the output
HTH

Related

How to prevent the output truncated if the rows of output from the windbg to large?

If the output rows from the windbg command to large ,such as 100k rows, finally the windbg just display thousands of the rows, and most of them would be truncated , so my question is how to prevent the output truncated , or write all of the rows from the output to a local file to keep all of the output rows? the "write Windows text to file" wouldn't helpful.
Not sure if it would help, but .logopen and .logclose commands might be helpful in this case (respectively open and close a log file which keeps a copy of the events and commands from the Debugger Command window).
See also Keeping a Log File in WinDbg.
sometimes simply piping works especially when running cdb and quitting after executing just one command
cdb -c "tc 100;q" calc >> foo.txt
you should have 100 calls lets check
grep -c !.*: foo.txt
256
lets check how many sysenter were done and what were the index of the syscalls
grep sysenter -B 4 foo.txt | grep eax | awk "{print $1}"
eax=000000ea
eax=0000014d
eax=000000fb
we can use the output when the commands run for an infinite amount of time
without having file locked issues
like this
if .logopen .logclose isnt an option
Try to open additional command window with Ctrl+N and execute the long outputed command within it

sed command is not working properly

I'm trying to replace the word in shell script with sed -e command but its not replacing , please help on that, i have tried the below
we have separate file in /data/docs/config.log, in that file there is a word ?account for example ,
username acc, passsword acc, ?account.name
this ?account word needs to be replaced with word 'GLOBAL' using sed -e command ,
reacc = GLOBAL
sed -e "s/?account/$reacc/g" /data/docs/config.log > /data/docs/newconfig.log
but here the file newconfig.log has created with 0 size , no output written to the file , its not replacing its an empty file,
the output should be username acc, passsword acc, GLOBAL.name in newconfig.log
Being the only person who can reproduce the problem, you are pretty much on your own. There are plenty of things you can do to analyze the problem, though.
Double-check the shell. Don't have blind faith in #!/bin/sh. In cygwin for example, /bin/sh is an alias for bash. Verify with: echo $SHELL
Check permissions and file system. Do you have rights to write to the output file? Is the disk full? Does cat /data/docs/config.log > /data/docs/newconfig.log work? Test again in a different folder.
Double-check the output file. Is it really empty, or is the file system just slow with updating the file size? Is sed really finished? Test without output redirection; see if the output is dumped to stdout.
Test with a small file; one or two lines is enough.
If even that does not work, then test sed itself. Who knows, maybe you have a weird alias that hides the real sed. The most trivial filter is sed -e '', which should simply echo every line you type (just like cat without parameters). Does that work? Then try some simple patterns.
Systematically iterate between test cases that succeed and test case that fail, until you have found the breaking point. Doing so, you should be able to find the cause. Sorry, that's all I can do for you right now.
Remove spaces around =. Try after making
reacc=GLOBAL

Can WER produce dumps similar to .dump /ma

My impression is that dumps produced my winDbg
.dump /ma
contains more than just a full dump
Configuring WER explains DumpType 0: Custom dump
CustomDumpFlags bitwise combination of MINIDUMP_TYPE
But what hex value gives dumps similar dumps as .dump /ma
All the bit combinations are a bit overwhelming for me.
WinDbg's .dump /ma saves the dump with these flags:
Flags 41826
0002 MiniDumpWithFullMemory
0004 MiniDumpWithHandleData
0020 MiniDumpWithUnloadedModules
0800 MiniDumpWithFullMemoryInfo
1000 MiniDumpWithThreadInfo
40000 MiniDumpWithTokenInformation
You can verify this by opening the crash dump file in WinDbg and issuing the (undocumented) .dumpdebug command.
So you will want to specify 41826 (hex) or 268326 (decimal) in the CustomDumpFlags registry key.

Why isn't this command taking the diff of two directories?

I am asked to diff two directories using Perl but I think something is wrong with my command,
$diff = system("sudo diff -r '/Volumes/$vol1' '/Volumes/$vol2\\ 1/' >> $diff.txt");
It doesn't display and output. Can someone help me with this? Thanks!
It seems that you want to store all differences in a string.
If this is the case, the command in the question is not going to work for a few reasons:
It's hard to tell whether it's intended or not, but the $diff variable is being used to set the filename storing the differences. Perhaps this should be diff.txt, not $diff.txt
The result of the diff command is saved in $diff.txt. It doesn't display anything in STDOUT. This can be remedied by omitting the >> $diff.txt part. If it also needs to be stored in file, consider the tee command:
sudo diff -r dir1/ dir2/ | tee diff.txt
When a system call is assigned to a variable, it will return 0 upon success. To quote the documentation:
The return value is the exit status of the program as returned by the wait call.
This means that $diff won't store the differences, but the command exit status. A more sensible approach would be to use backticks. Doing this will allow $diff to store whatever is output to STDOUT by the command:
my $diff = `sudo diff -r dir1/ dir2/ | tee diff.txt`; # Not $diff.txt
Is it a must to use the sudo command? Avoid using it if even remotely possible:
my $diff = `diff -r dir1/ dir2/ | tee diff.txt`; # Not $diff.txt
A final recommendation
Let a good CPAN module take care of this task, as backtick calls can only go so far. Some have already been suggested here; it may be well worth a look.
Is sudo diff being prompted for a password?
If possible, take out the sudo from the invocation of diff, and run your script with sudo.
"It doesn't display and output." -- this is becuase you are saving the differences to a file, and then (presumably) not doing anything with that resulting file.
However, I expect "diff two directories using Perl" does not mean "use system() to do it in the shell and then capture the results". Have you considered doing this in the language itself? For example, see Text::Diff. For more nuanced control over what constitutes a "difference", you can simply read in each file and craft your own algorithm to perform the comparisons and compile the similarities and differences.
You might want to check out Test::Differences for a more flexible diff implementation.

Unable to use SED to edit files fast

The file is initially
$cat so/app.yaml
application: SO
...
I run the following command. I get an empty file.
$sed s/SO/so/ so/app.yaml > so/app.yaml
$cat so/app.yaml
$
How can you use SED to edit the file and not giving me an empty file?
$ sed -i -e's/SO/so/' so/app.yaml
The -i means in-place.
The > used in piping will open the output file when the pipes are all set up, i.e. before command execution. Thus, the input file is truncated prior to sed executing. This is a problem with all shell redirection, not just with sed.
Sheldon Young's answer shows how to use in-place editing.
You are using the wrong tool for the job. sed is a stream editor (that's why it's called sed), so it's for in-flight editing of streams in a pipe. ed OTOH is a file editor, which can do everything sed can do, except it works on files instead of streams. (Actually, it's the other way round: ed is the original utility and sed is a clone that avoids having to create temporary files for streams.)
ed works very much like sed (because sed is just a clone), but with one important difference: you can move around in files, but you can't move around in streams. So, all commands in ed take an address parameter that tells ed, where in the file to apply the command. In your case, you want to apply the command everywhere in the file, so the address parameter is just , because a,b means "from line a to line b" and the default for a is 1 (beginning-of-file) and the default for b is $ (end-of-file), so leaving them both out means "from beginning-of-file to end-of-file". Then comes the s (for substitute) and the rest looks much like sed.
So, your sed command s/SO/so/ turns into the ed command ,s/SO/so/.
And, again because ed is a file editor, and more precisely, an interactive file editor, we also need to write (w) the file and quit (q) the editor.
This is how it looks in its entirety:
ed -- so/app.yaml <<-HERE
,s/SO/so/
w
q
HERE
See also my answer to a similar question.
What happens in your case, is that executing a pipeline is a two-stage process: first construct the pipeline, then run it. > means "open the file, truncate it, and connect it to filedescriptor 1 (stdout)". Only then is the pipe actually run, i.e. sed is executed, but at this time, the file has already been truncated.
Some versions of sed also have a -i parameter for in-place editing of files, that makes sed behave a little more like ed, but using that is not advisable: first of all, it doesn't support all the features of ed, but more importantly, it is a non-standardized proprietary extension of GNU sed that doesn't work on many non-GNU systems. It's been a while since I used a non-GNU system, but last I used one, neither Solaris nor OpenBSD nor HP-UX nor IBM AIX sed supported the -i parameter.
I believe that redirecting output into the same file you are editing is causing your problem.
You need redirect standard output to some temporary file and when sed is done overwrite the original file by the temporary one.