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.
Related
After some months of inactivity, I decided to work with Microsoft Visual Studio (C#) again.
After some clicks on "start debugging" I got windows error (I think svchost.exe has stopped working) and I don't know if this was relevant with what I'm about to say, but I'm not getting any errors when for example I'm calling an array out of bounds.
The program just doesn't execute the code assossiated with the error (I've noticed the array and file I/O problems) but continues to run normally which is driving me crazy because I have to click "start debugging" after I write each line of code just to be sure I'm correct.
So, Debug > Exceptions, it's chaos over there and I haven't touched it before.
Any help would be appreciated.
EDIT: I've restarted 3 times my computer and did the Clean and Rebuild just now (the project) and nothing changed.
EDIT2: Sorry if it's confusing, here are some new info:
public partial class frmMain : Form
{
PictureBox[] pic = new PictureBox[120];
public frmMain()
{
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e)
{
// Creating pictureboxes
for (int i = 1; i <= 199; i++) //199 instead of 120 or 119 and the rest of the for isn't executed plus no error or warning displayed.
{
pic[i] = new PictureBox();
EDIT3: Below is another example. If I try to read a non-existent file without the try-catch sequence, then the whole pic[] matrix is like being unloaded from the memory when the program runs.
pic[i].Image = Image.FromFile("H:\\My Pictures\\" + i + ".jpg");
EDIT4: Thank you for your time. I tried "Release" instead of "Debug" and the problem was fixed for a while.
When I decided to press "Continue" instead of "Break" on the "OutofRangeException", Windows popped this message: "Windows had to run the program on compatibility mode". Now when I press "start debugging" it's like before...
It sounds like you may be dealing with this issue:
Something swallowing up unhandled exceptions?
Basically, when building on 64 bit machines, exceptions are sometimes swallowed.
I believe there may be a hotfix for it, as outlined here:
https://connect.microsoft.com/VisualStudio/feedback/details/357311/silent-exceptions-on-x64-development-machines
Here is the hotfix: http://support.microsoft.com/kb/976038
Otherwise, try setting the target build to x86 rather than x64 or "Any CPU". Also try running in release mode and see if the exceptions occur.
If this is not the problem, then you may need to re-install Visual Studio. If you're using Visual Studio Express, why not upgrade to a more recent version than 2008?
EDIT:
Also, try applying all the service packs and patches to the OS as well. If you're using Windows 7, you should be on SP1 for sure. You should also make sure you are using Visual Studio 2008 SP1 and all patches.
You have hit a known misfeature in Windows / .Net / C# / Wow64, that happens when Form.Load event handlers throw exceptions.
VS2010 does not show unhandled exception message in a WinForms Application on a 64-bit version of Windows
From Hans Passant's answer:
This is a nasty problem induced by the Windows wow64 emulation layer
that allows 32-bit code to run on the 64-bit version of Windows. It
swallows exceptions in the code that triggers the Load event.
Preventing the debugger from seeing it and stepping in. This is
apparently hard to fix, the Windows and DevDiv groups at Microsoft are
pointing fingers back and forth. DevDiv can't do anything about it,
Windows thinks it is the correct behavior, mysteriously as that
sounds. It is only a problem with a debugger attached, your code will
bomb as usual without one.
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.
I have a dump file from an mvc4 web api that is pretty much crashing the w3wp.exe process (the bits are based off a debug build). I started diag debug diag to get the .dmp and there are parts of the .net stack .html summary for the crash report of the .dmp file that reference some of my methods which are probably suspect including a cacheing object as well as a db context that are somehow crashing due to systemobject dispose (something is going out of scope when I reference something..either cache or db context or both). It makes sense that those items are contained in the list summary of the .html .dmp report but they really don't tell me where the code is throwing.
With the .dmp file at hand when I try to load it within Visual Studio to Debug and link back to source code I get the following errors:
1) Debugging inforamtion for w3wp.exe cannot be found or does not match.
Symbols loaded (source information stripped). Do you want to continue
debugging?
continue selected...
2) Unhandled exception at 0x000007fefdc3cacd (KERNELBASE.dll) in
w3wp_MyApp_PID_36504_Date__02_14_2013__Time_04_32_57PM_276_First
chance exception 0XE0434352.dmp: 0xE0434352: 0xe0434352
I have the Debug/General "microsoft symbol servers" checked to presumably down any necessary symbols and linkage. However, when I continue and break after the last error, there are no references to my code within the call stack or the Debug/Windows/Paralell Stacks but I dont' see any of my classes or object called or spelled out. All is see are offsets and the disassembly with a carret as the break point at some "mov" operation.
I've followed this troubleshooting/debugging link to book but still cannot get any symbols to resolves to locals or see any of my method names being called.
http://blogs.msdn.com/b/tess/archive/2009/06/16/first-look-at-debugging-net-4-0-dumps-in-visual-studio-2010.aspx
ASK: How can I link this .dmp to the exact line of code that is throwing? Thanks!
Load it in windbg.
Load sos (in .NET 4 .loadby sos clr or in previous versions .loadby sos mscorwks)
!Threads
At this point you should see an exception in the relevant thread. If not, you might need to go searching for it using !DumpHeap -type Exception or something similar.
Use !pe <address> to examine the exception.
I'm happy to help if you get lost. Windbg is not easy.
I'm looking for an extension for Visual Studio where in debug mode it's possible to single step through the intermediate language beside C#.
I'm not looking for a solution to debug managed and unmanaged code.
What is your purpose? Is your IL generated by C# compiler or dynamically produced at run time? If the former one, you can use a trick of re-compiling your binary through ilasm.
Compile C# code as you normally would. It does not matter if it is optimized or not, but you have to specify compilation option to produce full PDB symbols.
Use ildasm to convert your binary to .il file. It is option Dump in the menu.
re-compile the .il file to get a new binary (and a new symbols)
ilasm .il [/exe|/dll] /debug
Now when debugging that specific assembly you will see IL code rather than C# code. You will also see a matching lines from original C# file if you select appropriate option in step 2.
For the case of dynamically generated IL, I would simply use WinDbg with SOS extension. It can dump IL and step through it, but it takes a bit to get used to.
Although not strictly a Visual Studio extension as the OP requested, there's now a maybe even better way to do this using dnSpy, a comprehensive, standalone, open-source .NET debugging tool. The tool actually does much more than just debugging; for example it allows direct editing of .NET and native (PEFile) assemblies, de-obfuscating them, browsing and modifying the raw managed and native headers, content, resources, BAML, and metadata, and more that I probably haven't discovered.
For the purposes of the discussion on this page, be sure to check out the IL interpreter section of the dnSpy project. Exactly as requested by the OP, this is the library that implements an IL interpreter for simulating the (pretend) execution of the IL code in parallel with the debugger's (actual) native instruction single-stepping, for the purposes of displaying the state of the (logical) IL execution stack. I believe there's some excellent x86/x64 disassembly rendering built-in to the debugger as well, if needed. Kudos to the developer of this tour-de-force app.
I don't think that an external disassembler is necessary here. When you're debugging in VS 2010 (though not Express) you can right-click on the code window and select "Go To Disassembly" to step through the IL code. Could that be what you're looking for? Read more here
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.