Analysing crash dump in windbg - debugging

I am using a third party closed source API which throws an exception stating that "all named pipes are busy".
I would like to debug this further (rather than just stepping through) so I can actually learn what is happening under the covers.
I have taken a dump of this process using WinDbg. What commands should I now use to analyse this dump?
Thanks

You could start doing as follows to get an overview of the exception:
!analyze -v
Now you could load the exception context record:
.ecxr
And now... just take a look at the stack, registers, threads,...
kb ;will show you the stack trace of the crash.
dv ;local variables
Depending on the clues you get, you should follow a different direction. If you want a quick reference to WinDbg I'd recommend you this link.
I hope you find some of this commands and info useful.

In postmortem debugging with Windbg, it can be useful to run some general diagnostic commands before deciding where to dig deeper. These should be your first steps:
.logopen <filename> (See also .logappend)
.lastevent See why the process halted and on what thread
u List disassembly near $eip on offending thread
~ Status of all threads
Kb List callstack, including parameters
.logclose
These commands typically give you an overview of what happened so you can dig further. In the case of dealing with libraries where you don't have source, sending the resulting log file to the vendor along with the build # of the binary library should be sufficient for them to trace it to a known issue if there is one.

This generally happens when a client calls CreateFile for an existing pipe and all the existing pipe instances are busy. At this point CreateFile returns an error and the error code is ERROR_PIPE_BUSY. The right thing at this point is to call WaitNamedPipe with a timeout value to wait for a pipe instance to become available.
The problem generally happens when more than one client tries to connect to the named pipe at the same time.

I assume that the 3rd party dll is native (Otherwise, just use Reflector)
Before using WinDbg to analyze the dump, try using Process-Monitor (SysInternals, freeware) to monitor your process's activity. if it fails because of a file system related issue, you can see exactly what caused the problem and what exactly it tried to do before failing.
If Process-Monitor wasn't enough than you can try and debug your process. but in order to see some meaningful information about the 3rd party dll you'll need it's pdb's.
After setting the correct debug symbols, you can view the call stack by using the k command or one of it's variations (again, I assume you're talking about native code). if your process is indeed crashing because of this dll than examine the parameters that you pass to it's function to ensure that the problem is not on your side. I guess that further down the call stack, you reach some Win32 API - examine the parameters that the dll's function is passing, trying to see if something "smells". If you have the dll's private symbol you can examine it's function's local variables as well (dv) which can give you some more information.
I hope I gave you a good starting point.

This is an excellent resource for using WinDbg to analyze crashes that may be of some use: http://www.networkworld.com/article/3100370/windows/how-to-solve-windows-10-crashes-in-less-than-a-minute.html
The article is for Windows 10, but it contains links to similar information for earlier versions of Windows.

Related

How to extract stack traces from minidumps?

I've got a whole bunch of minidumps which were recorded during the runtime of an application through MiniDumpWriteDump. The minidumps were created on a machine with a different OS version than my development machine.
Now I'm trying to write a program to extract stack traces from the minidumps, using dbghelp.dll. I'm walking the MINIDUMP_MODULE_LIST and call SymLoadModule64, but this fails to download the pdbs (kernel32 etc.) from the public symbol server. If I add "C:\Windows\System32" to the symbol path it finds the dlls and downloads the symbols, but of course they don't match the dlls from the minidump, so the results are useless.
So how do I tell dbghelp.dll to download and use the proper pdbs?
[edit]
I forgot to state that SymLoadModule64 only takes a filename and no version/checksum information, so obviously with SymLoadModule64 alone it's impossible for dbghelp to figure out which pdb to download.
The information is actually available in the MINIDUMP_MODULE_LIST but I don't know how to pass it back to the dbghelp API.
There is SymLoadModuleEx which takes additional parameters, but I have no idea if that's what I need or what I should pass for the additional parameters.
[edit]
No luck so far, though I've noticed there's also dbgeng.dll distributed together with dbghelp.dll in the debugging SDK. MSDN looks quite well documented and says it's the same engine as windbg uses. Maybe I can use that to extract the stack traces.
If anyone can point me to some introduction to using dbgeng.dll to process minidumps that would probably help too, as the MSDN documents only the individual components but not how they work together.
Just in case anyone else wants to automate extracting stack traces from dumps, here's what I ended up doing:
Like I mentioned in the update it's possible to use dbgeng.dll instead of dbghelp.dll, which seems to be the same engine WinDbg uses. After some trial and error here's how to get a good stack trace with the same symbol loading mechanism as WinDbg.
call DebugCreate to get an instance of the debug engine
query for IDebugClient4, IDebugControl4, IDebugSymbols3
use IDebugSymbols3.SetSymbolOptions to configure how symbols are loaded (see MSDN for the options WinDbg uses)
use IDebugSymbols3.SetSymbolPath to set the symbol path like you would do in WinDbg
use IDebugClient4.OpenDumpFileWide to open the dump
use IDebugControl4.WaitForEvent to wait until the dump is loaded
use IDebugSymbols3.SetScopeFromStoredEvent to select the exception stored in the dump
use IDebugControl4.GetStackTrace to fetch the last few stack frames
use IDebugClient4.SetOutputCallbacks to register a listener receiving the decoded stack trace
use IDebugControl4.OutputStackTrace to process the stack frames
use IDebugClient4.SetOutputCallbacks to unregister the callback
release the interfaces
The call to WaitForEvent seems to be important because without it the following calls fail to extract the stack trace.
Also there still seems to be some memory leak in there, can't tell if it's me not cleaning up properly or something internal to dbgeng.dll, but I can just restart the process every 20 dumps or so, so I didn't investigate more.
An easy way to automate the analysis of multiple minidump files is to use the scripts written by John Robbins in his article "Automating Analyzing Tons Of Minidump Files With WinDBG And PowerShell" (you can grab the code on GitHub).
This is easy to tweak to have it perform whatever WinDbg commands you'd like it to, if the default setup is not sufficient.

No "walkers" in mdb (Solaris modular debugger)

Every now and then I use the mdb debugger to examine core dumps on Solaris. One nice article that I looked at to get up to speed on the possibilities with mdb is http://blogs.oracle.com/ace/entry/mdb_an_introduction_drilling_sigsegv where the author performs a step-by-step examination of a SIGSEGV crash. In the article the author uses "walkers" which is a kind of add-on to mdb that can perform specific tasks.
My problem is that I don't have any of those walkers in my mdb. By using the "::walkers" command, all walkers available can be listed and my list is empty. So the question is, how can I install/add/load walkers such as the ones used in the above article? I don't really know where they are supposed to be loaded from, if you have to download and add them from somewhere or if it's a configuration step when installing Solaris?
mdb automatically loads walkers and dcmds appropriate for what you're debugging, usually from /usr/lib/mdb and similar directories (see mdb(1) for details). If you just run "mdb" by itself, you'll get almost nothing. If you run "mdb" on a userland process or core dump (e.g., "mdb $$"), you'll get walkers and dcmds appropriate for userland debugging. If you run "mdb" on the kernel (e.g., "mdb -k"), you'll get walkers and dcmds for kernel debugging.

Debugging a minidump in Visual Studio where the call stack is null

I have a customer who is getting a 100% reproduceable crash that I can't replicate in my program compiled in Visual Studio 2005. I sent them a debug build of my program and kept all the PDB and DLL files handy. They sent me the minidump file, but when I open it I get:
"Unhandled exception at 0x00000000 in MiniDump.dmp: 0xC0000005: Access violation reading location 0x00000000."
Then the call stack shows only "0x00000000()" and the disassembly shows me a dump of the memory at 0x0. I've set up the symbol server, loaded my PDB symbols, etc. But I can't see any way of knowing which of the many DLLs actually caused the jump to null. This is a large project with many dependencies, and some of them are binaries that I don't have the source or PDBs for, as I am using an API as a 3rd party.
So how on earth is this minidump useful? How do I see which DLL caused the crash? I've never really used minidumps for debugging before, but all the tutorials I have read seem to at least display a function name or something else that gives you a clue in the call stack. I just get the one line pointing to null.
I also tried using "Depends" to see if there was some DLL dependency that was unresolved; however on my three test machines with various Windows OS's, I seem to get three different sets of OS DLL dependencies (and yet can't replicate the crash); so this doesn't seem a particularly reliable method either to diagnose the problem.
What other methods are available to determine the cause of this problem? Is there some way to step back one instruction to see which DLL jumped to null?
Well it looks like the answer in this instance was "Use WinDbg instead of Visual Studio for debugging minidumps". I couldn't get any useful info out of VS, but WinDbg gave me a wealth of info on the chain of function calls that led to the crash.
In this instance it still didn't help solve my problem, as all of the functions were in the 3rd party library I am using, so it looks like the only definitive answer to my specific problem is to use log files to trace the state of my application that leads to the crash.
I guess if anyone else sees a similar problem with an unhelpful call stack when debugging a minidump, the best practice is to open it with WinDgb rather than Visual Studio. Seems odd that the best tool for the job is the free Microsoft product, not the commerical one.
The other lesson here is probably "any program that uses a third party library needs to write a log file".
The whole idea behind all 'simple' ways of post mortem debugging is the capture of a stack trace. If your application overwrites the stack there is no way for such analysis. Only very sophisticated methods, that record the whole program execution in dedicated hardware could help.
The way to go in such a case are log files. Spread some log statements very wide around the area where the fault occurs and transmit that version to the customer. After the crash you'll see the last log statement in your log file. Add more log statements between that point and the next log statement that has not been recorded in the log file, ship that version again. Repeat until you found the line causing the problem.
I wrote a two part article about this at ddj.com:
About Log Files Part 1
About Log Files Part 2
Just an observation, but the the stack is getting truncated or over-written, might this be a simple case of using an uninitialised field, or perhaps a buffer overrun ?
That might be fairly easy to locate.
Have you tried to set WinDbg on a customer's computer and use it as a default debugger for any application that causes a crash? You just need to add pdb files to the folder where your application resides. When a crush happens WinDbg starts and you can try to get call stack.
Possibly you already know this, but here are some points about minidump debugging:
1. You need to have exactly the same executables and PDB files, as on the client computer where minidump was created, and they should be placed exactly in the same directories. Just rebuilding the same version doesn't help.
2. Debugger must be connected to MS Symbols server.
3. When debugger starts, it prints process loading log in the Output window. Generally, all libraries should be successfully loaded with debug information. Libraries without debug information are loaded as well, but "no debug info" is printed. Learn this log - it can give you some information.
If executable stack contains frames from a library without debug information, it may be not shown. This happens, for example, if your code is running as third-party library callback.
Try to create minidump on your own computer, by adding some code which creates unhandled exception, and debug it immediately. Does this work? Compare loading log in successful and unsuccessful debugging sessions.
You may have called null function pointer. Current executing function information is needed to show call stack information. Force set instruction pointer to start of any simple function, then you'll see call stack information again.
void SimpleFunc()
{ // <- set next statement here
}

Deliberately crashing an external process under Windows

I would like to synthesise a native code fault. This is so that we can see where in particular some debugging output gets put when that occurrs.
Pskill (from Sys-Internals) causes a graceful exit. DotCrash.exe doesn't seem to be available anymore from Microsoft directly.
Is there any way to externally cause a crash in a process?
I've done this before using windbg by:
Starting the process
Attaching to the process with windbg
Setting a breakpoint on one of my app's functions
Running the app until I hit the breakpoint
In windbg setting a local variable to something that will cause an Access Violation (e.g. set a pointer to 0xFFFFFFFF or muck with the register values)
hit f5 and the app should hopefully crash
If what you want is the equivalent of a coredump, drwtsn32 -p ProcessId generates a dump of the current state of a running process. If you have the appropriate debug symbols you can get valuable information.
HTH.
As Nick mentions, this can easily be done via Debugging Tools for Windows - I'd go one step further though, and use cdb (the command-line WinDbg) to script the whole interaction.
If you need dumps at any desired time, you can use Microsoft's free debug diagnostic tool which has a nice UI to do that or on command line drwtsn32 -p processid as recommended by jrbjazz.
You could try using CreateRemoteThread. Using it correctly isn't easy, but making the other process crash should be pretty easy ;-)
Could you install some kind of hook function, or use something like the detours library?

How do I analyse a BSOD and the error information it will provide me?

Well, fortunately I haven't written many applications that cause a BSOD but I just wonder about the usefullness of the information on this screen. Does it contain any useful information that could help me to find the error in my code? If so, what do I need, exactly?
And then, the system restarts and probably has written some error log or other information to the system somewhere. Where is it, what does it contain and how do I use it to improve my code?
I did get a BSOD regularly in the past when I was interacting with a PBX system where the amount of documentation of it's drivers were just absent, so I had to do some trial-and-error coding. Fortunately, I now work for a different company and don't see any BSOD's as a result of my code.
If you want a fairly easy way to find out what caused an OS crash that will work ~90% of the time - assuming you have a crash dump available - then try the following:
Download WinDbg as part of the Debugging tools for Windows package. Note, you only need to install the component called Debugging Tools for Windows.
Run WinDbg
Select "Open Crash Dump" from the file menu
When the dump file has loaded type analyze -v and press enter
WinDbg will do an automated analysis of the crash and will provide a huge amount of information on the system state at the time of the crash. It will usually be able to tell you which module was at fault and what type of error caused the crash. You should also get a stack trace that may or may not be helpful to you.
Another useful command is kbwhich prints out a stack trace. In that list, look for a line contains .sys. This is normally the driver which caused the crash.
Note that you will have to configure symbols in WinDbg if you want the stack trace to give you function names. To do this:
Create a folder such as C:\symbols
In WinDbg, open File -> Symbol File Path
Add: SRV*C:\symbols*http://msdl.microsoft.com/download/symbols
This will cache symbol files from Microsoft's servers.
If the automated analysis is not sufficient then there are a variety of commands that WinDbg provides to enable you to work out exactly what was happening at the time of the crash. The help file is a good place to start in this scenario.
Generally speaking, you cannot cause a OS crash or bug check from within your application code. That said, if you are looking for general tips and stuff, I recommend the NTDebugging blog. Most of the stuff is way over my head.
What happens when the OS crashes is it will write a kernel dump file, depending on the current flags and so on, you get more or less info in it. You can load up the dump file in windbg or some other debugger. Windbg has the useful !analyze command, which will examine the dump file and give you hints on the bucket the crash fell into, and the possible culprits. Also check the windbg documentation on the general cause of the bug check, and what you can do to resolve it.

Resources