I'm trying to Instrument an ASP.NET web-application with Visual Studio 2012, .NET 4.
The solution contains a web-application and a class library.
The problem is I can't see step into the class library, I get a message stating:
Matching symbols could not be found. Choose the 'Symbol Settings...' link to add the symbol file location and then reload the report.
The output while profiling looks good though:
Preparing web server for profiling.
Profiling started.
Instrumenting C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\\bin\PerformanceTest.dll in place
Info VSP3049: Small functions will be excluded from instrumentation.
Microsoft (R) VSInstr Post-Link Instrumentation 11.0.50727 x86
Copyright (C) Microsoft Corp. All rights reserved.
File to Process:
C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\bin\PerformanceTest.dll --> C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\bin\PerformanceTest.dll
Original file backed up to C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\bin\PerformanceTest.dll.orig
Successfully instrumented file C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\bin\PerformanceTest.dll.
Warning VSP2013: Instrumenting this image requires it to run as a 32-bit process. The CLR header flags have been updated to reflect this.
Instrumenting C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\SomeLibrary\obj\Debug\SomeLibrary.dll in place
Info VSP3049: Small functions will be excluded from instrumentation.
Microsoft (R) VSInstr Post-Link Instrumentation 11.0.50727 x86
Copyright (C) Microsoft Corp. All rights reserved.
File to Process:
C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\SomeLibrary\obj\Debug\SomeLibrary.dll --> C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\SomeLibrary\obj\Debug\SomeLibrary.dll
Original file backed up to C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\SomeLibrary\obj\Debug\SomeLibrary.dll.orig
Successfully instrumented file C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\SomeLibrary\obj\Debug\SomeLibrary.dll.
Warning VSP2013: Instrumenting this image requires it to run as a 32-bit process. The CLR header flags have been updated to reflect this.
Launching web server with profiling.
Launching profilable project.
Warning VSP2355: Some Windows counters will not be collected. Without this data, some performance rules may not fire.
Profiling process ID 68 (iisexpress).
Process ID 68 has exited.
Data written to C:\Users\kipusoep\Documents\InfoCaster\svn\instances\PerformanceTest\PerformanceTest_130801(1).vsp.
Profiling finished.
Loaded symbols for C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\0329cb19\89f716fc\App_Web_0slsprtu.dll.
Loaded symbols for C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\0329cb19\89f716fc\assembly\dl3\62c5c0d2\9777513f_ae8ece01\PerformanceTest.dll.
Profiling complete.
I notice the output doesn't state anything about the class library called 'SomeLibrary' at the end, where it says "Loaded symbols for".
Does anyone know why I can't instrument the class library?
Here's the VS solution: http://www.fileswap.com/dl/C9HPd8uEC/
As far as I can tell from your solution, the .dll that is being instrumented is in the class library's "obj" folder.
Now, this may just be me speaking when I should keep my mouth shut (because I have little insight into the Visual Studio profiler, and I have no idea why/if one would want to instrument "obj" binaries rather than "bin"), and therefore, I guess I'd better describe my train of thought:
VS is looking for the symbol files (the .instr.pdb file specifically) in the "ASP.NET Temporary Files" location, because that's where it loaded the class library dll from. It won't find it, though, because that file is created in obj\Debug in the class library project and not copied over to the web application's "bin" folder - so it never gets shadow copied to "ASP.NET Temporary Files" either.
Removing the targets from the Performance Explorer and selecting "Add Project Target", checking both projects, gives me exactly what you (and I) had before:
PerformanceTest.dll in Web Application project's ...\bin\Debug
SomeLibrary.dll in Class Library project's ...\obj\Debug
So apparently, this is how VS wants it to be, whether it works or not. It instruments the class library in obj\Debug, then forgets all about the newly generated symbols when starting the profiler.
But if, instead, I remove the "SomeLibrary.dll" target again, select "Add Target binary..." and manually pick the one in the web application's ...\bin\Debug... And then start profiling: The report looks about the same, but I can browse into "SomeLibrary" and I get this in the output:
Preparing web server for profiling.
Profiling started.
Instrumenting E:\...\PerformanceTest\\bin\PerformanceTest.dll in place
Info VSP3049: Small functions will be excluded from instrumentation.
Microsoft (R) VSInstr Post-Link Instrumentation 11.0.50727 x86
Copyright (C) Microsoft Corp. All rights reserved.
File to Process:
E:\...\PerformanceTest\bin\PerformanceTest.dll -->
E:\...\PerformanceTest\bin\PerformanceTest.dll
Original file backed up to E:\...\PerformanceTest\bin\PerformanceTest.dll.orig
Successfully instrumented file E:\...\PerformanceTest\bin\PerformanceTest.dll.
Warning VSP2013: Instrumenting this image requires it to run as a
32-bit process. The CLR header flags have been updated to reflect this.
Instrumenting E:\...\PerformanceTest\bin\SomeLibrary.dll in place
Info VSP3049: Small functions will be excluded from instrumentation.
Microsoft (R) VSInstr Post-Link Instrumentation 11.0.50727 x86
Copyright (C) Microsoft Corp. All rights reserved.
File to Process:
E:\...\PerformanceTest\bin\SomeLibrary.dll -->
E:\...\PerformanceTest\bin\SomeLibrary.dll
Original file backed up to E:\...\PerformanceTest\bin\SomeLibrary.dll.orig
Successfully instrumented file E:\...\PerformanceTest\bin\SomeLibrary.dll.
Warning VSP2013: Instrumenting this image requires it to run as a
32-bit process. The CLR header flags have been updated to reflect this.
Launching web server with profiling.
Launching profilable project.
Profiling process ID 14652 (iisexpress).
Process ID 14652 has exited.
Data written to E:\...\PerformanceTest\PerformanceTest_130810(1).vsp.
Profiling finished.
Loaded symbols for
C:\...\App_Web_yzwcgfbx.dll.
Loaded symbols for
C:\...\assembly\dl3\928eb82e\75dbb6f1_5695ce01\PerformanceTest.dll.
Loaded symbols for
C:\...\assembly\dl3\6c0d460d\5208c7f1_5695ce01\SomeLibrary.dll.
Profiling complete.
Is this the correct way to fix it? Again, I have no idea. If not, there may be a way to get the profiler to look for symbols in the class library's obj folder when it doesn't find them where it expects to - or a way of copying the .instr.pdb file to the bin folder pre-profiling so that it gets included in the shadow copy to ASP.NET Temporary Files.
I had this problem in VS2014 with an exe which was built for "Any CPU" with "Prefer 32 bit" set, whereas the referenced libraries did not have "Prefer 32 bit" (ie. 32-bit exe, 64-bit libraries).
Changing the exe to not "prefer 32 bit" fixed the problem with symbols, I think it's because the libraries are modified to match the bitness of the exe (during instrumentation) and the symbols no longer match.
This solution worked for me:
http://www.brothersincode.com/post/Matching-symbols-could-not-be-found-Performance-Profiler.aspx
You could also try it the other way around, meaning removing your dll as it is and trying to put the one from bin cause that can might as well be the other way around.
I have successfully managed to profile my class library - but only from within a console application. I have not been able to profile the class library during an ASP.NET app performance profiling session.
Some assorted links - which alas didn't solve my problem, but may give you some leads:
Run the Developer Command Prompt for VS2012
Then you can use this to VSPerfReport <yourreport.vsp> /debugsympath to figure out where SomeLibrary.dll should be loaded from
Troubleshooting tips http://msdn.microsoft.com/en-us/library/bb385766.aspx
The currently accepted answer helped me to get there, but I'll try to humbly give a little more straightforward instructions to those who are trying to accomplish exactly the same thing that I am, just in case I would save a couple of hard googling hours for somebody.
I was unsuccessfully trying to profile a WCF service that uses external assemblies, which are loaded by reflection at runtime and have this service to be triggered by my custom client. I had 2 problems: my WCF service just didn't start at all during profiling session (but while debugging it would always do it), and then when it did for some reason - Visual Studio coulndn't load the symbols for external assemblies.
So to get both things to work I needed to create an instrumentation performance session with the target set to my main WCF service along with the custom external assemblies and set the launch mode - Internet Explorer (otherwise the service wouldn't start). No exes or pointing to client from solution. Then I didn't start the profiler immediately, but modified it's properties in "Performance Explorer" window and added a binary of my custom client to the "Launch" tab to be launched 2-nd (right after the service inself). It also helped to have a proper "Service reference" right in the client (I don't really use it, I use shared assembly and generate channels using ChannelFactory) and launch the client in debug mode first (but without actually ever accessing a service). Maybe that's not the right way to do it, but it does the trick and I finally can profile my service after 2 days of googling - not very much docs available on this topic, and the accepted answer to this stackoverflow question is the best resource I found.
I'm using Visual Studio 2019 and stumbles the same issue while instrument profiling an ASP.NET web site.
Heavily inspired by the above JimmiTh solution, I added the [ProjectPath]/obj/Debug paths of the missing project to VS Options->Debugging->Symbols. After profiling again I could easily access the source code and get more accurate profiling diagnosis.
Related
I have a simple application using a product activation system offered by cryptlex (cryptlex.com).
The program works correctly on my computer, but when I try to run the program on another machine it returns this error:
I've already made sure that the dll is inside the executable folder and everything looks OK.
When I remove all part of cryptlex the program works perfectly on any machine (x86-x64)
I used depencywalker to check for errors and found these two in the executable that uses cryptlex:
Windows 7 64bits,
.NET Version: 4.0
You can use Process Monitor to record all file activities of the program. Set a filter for your executable. After reproducing the error, save the log as XML file.
Then run ProcMon Analyzer (note: I'm the author of it). It will analyze the file and give a list of DLLs that were not found.
You could also do that manually, but note that some DLLs may not be found at first, but later be found when looking in the %PATH% environment variable etc. The tool will remove all those entries which have PATH NOT FOUND first but SUCCESS later.
While the DLL is present, have you checked the bitrate?
Most C# projects default to building against Any CPU - if the DLL is specific to a bitrate (ie x86 or x64) then it might be that the program picks the wrong bitrate on end machines (usually x86) but the right one on your machine (x64). This is usually best resolved by building out different x86 and x64 versions; it's messier, but only .NET itself is good at using the Any CPU paradigm.
The exception should have detail about what DLL in particular was not found - maybe look closer?
GPSVC and IESHIMS missing should not be a problem; as indicated by the hour glass, they're deferred dependencies anyway.
I'm working on a game written in C# using VS2013 and monogame. However, monogame doesn't support the XNA content pipeline (still), so the going advice is to build your content separately using Microsoft's XNA and VS2010. Since I didn't want to clutter my primary development machine (Win8) with VS2010 et cetera, I created a Win7 virtual machine to run Win7 along with VS2010 and all the tooling I need to build my content. All my project and solution files have corresponding 2010 versions, and the 2010 solution only has the necessary projects to build the content.
I can successfully build the content, but only if it's present direcly on the VM's hard disk (C:\). If I map a local drive to a network share on the host machine and attempt to build, I get a build time error. Why do I want to do this? Because I want a single copy of the source tree so I can iterate at a decent speed. It's just far too painful and error-prone if I have a separate source tree in the VM.
Here's the build error I get:
Error loading pipeline assembly "S:\Src\ContentPipelineExtension\bin\x86\Debug\Newtonsoft.Json.dll".
I have S:\ mapped to my network share. Newtonsoft.Json.dll exists at the indicated path.
I have tried:
specifying /verbosity:d when building to see if any more information is output. There isn't.
attaching a debugger to the MSBuild.exe process with break on any exception enabled. It never breaks.
using subst instead of Windows Explorer's drive mapping tool (it might be using subst behind the scenes, but I wanted to be sure).
debugging MSBuild, but I hit the "mismatched leave" bug when I did so.
applied the workaround for the mismatched leave bug and debugged the build simultaneously on both C:\ and S:\. In both cases, I put a breakpoint right before XNA's BuildContent task was called. I let both builds run until they hit this breakpoint, and then I opened the locals windows, side-by-side. I compared all locals and found no difference apart from the expected C:\ versus S:\ path roots.
spelunking through the XNA code in ILSpy to try and figure out where it's going wrong, but have had no luck with that either
enabling full trust on the network share in CAS by executing: CasPol.exe -m -ag 1.2 -url file://S:\* FullTrust. No change in behavior.
enabling Fusion Log Viewer (fuslogvw.exe) and checking out its log. It says it has successfully loaded the assembly!
added <loadFromRemoteSources enabled="true"/> to my MSBuild.exe.config. No change.
Why does the build fail when running off my mapped S:\ and succeed when a copy of the source is placed on my C:\?
UPDATE: I just found the most awful work-around. I modified my ContentPipelineExtension project's Output Path such that it is an absolute directory on my C:\. This allows the build to complete successfullly, but is obviously far from ideal.
Here is a hack I used. It's not a satisfying answer (and I won't mark it as accepted), but in the absence of a better solution, it will save me an enormous amount of time and pain.
I edited my 2010 project files and changed my output paths to something like this:
<OutputPath>$(TEMP)\ContentPipelineExtension\bin\x86\Debug\</OutputPath>
The TEMP environment variable resolves to a folder on C:\ and saves me hard-coding a specific path. Now I can build the project from my Win7 VM using the same source tree as I use in my primary Win8 machine.
I am desperately trying to deploy an ActiveX for IE developed in C# as a CAB archive. I have read many resources (some of them from StackOverflow) and it appears a lot of people are having the same problems. I have tried 3 solutions: a) creating a CAB VS project, b) manually creating a CAB using CABARC with a COM registration in INF and c) manually creating a CAB with launching msiexec. None of them worked. I even tried d) creating a bootstrapper which launches msiexec to no avail (because some people suggested simply launching msiexec on Vista can't work).
I am running Windows Vista but my project fails to run even on IE6 on XP.
When I install ActiveX using MSI, all is fine on ALL Windows. Apparently CAB thing is not working and I could not find a proper way to debug this whole process yet.
Any help is appreciated.
Update: Note that this old but excellent answer is still a very good outline for how to approach solving this problem, at least as along the evolutionary scale as Win7 and IE11. I just succeeded making it all work using the Answerer's Firebreath.org toolset as a jumping off point. It's not simple but it can be done. I've added a reference to that project to the reference list below since it may make a more logical jumping off point for current developers than this overview is.
Hooray - I have just finished an identical project, so you'll be pleased to know that it's actually possible. I have only tested this on XP - I understand there may be issues where Vista/7 don't allow msiexec to be called.
Given that you have an assembly correctly exposing a COM interface, I did the following:
Strong-named the assembly.
Created an INF file
Created an MSI using the Visual Studio 2008 "Setup Project" template.
Created a CAB file using "iexpress.exe" bundled with Windows XP.
Create INF file
The *.inf file I used looks like:
[version]
signature="$CHICAGO$"
AdvancedINF=2.0
[Setup Hooks]
install=install
[install]
run=msiexec.exe /package """%EXTRACT_DIR%\SampInst.msi""" /qn
The only bit you should need to change is the SampInst.msi. Note I would use an 8.3 filename, as long filenames can cause issues. While testing, I would not use the qn switch either, as that is a silent install.
Create the Installer
The installer has to do only one thing, and that is register the assembly by calling RegAsm on it. Most installers will provide some method to easily do this. For example, an installer created through VS 2008 will simply need to have the “Register” property of the assembly set to “vsdrpCOM”. Note that vsdrpCOM should be chosen as it generates the appropriate registry entries at build-time. The vsdrpCOMSelfRegistration setting is likely to fail as it calls RegAsm at run-time, and will thus not work for non-administrators.
Package the installer into a CAB file
This can be done by any cab archiver. Windows XP contains iexpress.exe, a wizard driven archiver, while Microsoft’s CAB SDK contains cabarc.exe. Other 3rd-party tools are also available.
Note that you will need to reserve space in the CAB file for code-signing if you are going to sign the CAB.
You will need to CAB the INF file, and the MSI file. You will not need to CAB the Setup.Exe file.
Handy hint: The VS2008 Setup Project project type allows you to set a post-build step in the properties, so you can build and CAB in a single step. My post-build step looks like:
cd "$(ProjectDir)"
"%WINDIR%\System32\Makecab.exe" /f "VboCslib.ddf"
The DDF file format is documented.
Sample HTML page
The object tag is used to point to the cab file containing the installer. A very simple HTML page which would deploy an ActiveXControl would be:
<html>
<head></head>
<body>
<!--
ID : The id of the ActiveX control to be used in JavaScript.
CLASSID : The GUID associated with the ActiveX control.
CODEBASE: The location containing the CAB installer for the ActiveX
control. This could be a URL, or a relative path.
-->
<OBJECT ID="MyActiveXControl"
CLASSID="CLSID:FC36FAE1-48E0-4f6b-B469-E1B5A8C6D1AC"
CODEBASE="cabfiles\SampleCabFile.CAB#version=1,0,0,0">
</OBJECT>
<script>
MyActiveXControl.SomeMethod();
</script>
</body>
</html>
Handy hints
Ensure your installer installs on a "per-user" basis, not a "per-machine" basis. This will make it more likely to install if the user does not have admin privileges.
Trouble-shooting
Internet Explorer 6 actually provides a really useful diagnostic aid. Clear your Temporary Internet Files, then navigate to the web-page. If the installation does not work, go to your temporary internet files and you will see a couple of files in there. One of these will be an error log starting ?CodeDownloadErrorLog. Drag it to your desktop and open it in notepad, and it will give details on what it was trying to do when it failed.
References
Microsoft KB247257 – Steps for signing a .cab file
MSDN – About INF File Architecture
SN.EXE - Code Strong Programs with Strong Names
Nikolkos Craft – How To: Deploy .NET ActiveX Control
CodeProject – Create ActiveX .NET Step by Step
CodeProject – Downloading C# ActiveX Components through CAB file
MSDN - ALLUSERS Property (Windows)
MSDN – Non-Admin ActiveX Controls
MSDN – Microsoft Cabinet Format
Update: Firebreath.org has a toolset for generating browser plugins for many platforms. The IE/ActiveX code to solve the problem posed here is just a subset. But as of 6 Nov 2014, I found it easier to start with Firebreath and its instructions than to try to build up my dev environment and roll all my own solutions from scratch.
I am using Visual Studio 2010 Professional Edition, and Windows Vista.
Firstly, I have this code. As you can see, it will crash the program!
using System;
namespace Crash
{
class Program
{
static void Main(string[] args)
{
string a = null;
if (a.Length == 12)
{
// ^^ Crash
}
}
}
}
The program will crash on the if statement. Now, I want to find out that it crashed on that if statement.
If I "Start without Debugging" from Visual Studio, Crash.exe crashes. It uses 1,356kb of memory. I get the Vista option of Close Program/Debug. If I choose Debug, I can open a new instance of Visual Studio, and it points me to a NullReferenceException on the if statement. This is good.
Now let me assume that it crashes on another computer, and I get them to give me a Dump File via Task Manager. It is 54,567kb. Why so big! It's vast! Anyway, I am less interested in that (slightly)
If I open that dump with Windbg, I get very little of use to my untrained eye:
Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [C:\Users\Richard\Desktop\Crash.DMP]
User Mini Dump File with Full Memory: Only application data is available
Symbol search path is: SRV*C:\SYMBOLS*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows Server 2008/Windows Vista Version 6002 (Service Pack 2) MP (4 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS Personal
Machine Name:
Debug session time: Sat Jan 15 11:07:36.000 2011 (UTC + 0:00)
System Uptime: 0 days 4:24:57.783
Process Uptime: 0 days 0:00:05.000
........................
eax=002afd40 ebx=77afa6b4 ecx=002afd48 edx=00000001 esi=001cdaa4 edi=00000000
eip=77bf5e74 esp=001cda5c ebp=001cdacc iopl=0 nv up ei ng nz ac pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000297
ntdll!KiFastSystemCallRet:
77bf5e74 c3 ret
However, this is of less interest to me. As far as I can tell, I need to write commands in to get useful output, and Visual Studio is better.
So I open it with Visual Studio. I can choose to "Debug with Native Only", but I get lots of things that mean something to clever people like you, and I am not clever! I get these two screens:
So, my question:
How do I show Visual Studio to my source code?
Also, is there a way to get a smaller dump file? It seems ridiculously big, even after compressing. I don't understand why there couldn't be one which is only just a tiny bit bigger than the program's footprint, and still get a nice debugging, with the source code.
The much advertised feature that Visual Studio 2010 allows you to debug crash dump files and step through the managed source code comes with a gotcha: it works only for .NET 4.0 assemblies. Here are the steps:
Create a crash dump file on another computer using the Task Manager
Open the solution in VS2010
Open the .DMP file (File->Open...)
Click on Debug With Mixed (This will be visible only for .NET 4.0)
Source code will open and you will be able to inspect the exact cause and location of the exception
As far as debugging with native only is concerned Visual Studio is no more useful than WinDbg.
The tooling you are using here wasn't ever designed to troubleshoot crashing managed programs. Minidumps and Windbg is what you use to find out what's wrong with code written in C or C++. Pretty important tools, these are languages whose runtimes have no support for the kind of goodies you can get out of a crashing managed program. Like an exception with a stack trace.
The reason the minidump sizes are so different is because of the mini in minidump. By design, it was meant to capture a small snapshot of the process. The relevant argument is DumpType in the MiniDumpWriteDump function. There's really clever code in this function that can figure out what parts of the process state don't need to be recorded because you are not likely to use it in the debugger session. Which you can override by providing additional dump type flags. The minidump that Explorer generates has all of those flags turned on, you get the whole kit and caboodle.
Which is actually pretty important for a managed program. The heuristics used by this minidump creator is one that's only appropriate for unmanaged code. Debugging a managed program dump only works well when you include the entire garbage collected heap in the dump. Yes, that will be a large dump, mini doesn't apply anymore.
Your next problem is that you are getting the soul of the machine view from the minidump data. Your screen shots are showing the machine code. You happen to be located inside of Windows in those shots, note how ntdll.dll is on top of the stack. The mscorwks.dll entries are the CLR. Further down, out of view, you ought to see stack frames from your own code. You'll however see the machine code that was generated by the JIT compiler. Not your C# code.
There's a Windbg add-in called sos.dll that extends the command set of Windbg to be able to inspect managed data. Just google "sos.dll" to get good hits. This is however still a looong way away from the kind of debug experience you'll get out of the Visual Studio debugger. Which is intimately aware of managed code, very unlike Windbg or the VS debugger that can load minidumps. Sos was really designed to troubleshoot CLR bugs.
There were no dramatic improvements in VS2010 other than the minidump info page you now see. Which really doesn't do much at all. I suspect the Debugger Team to have this on their todo list, there are surely some fundamental problems to overcome. Particularly in the minidump format and creation code. Use connect.microsoft.com to provide feedback, they pay attention to it and let votes affect their priority list.
You should be supplying the related pdb (program database) file to the debugger so it can load the symbols. Also to get a better view, use Microsoft Public Symbol server. This article contains information on it.
When compiling a library or an application (e.g a Console Application in the Visual Studio IDE), in the Debug folder of the application, apart from the .dll or .exe, there will be one more file with extension ".pdb".
What is the exact usage of this .pdb file?
PDBs contain debugging symbols, so you can ship a compiled binary to your customer without exposing your source code algorithms and other private details to them.
If your app goes wrong on a customer site, you can get a crash dump from them (using DrWatson), bring it back to your dev workstation and debug the crash, the debugger will use the symbols file in conjunction with the crash to show you the source code, data structures etc. In many cases, all you have to do is open the crash dump and the debugger will take you directly to the source code of the exception, and show you variables and threads too.
That's the primary use of them, they're invaluable when a customer reports a crash. The things you need to know about using them though - they are only valid for the build that created them, so if you recompile, your symbols file is next to worthless.
John Robbins has an excellent article why you would use them.
John Robbins has written some really great articles on PDBs lately:
PDB Files: What Every Developer Must Know
Visual Studio Remote Debugging and PDB Files
How Many Secrets do .NET PDB Files Really Contain?
Do PDB Files Affect Performance?
Correctly Creating Native C++ Release Build PDBs
PDB's allow debugging of applications, for examlple when they crash or if you have a minidump. They also allow you to find more detail about errors when outputting exceptions to logging (they will give a more complete stacktrace with line numbers rather than just showing the name of the function where the error occurred).
PDB's are useful when you want to do remote debugging as well.
Keeping the PDB's together with your installed application makes it possible to hook up visual studio remotely to the client's production environment and debug the application when necessary.
Well you've given yourself a big clue in your title.
It's the file Visual Studio needs to be able to debug your application.
This MSDN page has more information.
A program database (PDB) file holds debugging and project state information that allows incremental linking of a Debug configuration of your program.
As far as i know, they contain debugging information, such as line numbers, variable names, etc.