Has anyone figured out how the Very Sleepy profiler finds PDB files? It seems like it doesn't use the _NT_SYMBOL_PATH env variable.. I've had success by putting PDBs in the same directory as the executable and DLLs, but I'm trying to profile a program that uses a TON of DLLs and it's getting really painful. Isn't there some way to have it point to a symbol server?
The path to the original .pdb file is getting included in the DLL. Just don't move them.
The source code for Very Sleepy is readily available. It uses the DbgHelp API, symbolinfo.cpp source code file. The call to SymInitialize() allows a tool to specify the the search path for symbols, 2nd argument. It passes NULL, that's where the buck stops.
Related
I have a c++ application that uses the g3log library to provide stack trace information when a crash happens. My release configuration also builds full pdb file so that this is possible. My app.exe stores the full path to the pdb file, that is I am not using /PDBALTPATH:%_PDB%.
When I am running the .exe from any folder path, so long as the .pdb has not been moved, then if I force a crash, I get a meaningfull stack trace. Now if I move the .pdb file to be in the same directory with my .exe it is not loaded anymore. My guess is that is does not match the path in the .exe. I thought that a .pdb file with the same name as the .exe would be loaded, I guess I was wrong.
I have tested by specifying /PDBALTPATH:%_PDB% such that there is no path information but then the .pdb file is again never loaded.
For both cases if I attach a debugger all is good in the debugger but not in my stack trace.
Is there a way to get the "automatic loading" of the .pdb (not sure how to call it) from when it matches the full path to happen when the .pdb is in the same directory. That way I can get a meaningful call stack when needed.
In general, your use case seems pretty weird. Because unexpected exception usually means an undefined state, and there is no sense to continue. So you need probably to save a dump and investigate it later with your PDB files.
I'm not sure about the inner mechanics which gets the stack trace information in your dev environment. But usually, a debugger is looking for PDB files and trying to load it from different places. And when you place a PDB file with an EXE file, you make it possible to be found by a debugger.
For example, my build server saves PDB files while building to my local symbol server. And when I debug a crash dump with my debugger, it gets desired symbols correctly.
I have never tried to do things you are trying to do. In fact, it looks like debug build in production, which is not a good practice. So, I would consider an approach I described above.
You can set this path;
set _NT_SYMBOL_PATH=C:\MySymbols, where your pdb files are there.
Thats the simple way, if you cant set this path, then follow below procedure.
You mentioned:
When I am running the .exe from any folder path, so long as the .pdb has not been moved, then if I force a crash, I get a meaningfull stack trace. <<
So, always make sure your app runs from the directory where the .exe+.pdb files are there.
You can do that with GetModuleFileName+SetCurrentDirectory.
That means, your working directory is different.
I would suggest is, in you application, get "GetModuleFileName".
Then change the working directory to exe path using: SetCurrentDirectory.
It seems that #prasad-mk is half way correct. Setting the _NT_SYMBOL_PATH somehow forced my .pdb symbol to be loaded as in the case where the path matches.
Another option that I found is by using this utility
http://bytepointer.com/tools/index.htm#peupdate to update the path to wharever the location of my pdb is.
I'm currently working on a tool that allows me to change C++-code on the fly. Changed files are compiled in the background, loaded from the .obj, relocated & linked, and patched into the running process.
This works fine so far.
However, I have been unable to load symbols for the new functions so that they are visible by the debugger. I have tried creating a virtual module using SymLoadModuleEx and adding symbols via SymAddSymbol, but that didn't work.
Ultimately, I would like to be able to add symbols and line information for the new functions. I could do that from either a .pdb file or the COFF info stored in the .obj (I have both), but I seem to be missing the crucial part that informs the debugger.
Is there a function for this that I simply missed? Or an undocumented code for RaiseException that is understood by the debugger (similar to naming a thread)?
I use Visual Studio, but any help in getting this to work in either the VS debugger or WinDBG is greatly appreciated.
I have a very frustrating problem, I'm debugging my code, and for complete Call Stack I need to get symbols for msvcr120.dll (msvcr120.i386.pdb).
The thing is, that I can't get it.
tried loading it from MS Symbols Servers, result:
SYMSRV: http://msdl.microsoft.com/download/symbols/msvcr120.i386.pdb/16F5E2EF340A453ABC8B8F67DC6FD8082/msvcr120.i386.pdb not found
http://msdl.microsoft.com/download/symbols: Symbols not found on symbol server.
tried downloading manualy symbols packages for various Windows versions from MS, downloaded aprox. 2GB, got symbols for msvcr from 90 to 110, and two 120 (from Win 10 package):
msvcr120.i386.coresys.pdb
msvcr120_clr0400.i386.pdb
So, is there a way to get "msvcr120.i386.pdb" ?
In order to get the proper PDB for the file, you need to know which module is actually loaded. If you create a crashdump (.DMP) of the program while running (which you can do with taskmanager), it should show you the exact file loaded, including it's full path. You can also use a tool like dependency walker, which may do a better job at finding the full path.
Once you have the path, you can then specifically try to force-load symbols for that module by right-clicking, loading, and pointing to the exact file in question. That should get the proper hash and load the correct PDB from the MS symbol store into your local cache.
What's likely happening is that the program you're running either has a manifest calling out a specific SxS version of the DLL, OR your program has crashed enough that Windows has placed it in "compatibility mode". Either way, that means the program and VS are finding different versions of the DLL, thus the problem you're having. You can also see this when your program crashes on a different machine than the one you're debugging on, especially if they're not both exactly in the same place for windows updates.
If you do dev work regularly, you should disable Windows automatically putting things into compatibility mode. It will save you lots of headaches down the road.
My basic issue is this: my program (MyProgram.exe) has a dependency on a DLL from another program (OtherProgram), and I'm trying to avoid repackaging a new DLL every time OtherProgram updates. I'd like to have MyProgram.exe link in OtherProgram's DLL when it launches, but I'm not completely sure that Windows allows for this. So if there is some kind of workaround that would also be acceptable.
And just for some background, the platform is Windows 7 x64, and MyProgram.exe runs fine when I create a symlink in the MyProgram.exe project directory to the DLL in OtherProgram's install directory. When I try to run it without the symlink, I get the "program can't start because OtherProgramDLL.dll is missing from your computer" error.
Any advice or links to relevant info is greatly appreciated!
EDIT: Clarification: the DLL is not linked at compile-time, this issue crops up at runtime
There are two types of dynamic linking in the Windows world:
Load-Time linking is when a DLL is loaded automatically when your program starts up. Windows finds this DLL using a specific algorithm I'll discuss below.
Run-Time linking is when you specifically load a DLL by calling LoadLibrary in your code. Similar rules apply as to how the library is found, but you can specify a fully-qualified or relatively-qualified path to control the search.
In the case of Load-Time linking, MS recommends that your program's DLLs are stored in and loaded from the same directory where your application is loaded from. If this is at all workable, this is probably your best option.
If that doesn't work, there are several other options, outlined here. One is to leverage the search order by putting the DLL in either the working directory or the directory where the application was loaded from.
You can change the working directory of an application by:
Create a shortcut to your application.
Bring up the shortcut's properties
Edit the "Start in" property with the directory where the DLL is located.
When you launch your application using the shortcut, it will load the right DLL.
Other options for load-time linking include:
Adding a manifest to your application which specifies where your dependent assemblies are, or,
Setting the PATH.
You could use LoadLibrary, but you would need a way to guarantee the DLL's location. This Wikipedia article provides good example on how to use the DLL after it has been loaded.
You can add the directory where the dll is located to the PATH environment variable.
I have struggled with the same problem and also found a dead end with the suggested methods like LoadLibrary, SetDllDirectory, Qt's addLibraryPath and others. Regardless of what I tried, the problem still remained that the application checked the libraries (and didn't find them) before actually running the code, so any code solution was bound to fail.
I almost got desperate, but then discovered an extremely easy approach which might also be helpful in cases like yours: Use a batch file! (or a similar loader before the actual application)
A Windows batch file for such a purpose could look like this:
#echo off
PATH=%PATH%;<PATH_TO_YOUR_LIB>
<PATH_TO_YOUR_APP_EXE>
/edit: Just saw #SirDarius comment in Luchian's answer which describes that way, so just take my batch code bit as a reference and all credits go to him.
I have the same problem with one application I am working on.
I do not want to use runtime loading because there are tens of functions I would need to manually create function pointer for.
Mr Dibling's mention of manifest file opened a new door for me but I sadly found out that the oldest version of windows that supports the feature is Windows 7. It won't even work on Vista.
Long story short, a friend familiar with Windows Application development told me to look up Delay-Loaded DLL, which turns out to solve the problem perfectly with minimal effort. It delays the loading of DLL library to either the point you manually do, or the first time its function is called. So you just need to add your DLL path to the search path before that happens, where SetDllDirectory helps.
Here is the steps to make it work:
1) Specify the DLL to be delay-loaded to linker, either through your makefile, cmake or VS property page (Linker->Input of VS2015)
2) Call SetDllDirectory at the beginning of your program, before any call to the DLL is made.
Delay-loaded DLL is supported all the way back to VC6.
SetDllDirectory is supported after XP SP1.
Use Symbolic Links to the 3rd Party Executables
I found the approach advocated by Aaron Margosis useful. See:
Using NTFS Junctions to Fix Application Compatibility Issues on 64-bit Editions of Windows
Essentially, create symbolic links to each of the dependent 3rd Party executables. Place these symbolic link files in and amongst your own dependent executable files. Except for filename changes to the targets, the 'soft' symbolic links will resolve the load-time dependencies even as the target of the links are changed by future updates.
What is the use of .map files VC++ linker produces when /MAP parameter or "Generate map file" project setting is used? When do I need them and how do I benefit from them?
A nice article on how to use map files for finding crashes.
http://www.codeproject.com/KB/debug/mapfile.aspx
Manually doing all this is very uninteresting.
I am not aware of any tools which can read map file and help in finding the crash location. If anybody knows please update us.
For embedded systems, map files are a lot more useful. (Although you wouldn't be using Visual C++ for that ;)
Things like knowing how close you are to running out of program/data memory, and what location a particular variable resides in, are important.
WinDBG uses .map and .pdb files to help debug crashes, when analysing .hdmp and .mdmp crash dumps.
Basically they map memory address offsets to functions and variables within the .exe (and/or loaded .dlls). Very useful in general if you need to figure out why a customer is upset. Even more useful when they prove it was not your fault.
The most useful way to debug "post-mortem" crashes is using WinDbg (Windows platform). Open it up, and open the crash dump. Then set the source path to point at the code (if you have it), the symbol path to point at your .map and .pdb and the image path to the .exe, and type "!analyse -v" in the command line. Now you have a full stack trace with lines of code and everything. Of course you need to have the correct version of the source code for the version of the exe's and DLLs you are debugging.
It's even better if you have the MS symbol server in the path, and if the full page heap was turned on or adplus was running. With ADPlus in particular you will likely have variable values captured as well.
Some favourite WinDbg resources of mine:
First stop :: http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx
Force load the symbols :: http://www.osronline.com/ShowThread.cfm?link=182377
Useful site :: http://www.dumpanalysis.org/blog/index.php/category/windbg-tips-and-tricks/page/7/
You need them rarely, but they can be handy debugging some problems because they give information on the location of functions and data.
For example:
detailed information on all segments (code, data and other).
link line numbers to code
You can use map files for debugging tools.
Linker maps can be very useful in large projects when you need to track dependencies between compilation units and libraries. Typically, a linker will report a symbol which caused problems, and more often than not, a simple search for this symbol name won't return any results (or will return tons of false positives for symbols like read).
Without a linker map, the only option you have is to analyze all available source files (after preprocessing pass if macros were used, which is typically the case) and hope that you find the relevant spot.
Linker maps usually have a section called "reference by file/symbol" which tells you which object file was required by another object file of your project, and which symbol exactly was referenced.
I was once working on a project which had to be ported on a system without locale support. The linker was reporting "undefined reference to _localeconv_r" errors, which would have been a pain to track down by searching through the sources. Luckily, a GCC linker map file generated with -Map=output.map revealed all problematic functions with a single search.
amap cross-platform GUI tool allows you to examine MAP files produced by the GCC, Visual Studio and some other compilers. You can find out, for example, how much every source file and every external dependency contribute to size of your executable.