How much trust should I put into pdb line numbers? - windows

I'm debugging a problem at present in Windbg from a dump. I've got the correct pdbs and I can view the locals etc quite happily. However, the source code I have (which I've pulled from the VCS branch from which this release supposedly came from) appears to be off by several lines in some parts of the stack I'm looking at. I've seen instances where it's off by 1 before, but not 3/4 lines.
What causes this? Is there any definitive way I can check that I've got the right source files?

Are you looking at debug or non optimised version of release code?
Code optimisation may cause the line shift you are seeing so you should recompile with /Od C++ optimization set to 'disabled' and see if this corrects what you see.
WinDbg uses the same method as Visual Studio to check if the source file you are viewing/setting breakpoints with matches the pdbs so it should warn you (I think it does this I cannot verify).
Besides you can verify the pdbs if not the source files using:
!itoldyouso myDLL
additionally you can open the source file in another window, during stepping and it should put a magenta line at the line it thinks the current call is at, this should be correct and behave the same as visual studio.

Related

The mystery of blind source stepping, or how F# behaves erratically on large source files

I was testing whether I could rely on __LINE__ to always return the correct value and created a large source file with many lines.
At some point, the inline function names (which get names like fun#7564-1, where 7564 is the line number) started counting from zero again.
After some research I noticed that:
If your source code hits line 65536, any errors, messages, stacktraces start counting from zero
__LINE__ still returns the correct value
Decorated names of inline functions start from zero again
Compile time errors underline totally unrelated lines
Stepping through with debugging goes over totally unrelated lines
Setting a breakpoint on the actual line sets it on the "blind" line
Tooltips over variables during debugging still show the correct value, and no tooltips appear in the "blind" spot.
To illustrate, with a bunch of newlines and the method being debugged being over line 65535, I managed to get a blind source stepping experience:
Is this 216 boundary deliberate or by accident? Is it a limit artificially imposed by F# or by the CLR or PDB format?
Note (1): I only tested this with F# 4.0, .NET 4.5 on Windows 7 and 2012, using VS 2015.
Note (2): I doubt this boundary will be hit often, unless perhaps for auto-generated source files (in C# I have some autogen'ed files that exceed this boundary).
Update: reported as a bug to the FSharp team on Github here.
I have tried to reproduce using large files, and this is also weird on my machine.
In the GitHub repo, Don Syme has replied and asked something about your source code. This might be a limitation of current Visual F#'s tool.
This appears to be a confirmed bug in Visual F#, the bug report has a full repro solution for download.
There's a related issue on large source files throwing StackOverflowException in Debug build, and another related issue also throwing an SOE on large lambda or entrypoint, but in any build.

"The breakpoint will not currently be hit" keeps showing on a partial view

In a specific partial view, I consistently get a message in the breakpoints I set:
"The breakpoint will not currently be hit. No symbols have been loaded for this document."
Is there any reason for this to happen? What may I have done?
I restarted Visual Studio and I even restarted my computer, but it didn't work.
What do I have to do to debug this page?
Thanks!
Edit
I edit the partial view file with which I am having problems, but the changes do NOT take effect. So, somehow, that bastard compiler is getting the file from somewhere else. Where?!
I had the same situation after modifying a view that used to debug ok. I reverted my changes and debugging resumed working. I found I had a syntax error on a line. There was no clue it was wrong - there was no red underlining and the project compiled fine.
If you have the problem in your view, I suggest commenting most of the code to a minimal skeleton. If debug works again, uncomment some of your lines back in until you find the problem code. Good luck with that.
There are several possible reasons for that:
The version of the source file is not the one you compiled. Try to recompile.
The DLL containing the code is not loaded in the program at runtime. Use the program in a way that the DLL will be needed if you have dynamic loading of DLL.
You are visualizing a source file which is not in the right directory (another copy of the solution somewhere else on the hard disk). Open the right source file.
You didn't compile the program in debug mode. Recompile it in debug mode.
You didn't launch the program in debug mode. Launch it in debug mode.
This is happening to me too...it's a real pain in the arse. The reason is because your PDB files are missing from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root[random][random]\assembly\dl3[random][guid]
I have about 30 DLL files that get built with my project, I have to go into each one of those stupid temp directories and copy the PDB file for each DLL from my VS build bin. I've posted questions on here about it too but haven't gotten any help. For a quick fix, you can try to copy your matching pdb files over but I'm telling you it's gonna get old real fast.
Someone else in my office has fixed the problem by using the "Publish" feature in Visual Studio and publishing their site straight into a web directory but I haven't had any time to mess with that yet. Someone else has told me that it's a x64 bug in Visual Studio but I find that hard to believe considering how crippling it is.
The way I resolved it is by going to the properties(F4) of the file and set the value of Build Action to Compile.

Can I use pdb files to step through a 3rd party assembly?

my friend has made a really helpful class library which I use all the time. I usually use Reflector to see what his code does.
What I really wanted to do was to step through his code while I'm debugging. So he gave me his .pdb file.
Foo.dll (release configuration, compile)
Foo.pdb
Now, I'm not sure how I can get it to auto break into his code when it throws an exception (his code, at various points, thorws exceptions .. like A first chance exception of type 'System.Web.HttpException' occurred in Foo.dll ...
Can I do this? Do i need to setup something with the Symbol Server settings in Visual Studio ? Do i need to get the dll compiled into Debug Configuration and be passed the .dll and .pdb files? Or (and i'm really afraid of this one) .. do i need to have both the .dll, .pdb AND his source code ...
I also had a look at this previous SO question, but it sorta didn't help (but proof I've tried to search before asking a question).
Can someone help me please?
Yes you can, if your friend indexes those PDB's, so that the debugger knows where to find the appropriate source in a source-control system, and if your friend uploads those pdb's to a symbol-server, you can perfectly step through the code while debugging.
I have done this for some projects at work, and this works like a charm.
More info about setting up a symbol server:
Source server helps you kill bugs
Setting up a symbol server
Using symstore
The answer is in in the linked question, though perhaps it's not blindingly obvious, so I'll say it: yes, you need to have the source code in order to step through the source code. The PDB file only tells the debugger what line of what source file corresponds to a particular machine instruction.
You don't need to set up a "symbol server" or anything like that. Just get him to send you the source. When you load the PDB file Visual Studio will prompt for the location of the source files if they're not at the same path.
I guess you posted link to another question just to prove that you have searched because that question does have an answer to your question.

Any recommended VC++ settings for better PDB analysis on release builds

Are there any VC++ settings I should know about to generate better PDB files that contain more information?
I have a crash dump analysis system in place based on the project crashrpt.
Also, my production build server has the source code installed on the D:\, but my development machine has the source code on the C:\. I entered the source path in the VC++ settings, but when looking through the call stack of a crash, it doesn't automatically jump to my source code. I believe if I had my dev machine's source code on the D:\ it would work.
"Are there any VC++ settings I should know about"
Make sure you turn off Frame pointer ommision. Larry osterman's blog has the historical details about fpo and the issues it causes with debugging.
Symbols are loaded successfully. It shows the callstack, but double clicking on an entry doesn't bring me to the source code.
What version of VS are you using? (Or are you using Windbg?) ... in VS it should defintely prompt for source the first time if it doesn't find the location. However it also keeps a list of source that was 'not found' so it doesn't ask you for it every time. Sometimes the don't look list is a pain ... to get the prompt back up you need to go to solution explorer/solution node/properties/debug properties and edit the file list in the lower pane.
Finally you might be using 'stripped symbols'. These are pdb files generated to provide debug info for walking the callstack past FPO, but with source locations stripped out (along with other data). The public symbols for windows OS components are stripped pdbs. For your own code these simply cause pain and are not worth it unless you are providing your pdbs to externals. How would you have one of these horrible stripped pdbs? You might have them if you use "binplace" with the -a command.
Good luck! A proper mini dump story is a godsend for production debugging.
If your build directly from your sourcecode management system, you should annotate your pdb files with the file origins. This allows you to automatically fetch the exact source files while debugging. (This is the same proces as used for retrieving the .Net framework sourcecode).
See http://msdn.microsoft.com/en-us/magazine/cc163563.aspx for more information. If you use subversion as your SCM you can check out the SourceServerSharp project.
You could trying using the MS-DOS subst command to assign your source code directory to the D: drive.
This is the procedure I used after some trouble similar to yours:
a) Copied to the production server all the EXE & DLL files that were built, each with its corresponding PDB to the same directory, started the system, and waited for the crash to happen.
b) Copied back all the EXE, DLL & PDB files to the development machine (to a temporary folder) along with the minidump (in the same folder). Used Visual Studio to load the minidump from that folder.
Since VS found the source files where they were originally compiled, it was always able to identify them and load them correctly. As with you, in the production machine the drive used was not C:, but in the development machine it was.
Two more tips:
One thing I did often was to copy an EXE/DLL rebuilt and forget to copy the new PDB. This ruined the debug cycle, VS would not be able to show me the call stack.
Sometimes, I got a call stack that didn't make sense in VS. After some headache, I discovered that windbg would always show me the correct stack, but VS often wouldn't. Don't know why.
In case anyone is interested, a co-worker replied to this question to me via email:
Artem wrote:
There is a flag to MiniDumpWriteDump()
that can do better crash dumps that
will allow seeing full program state,
with all global variables, etc. As for
call stacks, I doubt they can be
better because of optimizations...
unless you turn (maybe some)
optimizations off.
Also, I think disabling inline
functions and whole program
optimization will help quite a lot.
In fact, there are many dump types,
maybe you could choose one small
enough but still having more info
http://msdn.microsoft.com/en-us/library/ms680519(VS.85).aspx
Those types won't help with call stack
though, they only affect the amount of
variables you'll be able to see.
I noticed some of those dump types
aren't supported in dbghelp.dll
version 5.1 that we use. We could
update it to the newest, 6.9 version
though, I've just checked the EULA for
MS Debugging Tools -- the newest
dbghelp.dll is still ok to
redistribute.
Is Visual Studio prompting you for the path to the source file? If it isn't then it doesn't think it has symbols for the callstack. Setting the source path should work without having to map the exact original location.
You can tell if symbols are loaded by looking at the 'modules' window in Visual Studio.
Assuming you are building a PDB then I don't think there are any options that control the amount of information in the PDB directly. You can change the type of optimizations performed by the compiler to improve debuggabilty, but this will cost performance -- as your co-worker points out, disabling inline will help make things more obvious in the crash file, but will cost at runtime.
Depending on the nature of your application I would recommend working with full dump files if you can, they are bigger, but give you all the information about the process ... and how often does it crash anyway :)
Is Visual Studio prompting you for the
path to the source file?
No.
If it isn't then it doesn't think it has symbols
for the callstack. Setting the source
path should work without having to map
the exact original location.
Symbols are loaded successfully. It shows the callstack, but double clicking on an entry doesn't bring me to the source code. I can of course search in files for the line in question, but this is hard work :)

Attaching to a foreign executable in Visual C++ 2003

I have an executable (compiled by someone else) that is hitting an assertion near my code. I work on the code in Visual C++ 2003, but I don't have a project file for this particular executable (the code is used to build many different tools). Is it possible to launch the binary in Visual C++'s debugger and just tell it where the sources are? I've done this before in GDB, so I know it ought to be possible.
Without the PDB symbols for that application you're going to have a tough time making heads or tails of what is going on and where. I think any source code information is going to be only in that PDB file that was created when whoever built that application.
This is assuming that the PDB file was EVER created for this application - which is not the default configuration for release mode VC++ projects I think. Since you're asserting, I guessing this is a debug configuration?
Short of any other answers, I would try attaching to the executable process in Visual Studio, setting a break point in your code and when you step into the process you don't have source to, it should ask for a source file.
Yes, it's possible. Just set up an empty project and specify the desired .exe file as debug target. I don't remember exactly how, but I know it's doable, because I used to set winamp.exe as debug target when I developed plug-ins for Winamp.
Since you don't have the source file it will only show the assembly code, but that might still be useful as you can also inspect memory, registers, etc.
Update
If you are debugging an assertion in your own program you should be able to see the source just fine, since the path to the source file is stored in the executable when you compile it with debug information.

Resources