Fri
Jan 19
2007

CLR Debugging

To get started with debugging the CLR see Tess Ferrandez’s post on getting .NET memory dumps and Associating Windbg with .dmp files. See her other posts for mining these dumps for useful information.

To debug ASP.Net worker process crashes, create a batch file named debug_crash_iis5.bat in windbg folder with:
cscript.exe adplus.vbs -crash -pn aspnet_wp.exe -FullOnFirst

To dump (non-crashing) exceptions from ASP.Net, create a batch file named debug_monitor_iis5.bat with:
cscript.exe adplus.vbs -pn aspnet_wp.exe -c TrackCLR.cfg

and another file named TrackCLR.cfg with:

<ADPLUS>
  <SETTINGS>
   <RUNMODE>CRASH</RUNMODE>
  </SETTINGS>
  <PRECOMMANDS>
   <CMD>!load clr10\sos</CMD>
  </PRECOMMANDS>
  <EXCEPTIONS>
   <OPTION>NoDumpOnFirstChance</OPTION>
   <OPTION>NoDumpOnSecondChance</OPTION>
   <CONFIG><!-- This is for the CLR exception -->
    <CODE>clr</CODE>
    <ACTIONS1>Log</ACTIONS1>
    <CUSTOMACTIONS1>!cen;!clrstack;.dump /ma /u c:\exceptiondump.dmp;gn </CUSTOMACTIONS1>
    <RETURNACTION1>GN</RETURNACTION1>
   </CONFIG>
  </EXCEPTIONS>
</ADPLUS>

After opening a .dmp file with windbg, the most useful commands are:
!clrstack
!dae
!help

Tue
Jan 16
2007

Recompile All Oracle Objects

exec dbms_utility.compile_schema(schema => 'MYSCHEMA', compile_all => FALSE);

          
Thu
Jan 11
2007

Catching Unhandled ASP.Net Exceptions

Exceptions that occur off the worker process thread are silently swallowed by ASP.NET 1.1. Use the method described in MS article 911816 to create an HttpModule to catch the exceptions. The follow is adapted for ASP.NET 1.1 without requiring registration in the GAC and a strong name. It also logs to the EventLog as well as sending an email as

Add the following code to UnhandledExceptionModule.cs:

using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Web;
 
namespace WebMonitor {
    public class UnhandledExceptionModule: IHttpModule {
 
        static int _unhandledExceptionCount = 0;
 
        static string _sourceName = null;
        static object _initLock = new object();
        static bool _initialized = false;
        static string _mailServer = "mymailserver";
        static string _mailTo = "abc@xyz.com";
 
        public void Init(HttpApplication app) {
 
            // Do this one time for each AppDomain.
            if (!_initialized) {
                lock (_initLock) {
                    if (!_initialized) { 
 
                        _sourceName = string.Format(CultureInfo.InvariantCulture, "ASP.NET {0}.{1}.{2}.0",
							System.Environment.Version.Major, 
							System.Environment.Version.Minor,
							System.Environment.Version.Build);
 
                        if (!EventLog.SourceExists(_sourceName)) {
                            throw new Exception(String.Format(CultureInfo.InvariantCulture,
                                                              "There is no EventLog source named '{0}'.", 
                                                              _sourceName));
                        }
 
                        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);
 
                        _initialized = true;
 
						LogMessage("UnhandledExceptionModule started", "", EventLogEntryType.Information);
 
                    }
                }
            }
        }
 
        public void Dispose() {
        }
 
        void OnUnhandledException(object o, UnhandledExceptionEventArgs e) {
            // Let this occur one time for each AppDomain.
            if (Interlocked.Exchange(ref _unhandledExceptionCount, 1) != 0)
                return;
 
            StringBuilder message = new StringBuilder("\r\n\r\nUnhandledException logged by UnhandledExceptionModule.dll:\r\n\r\nappId=");
 
            string appId = (string) AppDomain.CurrentDomain.GetData(".appId");
            if (appId != null) {
                message.Append(appId);
            }
 
            Exception currentException = null;
            for (currentException = (Exception)e.ExceptionObject; currentException != null; currentException = currentException.InnerException) {
                message.AppendFormat("\r\n\r\ntype={0}\r\n\r\nmessage={1}\r\n\r\nstack=\r\n{2}\r\n\r\n",
                                     currentException.GetType().FullName, 
                                     currentException.Message,
                                     currentException.StackTrace);
            }           
 
			LogMessage("UnhandledExceptionModule exception", message.ToString(), EventLogEntryType.Error);
        }
 
		void LogMessage(string subject, string message, EventLogEntryType severity)
		{
			try
			{
				EventLog Log = new EventLog();
				Log.Source = _sourceName;
				Log.WriteEntry(subject + "\n" + message, severity);
			}
			catch  {}
			try
			{
				System.Web.Mail.MailMessage msg = new System.Web.Mail.MailMessage();
				msg.Body = message;
				msg.To = _mailTo;
				msg.Subject = severity.ToString() + ": " + subject;
				msg.From = _mailTo;
 
				System.Web.Mail.SmtpMail.SmtpServer = _mailServer;
				System.Web.Mail.SmtpMail.Send(msg);
			}
			catch {}
		}
 
    }
}

Open a Visual Studio Command Prompt and run: csc /t:library /r:system.web.dll,system.dll UnhandledExceptionModule.cs

Place the DLL in your bin folder

Add following to your web.config:

<system.web>
  <httpModules>
    <add type="WebMonitor.UnhandledExceptionModule, UnhandledExceptionModule" name="UnhandledExceptionModule"/>
  </httpModules>
</system.web>

Here is sample code to trigger an unhandled exception

using System.Threading;
Timer t;
private void btnTest_Click(object sender, System.EventArgs e)
{
  t = new Timer(new TimerCallback(t_Elapsed), null, 250, Timeout.Infinite);
}
private void t_Elapsed(object state)
{
  throw new Exception("My unhandled exception");
}
Thu
Jan 4
2007

Could not load type ‘Namespace.Global’ with Network share

This occurs when running an ASP.Net website located on a network share. Configure .Net to trust assemblies from the network share. Solution from heromull.

1. Open .Net Framework 1.1 Configuration
2. Runtime security policy > machine > code groups > all_code
3. Right-click and create new.
4. Enter any name, URL, \\myserver\share\optionalfolder\* (note the * is important)
5. Restart IIS

Wed
Jan 3
2007

VSS Best Practices

Team Development with Visual Studio .NET and Visual SourceSafe

© 2009 Brian Low. All rights reserved.