PDB file and error handling? - c#

We have a windows form application running across different customers, when they get errors we log into a database & using that stack information that is logged, we correct the issue.
However there are issues that occur only in production, the stack shows for example
CalculateTotals(method name) :NullReferenceException: Object reference not set to instance of an object.
The CalculateTotals is a method name, that has lots of sub-method calls & more lines, i am not able to get the exact line # of the code where it fails.
My application's PDB file is not sent to customers (when they do installation),
how do i keep a copy of that .PDB file (may be in a remote location and
not make it part of installation) and use that to
debug the errors & get the exact line?

You can include the pdb-files in release if you want to, but you can also use IntelliTrace to debug data from production in Visual Studio.
In short, IntelliTrace:
IntelliTrace plays a role similar to that of a black box in a plane. It keeps track of important points in your programs execution and allow you to play back what happened at those points at a later time.
Have a look at these blog posts:
Running IntelliTrace on Applications in Production
IntelliTrace - what and how.
And of course, you can search the web and find more about IntelliTrace.

You will only get line number info in the exception's stack trace when the CLR can find the PDB file at runtime. You are making this difficult by wanting to do this from a remote location but it is not impossible. The underlying API that the CLR uses is DIA (Debug Interface Access) which in turn uses the Debug API.
You'd have to setup the machine the same way you'd setup a debug session to have the debugger use a symbol server. Requirements are that you first setup a symbol server that can be accessed across the Internet, similar to the Microsoft Symbol Server. Then set the _NT_SYMBOL_PATH environment to reference that server. The core MSDN Library page that describes this is here. Beware that this is not easy to troubleshoot if it doesn't work.
An entirely different approach is that you create a minidump from the crashed process. You'll need to pinvoke MiniDumpWriteDump(). Beware that a good minidump for a .NET process is not very mini, you'll need the plumbing to have enough storage and somehow get it to your machine.

Related

Unable to get Application Insights to show debugging telemetry

I am a total noob with Application Insights, and sadly for a whole day of trying I have been unable to get it working at all. I tried with the following code:
this.telemetryClient = new TelemetryClient(TelemetryConfiguration.CreateDefault());
this.telemetryClient.TrackTrace($"Test", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Warning);
But when I go to the application insights window and show all telemetry from the current debugging session there is nothing logged. One user said an ApplicationInsights.config file is missing (and that an empty one would do fine for debugging), I created one but it changed nothing.
Then I tried the simplest console app I could find - https://learn.microsoft.com/en-us/azure/azure-monitor/app/console . I don't have an instrumentation key, and from the hundreds of forums I read today, if you leave it blank it should still appear in the debugging telemetry. Alas, still nothing in Application Insights.
How can I get it working? I just want to see a single Trace message in the Visual Studio Application Insights window when queried for "debugging telemetry".
I used to work on this stuff and the way it generally works, the extension tries to figure out if it should watch for debug output, and if it doesn't recognize the project type, we do nothing (to avoid doign work in the debugger when we don't need to). in this case, console apps aren't a "known" supported project type.
IIRC, to get debug output I believe you need to do 2 things, of which you've done 1:
1) add an ApplicationInsights.config file at the root of that project
2) add an application insight resource id to to the csproj:
<ApplicationInsightsResourceId>/subscriptions/abc</ApplicationInsightsResourceId>
i don't think the resource id even needs to be valid, but if it does even better, because then other things can light up, like exceptions codelens, various links to the portal/etc.
you migth only need to do #2?
i think that if you do the above and restart vs/reload the solution, you should see the debugger integration try to do work when the debugger starts. (it used to!)

How do I obtain a crash dump

I need to get a crash dump from a program. How do i get it?
The Program is written in C#. What exactly is a crash dump? When is it created? Where is it saved?
How do i read it?
Since you are saying C# I assume you are using the Windows platform.
A crashdump, or just dump, is the complete memory snapshot and other related system info of a process at a particular point in time. Dumps can be used to debug program crashes, hangs, memory and resource leaks and probably more problems I have not listed here.
In the case of crashes and hangs the first piece of data you want to obtain from a crash dump will be the callstack. This indicates the point of a crash or the point at which an operation blocked and never returned so the program sits and does nothing.
For resource leaks multiple memory dumps of a process can be collected over a period of time and examined to see which objects in memory are growing the most. This can help narrow down which parts of the code are causing the leak. To learn more about debugging specific issues I highly recommend this blog.
There are a few ways to capture a dump file.
Procdump (http://technet.microsoft.com/en-us/sysinternals/dd996900.aspx)
Visual Studio 2010 (http://msdn.microsoft.com/en-us/library/vstudio/fk551230(v=vs.100).aspx)
WinDbg - Not to bad but more intimidating than other tools
With procdump you can simply do:
c:\>procdump.exe -ma YourProcessName.exe
The result of this command will be a full memory snapshot of YourProcessName.dmp written to c:\ . The -ma switch specifies dumping a complete memory image. If you are debugging a crash or hang you can likely get away without the -ma switch. Keep in mind without the full memory dump when you go to examine data structures you probably won't have valid data. Without the full memory dump you will still have callstack data which is often good enough for crashes and hangs. I typically error on the side of harddrive space is cheap so collect the full dump.
Procdump will also automatically take dumps at time intervals or when a specific condition is met. Read the documentation at the link above for more info. One switch I would recommend is -e.
c:\>procdump.exe -ma -e YourProcessName.exe
Instead of writing the dump immediately it will only write it when your program crashes.
With Visual Studio 2010 you can attach to the process with the debugger and save a dump file. (Keep in mind when you F5 debug your program Visual Studio automatically attaches). When your program is in a "break state" (breakpoint, unhandled exception, crash) the Debug menu will have the option to Save Dump As.... Then you can save that dump any where you would like.
Since you mentioned C# you are very likely collecting managed dump files. The easiest way is to use Visual Studio 2010. Simply, open up the dump file you created as you would any other file and begin debugging.
However, if that is not an option you can always use VS2008 or WinDbg with the SOS extensions. I do highly recommend Visual Studio 2010 though as SOS extensions and WinDbg in general have a pretty steep learning curve. To learn more about SOS check out these MSDN articles here and here.
Another reason I recommend using Visual Studio or procdump is that they will collect the dump file you expect. I recommend steering clear of Task Manager's "Create Dump File Tool". The reason being it will collect 64bit dumps of 32bit processes which are overly difficult to debug.
On Windows XP you can create a dump file with this utility:
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=e089ca41-6a87-40c8-bf69-28ac08570b7e&displaylang=en
Once installed browse to the installation directory and run
userdump PID
from the command line where PID is the PID of the process you want to get a crash dump of (you can find this in task manager, but you might need to add the column to the standard view).
This file can then be opened in Visual Studio - you just need to make sure you have the symbols built.
In Windows 7 just right click on the process in Task Manager and select "Create Dump File"
Use ADPlus. It comes with the Debugging Tools for Windows.
It'll create folders of crash dumps beneath it's home directory. You can analyse them using WinDbg afterwards.
Luke, a crash dump is a whole bag of data related to the status of your application at the moment the crash has happened, to dump it means to record all those information somewhere, typically in a text file.
a basic approach is to log the whole stacktrace when an exception happens so you could investigate later and see what method has failed and thrown which exception, what the parameter values were and so on. This is not really a crush dump but helps a lot in many cases.
There was something developed recently by MS about crash dumps and application crashes, I think it was related to Windows 7 actually...
see here: Application Recovery and Restart
http://msdn.microsoft.com/en-us/library/cc948909(v=vs.85).aspx
You can also try using WinDbg
http://www.windbg.org/
A crash dump is when the contents of RAM memory and certain parts of the processor are copied to a file. This file is created at the critical point of an error and can be used to debug the problem.
This has worked for me in the past. It's a keyboard shortcut to crash dump in windows.
* Start Registry Editor.
* Locate the following registry subkey:
o HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\i8042prt\Parameters
* On the Edit menu, click Add Value, and then add the following registry entry:
o Name: CrashOnCtrlScroll
Data Type: REG_DWORD
Value: 1
* Exit Registry Editor and then restart the computer.
http://vinaytechs.blogspot.com/2010/01/how-to-get-crash-or-hang-dump.html

SharePoint fails to load a C++ DLL on Windows 2008

I have a SharePoint DLL that does some licensing things and as part of the code it uses an external C++ DLL to get the serial number of the hardisk.
When I run this application on Windows Server 2003 it works fine, but on Windows Server 2008 the whole site (loaded on load) crashes and resets continually. This is not Windows Server 2008 R2 and is the same in 64 or 32 bits.
If I put a Debugger.Break before the DLL execution then I see the code get to the point of the break and then never come back into the DLL again. I do get some debug assertion warnings from within the function, again only in Windows Server 2008, but I'm not sure this is related.
I created a console application that runs the C# DLL, which in turn loads the C++ DLL, and this works perfectly on Windows Server 2008 (although it does show the assertion errors, but I have suppressed these now).
The assertion errors are not in my code but within ICtypes.c, and not something I can debug.
If I put a breakpoint in the DLL it is never hit and the compiler says:
"step in: Stepping over non user code"
If I try to debug into the DLL using Visual Studio.
I have tried wrapping the code used to call the DLL in:
SPSecurity.RunWithElevatedPrivileges(delegate()
But this also does not help.
I have the source code for this DLL so that is not a problem.
If I delete the DLL from the directory I get an error about a missing DLL. If I replace it, back to no error or warning just a complete failure.
If I replace this code with a hardcoded string the whole application works fine.
Any advice would be much appreciated, I can't understand why it works as a console application, yet not when run by SharePoint. This is with the same user account, on the same machine...
This is the code used to call the DLL:
[DllImport("idDll.dll", EntryPoint = "GetMachineId", SetLastError = true)]
extern static string GetComponentId([MarshalAs(UnmanagedType.LPStr)]String s);
public static string GetComponentId()
{
Debugger.Break();
if (_machine == string.Empty)
{
string temp = "";
id= ComponentId.GetComponentId(temp);
}
return id;
}
This could be security related:
An important point is that it works in a console app.
In a console app RunWithElevatedPrivileges has no effect since it emulates the app pool user for your worker process, a user that should have no special rights on the box itself.
In contrast a console app runs in context of the logged in user.
Try emulating a user with rights like when you run the console application specified here (with Undo() inside try/finally mind you!). When obtaining the token you can create an SPUserToken and establish site context using the SPSite constructor that takes a GUID and a SPUserToken
Theres several examples out there documenting this approach, here for example.
EDIT: oh and the reason it worked on 2003 could be that your app pool account had way too many rights ;-)
Why not use WMI to get the serial number of hard disk, thus avoids execution of unmanaged code. See this sample How to Retrieve the REAL Hard Drive Serial Number
That non-deterministic crashing behavior is often seen with memory overwrites/corruption; sometimes it matters (crash), sometimes you get lucky.
You might want to check into getting a crash dump and analyze it with WindDbg. Since you have the source you could re-build it with the various stack, heap memory protection and warning systems enabled (depending on your compiler) and see what you get.
I'd find out if it is a User Account Control related problem, you can try to disable it.
2003 doesn't have UAC.
Your app pool account might not have the right to retrieve this information?
In visual studio, go into the properties of your executable assembly, and under the debug tab, check the enable debugging unmanaged code option.
If the method your are importing belongs to a class, you need to add the mangled C++ name (e.g. 2#MyClass#MyMethod?zii) as an entry point to the DllImport attribute (run depends on the native DLL to get it).
You do not need C++ for that: http://www.codeproject.com/KB/cs/hard_disk_serialno.aspx
If i put a breakpoint in the DLL it is
never hit and the compiler says :
"step in: Stepping over non user code"
That's the debugger, not the compiler, and if you configured it properly it wouldn't do that. Look for the options calls "Use native debugging" and "Just my code". The first one should be on and the second one off.
This problem may happen due to one of the problems listed below.
the web part may not have the right permissions to call the DLL or
you may not have set the appropriate trust level for your SharePoint site.
For the permission you can use impersonation and for the trust level below site can help you.
http://msdn.microsoft.com/en-us/library/dd583158(office.11).aspx
I made a new C++ DLL from scratch which works fine when referenced as a console application on Windows Server 2003 and Windows Server 2008, but as soon as I reference it from the DLL in SharePoint the same things happens and it won't run.
It does find the DLL, but I think it has no permissions to execute it, even if I put it into the My Documents section and reference it directly!

VB control crashes my app

I am using this - otherwise excellent - vb tab control in one of my c# apps. When the app using it is installed on another machine, Windows tells the user in its usual friendly and descriptive manner that "The application encountered a problem and needs to close". I guess the control has some hidden vb-related dependency, but what can that be?
Any ideas guys?
Since the tab control appears to be managed code as well, your 'crash' is most likely an unhandled .NET exception.
Looking at the error details (by expanding the error dialog using the button provided for that purpose...) should give you the exception message, which should give you an idea of what's going on. If it's a missing dependency DLL, the name should be included in the message.
To get the full exception, including the stack trace, one of the following should work:
Least effort: in the first line of your own managed code, add an unhandled exception handler which shows the full exception in a message box or logs it to a file prior to rethrowing it
Medium effort: attach a debugger to the process on the client machine. If it's on your local network, setting up remote debugging should be trivial, and should also allow you to debug exceptions that occur prior to your first line of code executing (which may very well be the case if the error is binding-related...)
Most effort: obtain the crash dump file from the client machine, and look at the managed exception using Windbg and the SOS debugging extensions. Getting productive with the tools involved will take some time, but on the plus side will teach you valuable debug ninja skills that will allow you to tackle pretty much any 'mysterious crash'...
BTW, all standard 'VB dependencies' are part of the default .NET Framework install, so that's not your problem -- only the exact exception (and possibly stack trace) will tell you what's going on.
Click the 'What data does this error report contain?' button and there will be more descriptive info. (i.e. type of the thrown exception, module etc.).
For additional info see Dr. Watson vs. CLR.
Is the dll containing the control distributed with your app? Perhaps you have a dependancy in the GAC thay you are missing?

Finding the crash dump files for a C# app

An app I'm writing always crashes on a clients computer, but I don't get an exception description, or a stack trace.
The only thing I get is a crash report that windows wants to send to Microsoft.
I would like to get that dump file and investigate it myself, but I cannot find it.
When I "View the contents of the error report" I can see the different memory dumps, but I cannot copy it or save it.
You can use the Windows debugging tools to view the crash dump. To get the most use out of it, you'll need an exact copy of the symbols for that application (i.e. same version).
Have a look at Tess's blog for tutorials on how to use the Windows debugging tools. I refer to her blog constantly whenever I'm in need of analysing crash dumps.
Tess' blog was a great resource. Eventually I managed to figure out how to do remote debugging which means I didn't have to look at the crash dump.
For the general community, here are some links I found useful:
Remote debugging, how to set up and run it.
Crash dumps, how to save and debug them.

Categories

Resources