Visual Studio Profiler does not show source code positions - c++

I'm trying to profile a Win32 native application which also makes use of some external DLL's which are same Win32 native build.
When I stop data collection at some point, the profiler starts generating an overview how much process time and data are collected where - but whatever it is, it always shows me "External code" in this tree.
To clarify my problem: this happens for all positions in my application, means where sources are available and which are built with debug symbols!
Any ideas what could cause this? Thanks!

if you want show source code at debug or profiler mode, you must got pdb file for bins(include exe and dlls).
for "some external DLL's", may you can't get a match pdb.
for you win32 exe, you must generate pdb file for debug, you can google it.

Related

Dumping a stack trace from C++ (Windows) - fails to find symbols

I'm a developer of Windows desktop software, and from time to time our app crashes. In rare cases I'd like to get a customer to run a debug version of the app to send me a stack trace so I know where it crashed. I followed the instructions in here:
Windows C++ stack trace from a running app
...but while it works on my development machine, it doesn't work on any client machine or those of my colleagues, who don't have Visual Studio installed. So I presume that there's some .dll or something they need before it'll work. They're using the same .exe I'm using, i.e. the one I compiled in VC++ in debug mode.
After some painstaking "message window" debugging, I learnt it's failing in SymGetSymFromAddr64() - this returns FALSE. But when I walk the stack, this always returns FALSE or it returns garbage that doesn't make sense (random unrelated method names), as if it's the PC values which are invalid, not the mapping process. To reiterate, it's a debug mode .exe that produces a perfect symbolic stack trace on my development machine.
I did some research and found some mentions of "dbghelp.dll" and "imagehlp.dll" but I just ended up confused. "dbghelp.dll" ships with all versions of Windows, but with reduced functionality. There's some other things I could install, but it's a little scary to be installing some Windows "WDK" or "debug kits" which might overwrite important system .dll's or do god-knows-what to your computer.
So what I need to know is: "what's the simplest set of instructions I can give to these helper customers e.g. the minimum set of .dll's and where to stick them so that we can get proper symbolic information out of the stack traces when our program crashes?"
The most likely reason for failing to find the symbols is that the .pdb file cannot be found. Even if you generate a .exe in debug mode, the symbols are not in the .exe, they are in the .pdb file. Through a lot of empirical testing, it seems that the process has the pathname of the .pdb hardcoded in it, so if your clients don't have that file at that location, they won't necessarily find it. However, you can supply a "search path" to the SymInitialize() function - a folder or set of folders to use to search for the .pdb file.
In my configuration, I had an exe called "Edval.exe" and a .pdb called "DebugEdval.pdb". The process searches for "DebugEdval.pdb" in the search folders. This corresponds to what you've configured in "Properties > Linker > Debugging > Generate Program Database File".

Debug symbols are said to be not loaded for a document even though they are loaded for the dll

I have built a particular dll with debug information (compiler option /Zi and linker option /DEBUG). Through an interrupt statement in the main program, I launched the Visual Studio for debugging. In the list of modules shown as seen from Debug->Windows menu, I could see that the symbols have been loaded for the dll interested in. However when I open a C++ file from that dll and try to set a breakpoint, it says debug symbols are not available for the document. There is no question that this C++ file was compiled into that dll, and that it is the same source used to build the dll (I only did it). Why does this happen? Please help, before I shoot myself.
I don't have a definitive answer, only a few suggestions.
Sometimes mdm.exe (Machine Debug Manager) stops to work properly. Terminating the process and re-starting Visual Studio helps. If the problem persists between reboots however that probably isn't the cause.
Source-file-times (last modified) that are in the future can cause all kind of weird problems. To check file times, you can do a search for nothing (Windows XP) or "*" (Windows 7). That will list all files in the selected folder. Then sort the result by date to see the max/min file time. I have no idea where the incorrect file-times come from - I just know that it happens from time to time. Might be Visual Studio itself, might be some other tool I'm using.
You could try to start the application that uses your DLL from Visual Studio, with your DLL project already open. To do that, open the "Configuration Properties", select the "Debugging" page, and enter the .exe that should be started (+ arguments if you need any). Then start the debug session as you would for a .exe project.
A cure for many problems with Visual Studio is to "clean" the project manually, and do a full re-compile. Delete all files that are generated during a build process or that store solution or project "options". i.e. all .suo .ncb .user files plus everything in the "intermediate" and "output" folders. If you're using source control, just retrieve the whole project from your source control system into a clean directory, and re-build from scratch. (Getting everything "fresh" from source control also takes care of any potential file-time problems - at least with source control systems that don't preserve file-times)
Another possible reason would be, that VS loads the wrong .pdb file. A .pdb file with a matching name could be found in a symbol server/symbol directory configured for VS (or system wide through the _NT_SYMBOL_PATH variable), or in the VS symbol cache directory. How a .pdb file with a matching name came to be in such a place is a different story, but one can easily check if the wrong .pdb file is loaded: delete the .pdb file generated by the build, and start a debug session. If VS traces "symbols loaded" for the .exe/.dll in question, it must have found a .pdb file in some other location.
Sometimes VS seems to mess up breakpoint locations in some way. I don't exactly know when or how this happens, but one of the symptoms is, that if one deletes some breakpoints, they magically reappear when starting the next debug-session. I found that setting a new breakpoint, then deleting all break points by Debug/Delete All Breakpoints, and the re-setting the required ones helps.
1) Are you not able to hit the breakpoint at all ? Generally, it gets resolved once the code in the module or stack frame needs to be hit.
2) Check if your pdb is not source information stripped
Do a Build->Clean Solution, close visual studio and then restart it and do a fresh build. This happened to me once before, and that seemed to fix it, just some outdated pdb information, I suppose.
In my case, I had renamed the C++ project. The compiler was outputting newName.lib while my other projects were still referencing oldName.lib which of course would not be removed by a Build->Clean.
I found this out by following the advice to manually clean the build directory. The subsequent linker unresolved external reference gave away the situation.

Breakpoint not hitting

I ported an application from VC6 to VS 2008. I rebuilt the application in release build. The Pdb file is available in the folder where exe is located. But when I loaded the application and put break point I am getting the following message
"The breakpoint will not currently be hit.No symbols have been loaded for this document"
What would be the cause of the issue?
The debugger could not find either the application or the PDBs.
When you start the program, exactly which binaries are loaded are shown in the Output window. Make sure the right files are being loaded. When everything loads properly, the output looks something like this:
'hacks_vs10.exe': Loaded
'C:\Users\john\Documents\Visual Studio
2010\Projects\hacks_vs10\x64\Debug\hacks_vs10.exe',
Symbols loaded.
When the PDB is not found, instead of saying "Symbols loaded" it says:
Cannot find or open the PDB file
Make sure that you are first running the correct version of your application (check the running path), and then make sure that the PDB is in that directory. You can change where the PDB is generated to by tweaking "Project>Properties...>Linker>Generate Program Database File"
The debugger could not find code associated with the source location you put the breakpoint at.
There can be a number of reasons for this. The one I've most often found was a section of code that was truly not compiled in. (either because of preprocessor conditionals or dead-code removal).
I imagine there can be other reasons too (e.g. inlining, though in theory, the compiler could generate the proper mapping for all the inlines. I don't know what VS2008 does here).
Are you sure you're putting the breakpoint in a code path that is supposed to be executed ?
The PDB file you mention is probably not related to the release build,
Debug information is normally absent in the release build (though you can enable it if you have to but should anticipate surprising effects due to compiler optimizations).
Therefore, you can only set breakpoints on known DLL entry points (possible via the Module List view - it has been a while since I used Visual Studio intensively) or directly on assembly instructions.
Note that you could perhaps compile part of your application with debug symbols.
I have just solved a similar problem
I re-referenced all my DLL's
went to (Tools->Options, "Projects and Solutions", "Build and Run") and set "On Run when projects are out of date" to 'Prompt to build'
I'm not sure which of these fixed the problem, but it did!

Windows/C++: Is it possible to find the line of code where exception was thrown having "Exception Offset"

One of our users having an Exception on our product startup.
She has sent us the following error message from Windows:
Problem Event Name: APPCRASH
Application Name: program.exe
Application Version: 1.0.0.1
Application Timestamp: 4ba62004
Fault Module Name: agcutils.dll
Fault Module Version: 1.0.0.1
Fault Module Timestamp: 48dbd973
Exception Code: c0000005
Exception Offset: 000038d7
OS Version: 6.0.6002.2.2.0.768.2
Locale ID: 1033
Additional Information 1: 381d
Additional Information 2: fdf78cd6110fd6ff90e9fff3d6ab377d
Additional Information 3: b2df
Additional Information 4: a3da65b92a4f9b2faa205d199b0aa9ef
Is it possible to locate the exact place in the source code where the exception has occured having this information?
What is the common technique for C++ programmers on Windows to locate the place of an error that has occured on user computer?
Our project is compiled with Release configuration, PDB file is generated.
I hope my question is not too naive.
Yes, that's possible. Start debugging with the exact same binaries as ran by your user, make sure the DLL is loaded and you've got a matching PDB file for it. Look in Debug + Windows + Modules for the DLL base address. Add the offset. Debug + Windows + Disassembly and enter the calculated address in the Address field (prefix with 0x). That shows you the exact machine code instruction that caused the exception. Right-click + Go To Source code to see the matching source code line.
While that shows you the statement, this isn't typically good enough to diagnose the cause. The 0xc0000005 exception is an access violation, it has many possible causes. Often you don't even get any code, the program may have jumped into oblivion due to a corrupted stack. Or the real problem is located far away, some pointer manipulation that corrupted the heap. You also typically really need a stack trace that shows you how the program ended up at the statement that bombed.
What you need is a minidump. You can easily get one from your user if she runs Vista or Win7. Start TaskMgr.exe, Processes tab, select the bombed program while it is still displaying the crash dialog. Right-click it and Create Dump File.
To make this smooth, you really want to automate this procedure. You'll find hints in my answer in this thread.
If you have a minidump, open it in Visual Studio, set MODPATH to the appropriate folders with the original binaries and PDBs, and tell it to "run". You may also need to tell it to load symbols from the Microsoft symbol servers. It will display the call stack at the error location. If you try to look at the source code for a particular stack location, it may ask you where the source is; if so, select the appropriate source folder. MODPATH is set in the debug command-line properties for the "project" that has the name of the minidump file.
I know this thread is very old, but this was a top Google response, so I wanted to add my $.02.
Although a mini-dump is most helpful, as long as you have compiled your code with symbols enabled (just send the file without the .pdb, and keep the .pdb!) you can look up what line this was using the MSVC Debugger or Windows Debugger. MSN article on that:
http://blogs.msdn.com/b/danielvl/archive/2010/03/03/getting-the-line-number-for-a-faulting-application-error.aspx
Source code information isn't preserved in compiled C++ code, unlike in runtime-based metadata-aware languages (such as .NET or Java). The PDB file is a symbol index which can help a debugger map compiled code backwards to source, but it has to be done during program execution, not from a crash dump. Even with a PDB, Release-compiled code is subject to a number of optimizations that can prevent the debugger from identifying the source code.
Debugging problems which only manifest on end-user machines is usually a matter of careful state logging and a lot of detail-oriented time and effort combing over the source. Depending on your relationship with the user (for example, if you're internal corporate IT development), you may be able to make a virtual machine image of the user's machine and use it for debugging, which can help speed the process tremendously by precisely replicating the installed software and standard running processes on the user's workstation.
There are several ways to find the crash location after the fact.
Use a minidump. See the answers above.
Use the existing executable in a debugger. See the answers above.
If you have PDB files (Visual Studio, Visual Basic 6), use DbgHelpBrowser to load the PDB file and query it for the crash location.
If you have TDS files (separate TDS file, or embedded in the exe, Delphi, C++ Builder 32 bit), use TDS Browser to load the TDS/DLL/EXE file and query it for the crash location.
If you have DWARF symbols (embedded in the EXE, C++ Builder 64 bit, gcc, g++), use DWARF Browser to load the DLL/EXE and query it for the crash location.
If you have MAP files, use MAP File Browser to load the MAP file and query it for the crash location.
I wrote these tools for use in house. We've made them available for free.

Reading a windows *.dmp file

I was wonder if any knows how to open up a windows *.dmp file after a application crash written C/C++.
Using Visual Studio's File>Open Project or the free WinDbg's (part of Debugging Tools for Windows) File>Open Crash Dump select the dmp file.
Make sure to configure the tools to include a path to the location of the PDB debugging symbols for that application (you do have symbols right?). Either tool has a thread and call stack window that should give you a good idea where the crash occurred. Including paths to the source code will help as well.
Symbol and Source paths can be set in WinDbg under the File menu. It's buried in Visual Studio under Tools>Options>Debugging>Symbols and Tools>Options>Project and Solutions>VC++ Directores
Here's a link to an article from Microsoft on reading the small memory dump files that Windows creates for debugging
When using Debugging Tools for Windows be sure to setup symbols. For Microsoft symbols use: SRV*DownstreamStore*http://msdl.microsoft.com/download/symbols
For example: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
Take a look at these blogs for more on debugging:
http://blogs.msdn.com/tom
http://blogs.msdn.com/ntdebugging
http://blogs.msdn.com/tess
If you mean a dump file created by windows (either small memory dump, kernel memory dump or full memory dump) that is created after a system crash then you need WinDBG
You should be able to just double click the .dmp file to automatically open it in Visual Studio. If the .pdb file that was generated when the program was compiled is still around, Visual Studio should be able to automatically load the symbols from that. From then on, you can just hit Run/Debug (F5) to start peeking into the .dmp file.