September, 2006

  • Never doubt thy debugger

    Sweet sorrow... remote debugging (and more)


    Continuing from my previous post on common causes for memory leaks, remote debugging is another ASP.NET feature that has the potentiality to either delight (uhm... am I exaggerating here...? smile_wink) a web developer or drive him completely crazy smile_baringteeth
    I remember 8-9 years ago, when I was a young technology passionate learning the basics of web development (HTML, CSS, ASP etc...), on my desk I just had a couple of programming books for beginners, my dial-up modem to download some online manuals and my copy of Office 97 for students. My editors at that time were FrontPage 97 and Notepad... so all I could do to debug my web pages were to use lots of Response.Write() to inspect variable values, and lot of brain work to try to understand where things were going wrong...

    With ASP.NET and Visual Studio .NET in these days developers still have to do lot of brain work, but for sure the tools now help a lot with debugging web applications... but what happens if the debugger has tantrums? smile_omg
    Here is a list of the common debugger problems I saw so far in my experience with Microsoft Support; this is not at all a comprehensive list, you can find out more doing some research in MSDN, Knowledge Base or your favorite search engine.

    "Unable to start debugging on the web server"

    1. Your IIS application is not configured to use “Integrated Windows Authentication”: make sure that the “integrated windows authentication” checkbox on the “authentication method” dialog box is checked
    2. Check whether “Enable HTTP Keep Alive” option in IIS is checked or not. If it is turned off, you may need to turn it on and try your debugging again

    "You do not have permission to debug the web server"

    1. Make sure that “Integrated Windows Authentication” is enabled. Probably, you enabled only “Basic authentication” for Directory Security in IIS
    2. If you are using “Integrated Windows Authentication”, you need to make sure that your user account has full control on the application directory
    3. If you created the web project with a full machine name like http://machinename.domainname.appname, Internet Explorer will recognize it as part of the Internet Zone, so the security settings for this security zone will impact your application and the logon type. In this case you need login with your current account also in the Internet security zone in IE: go to menu Tools -> Internet Options -> Security tab -> select the Internet zone -> click the Custom Level... button, scroll down the list of settings until you find User Authentication -> enable Automatic logon with current username and password

    "The project is not configured to be debugged"

    Make sure your application is configured to be debugged; to do this check that your web.config file contains the instruction debug="true".
    NOTE: please remember to set this to debug="false" when you deploy your application in production! See this and this.

    "The server does not support debugging of ASP.NET or ATL server applications"

    You may need to think about the order of installation between Visual Studio and IIS; If you install IIS after Visual Studio you will get this error. In this case you need to register the ASP.NET mappings in IIS with “aspnet_regiis.exe –i” from the .NET Framework installation folder (choose the version you want to restore).

    "Access is denied. Verify that you are an administrator or a member of the 'Debugger Users' group on the machine you are trying to debug. After being added to the 'Debugger Users' group, you must log off and log back on for the setting to apply"

    Quite self explanatory... smile_regular

    "Could not start ASP.NET or ATL server debugging"

    1. If you have installed the IIS Lockdown tool, find the urlscan.ini file and add "DEBUG" (case sensitive) into “[allowverbs]” section
    2. If your web server is also a domain controller and you created your project using the full domain name, you may need to change the URL of the project
    3. If your IIS is set to use dedicated IP as “Web site identification” (you can find this option in IIS setting with IIS MMC), you may see this error message. In this case, you need to change your project name to use the IP address directly. For existing project, you need to change project to use IP address than just machine name by editing the “.sln” and the “.webinfo” file
    4. If you modified the value “<httpRuntime maxRequestLength="#########" />” in your web.config, make sure that the value is not too big. The default unit is “Kbyte”, not “byte” so if you put too big number, it causes problem with debugging

    "Access is denied"

    To be able to attach to the ASP.NET worker process your account must be part of the "Debugger users" group and be an Administrator of the remote machine; as an alternative you can configure your ASP.NET worker process to run under the same account you'll use to logon on on your development machine.

    Remote debugging fails with machines on a workgroup

    In the work group environment, you need to make sure that you have the same named user account on both machines with the same password, otherwise DCOM will fail to authenticate you.

    There is one more consideration: on XP Pro, because of the default security setting for "sharing and security model for local accounts", remote debugging is not allowed by default. Here are the steps to change this setting:

    1. Run "Local Security Settings" in Administrator tools
    2. Select "Security settings\Local policies\Security options
    3. Change "Network access : Sharing and Security model for local accounts" from "Guest only - local users authenticate as Guest" to "Classic - local users authenticate as themselves"
    4. After this, you need to reboot the machine

    Make sure that your user accounts on each machine has password. In some cases, without actual password it doesn’t work. This change should be applied on both machines for remote debugging now you should be able to remotely debug your application.

    However, there is security concern about this: because you changed default settings of the security model, it can expose:

    • Unexpected file sharing
    • Unexpected DCOM components sharing

    By default any kind of connection from the remote machine to your machine was guaranteed as "Guest", but after this change new connections could be authenticated with your local user account. So, like in the case of debugging, if you are sharing out a folder or DCOM object there is a possibility that any matched user (same user name and same password) on other machines could access your shared objects.

    I strongly recommend that, if you want to use this work-around, you make sure that all user accounts have strong passwords, or should setup network-Island for the debugging machines to prevent any malicious attack.

    Update (30/03/2007)
    I'm not sure when this was published, but here is an interesting list of common debugger errors and solutions smile_nerd



  • Never doubt thy debugger

    Quick things to check if you are leaking your memory


    After a couple of years working in InternetDev support I've seen many different kind of problems reported by customers (different environments, different use of Microsoft technologies and products combined together, different application needs, different customer's background and technical knowledge etc...), but as one of my favorite authors said, Sometimes they come back, so it happens that sometimes we also get incoming calls for well known problems like memory leaks, high CPU and worker process crashes. Of course there could be many different causes for those problems, but some of them are more likely to affect your application; here is a list of the first things I check when I'm working on a memory leak problem (usually analyzing a memory dump of the faulting application). This is not a complete list (but I promise to update the post if I'll find something new and interesting) and if you talk to other Support Engineers they might give you a slightly different view on the subject, this is what I found and learnt in my day to day support experience.

    Application deployed in debug mode

    This is something we must avoid in a production environment; debug mode is useful during development, but in production prevents the runtime to use a some optimization at compilation and resource management level (memory, CPU etc…): I personally saw a big eCommerce site stop working after a few minutes just because of this setting. To resolve it you have to check your web.config files and assure that you set debug=”false” as the compilation mode. See this nice post from Tess on the subject.

    Avoid duplicated assemblies (install them in the GAC)

    If you have multiple applications running on the same server, and all of those applications are using some common assemblies (maybe your own custom data access layer, or some common controls with shared functionality across all of your applications, some sort of utility classes etc...), and you put those components in the /bin folder of every application, all those assemblies will be loaded inside their correspondent AppDomain. As you can easily guess, you'll end up with some (maybe lots) of identical assemblies loaded multiple times (one per AppDomain/application), thus wasting resources on your server (of course memory, but those components must also be JITted and loaded in memory); wouldn't be nice if you could load just one instance of those shared components and then all of your applications could use that only copy in memory?
    Well... it turns out that this is exactly what the Global Assembly Cache is meant for! smile_regular

    - 315682 How To Install an Assembly in the Global Assembly Cache in Visual Basic
    · 815808 How To Install an Assembly into the Global Assembly Cache in Visual C#
    · Global Assembly Cache Tool (Gacutil.exe)

    Large Object Heap

    You should also pay attention to large objects, which lead to memory fragmentation. When .NET based application (as ASP.NET) needs to allocate new memory, it does so looking for (and reserving) chunks of 64 Mb free and contiguous memory: that is the key of this matter. When the Garbage Collector does its job and frees memory for unused (better say, unreachable) objects, it also tries to compact the chunks of memory to have it contiguous for future use, but this is not always possible: when the GC runs, it must temporarily stop all application threads, move around chunks of memory, update memory pointers and then the application can continue it’s job. But for performance reasons this can’t be done with objects larger than 85 Kb, which are seen as big objects from the CLR point of view and are allocated on a special heap, called the Large Object Heap. Objects in LOH are still collected and the memory freed, but since moving around such large chunks of memory is very expensive (and remember during this operation the application is frozen and can’t respond to client’s requests) and would require too much time and effort to the system, at the end the application would be too badly affected. The GC frees that memory but does not compact it, and this leaves some holes in our memory (like a Swiss cheese, if you like it smile_regular).
    Multiply this process during the life of the application and you could end up having lot of free memory but so fragmented (I’ve seen dumps where we still had 80% of available memory that the biggest contiguous free chunk of memory was just 50 Mb, too small for the 64 Mb needed), than the CLR could do nothing else but throw an OutOfMemoryException. Of course if you have lots of big objects you’ll have more chances to run into this problem.
    This article has a quite detailed description of GC internals: “Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework” and part2

    In this same category I include the Viewstate problem; Viewstate is certainly a useful and powerful feature and there are controls (like the DataGrid) which needs Viewstate to work properly, but you must always be very careful with it... if you are running short in memory always try to disable Viewstate for every control (also for every page, if this is feasible) which does not explicitly needs it. Sometimes looking at the list of large object in a dump we find very big string objects which contains the Viewstate for your page and controls... Disabling it whenever possible will reduce memory fragmentation and will also decrease the time a client need to load your pages, because of the smaller HTML it will have to download from the server.

    Dynamic assemblies

    XML/XSLT stuff going on inside your process is also a known cause of memory problems if not used correctly; the problem is related to dynamic assemblies which are created by the runtime to manage those operations. Here are a couple of articles which may help you on this:
    - 321702 HOW TO: Use Extension Objects When You Execute XSL Transformations in Visual Basic .NET Applications
    - 323370 HOW TO: Use Extension Objects When You Execute XSL Transformations in Visual C# .NET Applications
    - 316775 PRB: Cannot Unload Assemblies That You Create and Load by Using Script

    What about disposing objects?

    As you may know, even if the Garbage Collector usually does an excellent job removing objects, releasing resources and freeing memory for you, this does not relieve you as the developer to take care of the objects and resources you allocate, and release them when you're done; this specially applies for unmanaged (COM) resources and objects, since the GC is not able to collect that memory and release those resources, and it's developer's responsibility to take case of them.

    I've seen an extension of this particular circumstance with EventHandlers; this is the basic scenario: you create you own custom object to store information your application needs, that object exposes some events and you put that object in your user's session. Then from some other code in your application (a page or a custom component) you subscribe to one or more events exposed by that cached object, and your' re done, right? Well... nope! smile_omg Because if you don't explicitly remove the subscription to that event on the cached object, your subscriber code (page or component) will always be reachable (there will always be a link between it and the cached object) and the GC will not be able to remove your subscriber object, thus wasting memory. If in a dump the output of a !gcroot command shows a long chain of EventHandlers you stumbled into this problem. Of course this applies to every kind of objects, not just EventHandlers.
    My colleague Tess has a very nice post on this (we worked together on one of this cases a few months ago... maybe this inspired the post? smile_wink).

    Use /3Gb and multiple application pools

    Applying the /3Gb switch usually helps to address memory pressure problems, but only if the application reaches a point of stability where the GC is able to free enough memory for the runtime to run properly, but there might be circumstances where this is not enough; in those cases usually we have a problem with application design, either at code level or architecture level.
    · How to Set the /3GB Startup Switch in Windows
    · Memory Support and Windows Operating Systems
    · How to use the /userva switch with the /3GB switch to tune the User-mode space to a value between 2 GB and 3 GB

    Windows 2003 and IIS 6.0 gives us greater flexibility and fine tuning possibilities thanks to it’s architecture and internals (quite different from Windows 2000 and IIS 5.x); if your application’s design allows it, you can configure your application pool to be served by multiple worker processes (web garden), or you can split your application to run under different application pools. Everyone of them capable of taking advantage of the 2 (or 3, depending on your configuration) Gb or virtual memory available for Win32 processes. Of course this must we carefully tested before going live, but usually IIS 6.0 help us sorting some of those problems, or at least can put some relief on it while you are working to fine tune the solution (maybe with the help of a Microsoft PSS Engineer smile_regular).

    Oh, of course if you put a lot of data in your cache you could run out of memory...

    There is also a nice KB article on this subject (actually I found it after I wrote this post...):


    Update (18/07/2007):
    Reading this post I just noted I forgot to add the EventHandler problem I encountered a few times, and Tess described here



  • Never doubt thy debugger

    ASP.NET Membership Provider with custom schema


    =================== Membership control issue: when I create users and roles by wizard the default database is sql server express and the file is aspnet.mdf, but in my case I have my own database which store the users detail. I want to use the membership control functionality but don't want to deal with 2 databases; also, I want to add my table to the default database thus changing the schema.
    I expect the Membership provider to support that change and want to know what should I change in the application code

    “How to: Use membership in ASP.NET 2.0” at, in particular the section “Using the SQLMemberShipProvider”; basically you need to configure Forms authentication, install the membership database and configure the SqlMembershipProvider.

    Step 2. Install the Membership Database
    Before you can use the SqlMembershipProvider, you must install the SQL Server membership database.
    To install the membership database, log on to your server with an account that has authority to administrate SQL Server (such as the Administrator account). Open the Visual Studio 2005 command prompt, and run the following command:

    aspnet_regsql.exe -E -S localhost -A m

    -E indicates authenticate using the Windows credentials of the currently logged on user
    -S (server) indicates the name of the server where the database will be installed or is already installed
    -A m indicates add membership support. This creates the tables and stored procedures required by the membership provider

    The Aspnet_regsql tool is also used to install database elements for other ASP.NET 2.0 features, such as Role Management, Profile, Web Parts Personalization, and Web Events. Other command-line arguments perform database operations for these other features. You can use Aspnet_regsql without any command line arguments by using a wizard that allows you to specify connection information for your SQL Server and install or remove the database elements for all of the supported features.

    Step 3. Configure the SqlMembershipProvider
    The Machine.config file contains a default SqlMembershipProvider instance named AspNetSqlMembershipProvider that connects to the SQL Server Express instance on the local computer. You can use this instance of the provider if you are running SQL Server locally. Alternatively, you can specify provider details in your application's Web.config file, as shown here in the following example.

    <add name="MySqlConnection" connectionString="Data Source=MySqlServer;
    Initial Catalog=aspnetdb;Integrated Security=SSPI;"
    /> </connectionStrings> <system.web> ... <membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15"> <providers> <clear /> <add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider"
    connectionStringName="MySqlConnection" applicationName="MyApplication" enablePasswordRetrieval="false"
    enablePasswordReset="true" requiresQuestionAndAnswer="true" requiresUniqueEmail="true" passwordFormat="Hashed" /> </providers> </membership>





    Make sure to set the defaultProvider attribute value to point to your provider definition. The default value points to AspNetSqlProvider, which uses the local SqlExpress instance.



  • Never doubt thy debugger

    Unable to get the private bytes memory limit for the w3wp process


    I can run ASP.NET applications on the server, however I have noticed that when I do there is an asp error entry in the event log: "Unable to get the private bytes memory limit for the W3WP process. The ASP.NET cache will be unable to limit its memory use, which may lead to a process restart. Error 0x80070005".


    - Windows Server 2003
    - .NET Framework 1.1


    This error is caused by a known issue with insufficient permissions in your IIS metabase. The metabase ACL's on the target server did not include the IIS_WPG group on the following two nodes of the metabase (IIS_WPG is in both ACL's on a clean install):
    - W3SVC/AppPools
    - W3SVC/Filters

    You can download the MetaACL utility from After you have installed the program, open a command prompt and navigate to the directory where you installed it. Then type the following:

    - cscript metaacl.vbs IIS://Localhost/W3SVC/AppPools IIS_WPG RE
    - cscript metaacl.vbs IIS://Localhost/W3SVC/Filters IIS_WPG RE

    The path is case sensitive - type exactly as above; after you run this command restart the IIS services and see if this corrects the problem.


    Update: here is an update on this matter:



  • Never doubt thy debugger

    Automatic proxy configuration in .NET Framework 2.0


    The outcome of the execution of PAC file seems to change when called from IE or from a .Net 2.0 client. The internal URL we want to call is and the IP address of the web apps server is

    For example, here is a sample PAC file

    function FindProxyForURL(url, host) 
        if (isInNet(host, "", "")) 
            return "DIRECT" 
            return "PROXY" 

    When called from IE, the internal url is directly connected to the web server without using a proxy. So the PAC file returns “DIRECT”.

    When called from a .Net 2.0 application, the same url ( is redirected to the internal proxy If he uses the IP address of the web Server ( ), the isInNet function seems to work as the request is not redirected to the proxy anymore.

    I used the code below to test the differences between .Net 1.1, .Net 2.0 and IE (taken from ).

    using System; 
    using System.Net; 
    public class Test 
        public static void Main(string[] args)     { 
        IWebProxy iwp11 = GlobalProxySelection.Select; 
        Console.WriteLine(iwp11.GetProxy(new Uri(args[0])).ToString()); 
        //comment the following 2 lines when compiling on 1.1 
        IWebProxy iwp20 = WebRequest.DefaultWebProxy; 
        Console.WriteLine(iwp20.GetProxy(new Uri(args[0])).ToString()); 


    This behavior is by design in .NET2.0 because with the introduction of IPv6, isInNet needs to be more specific on what to compare. Therefore, IP address needs to be specified in isInNet if the PAC is to be used in .NET Framework 2.0.

    I read a draft (MSOnly) version of the KB article which will address this same issue (but I don't know when it will be published); in the meantime...

    The KB article has been published:;EN-US;922778



  • Never doubt thy debugger

    Content Management Server and proxy detection


    You are using Site Manager from MCMS 2002.
    Site Manager is partly build on C# and is using the HttpWebRequest class in .NET framework to connect to the MCMS server.
    In the customers environment SiteManager wrongly tries to connect through a proxy server rather than directly connecting to the MCMS server.

    Using a configuration file to instruct your application to use the right parameters:.

    Set the GlobalProxySelection option in the application config file (NRClient.exe.config) and copy the file into “C:\Program Files\Microsoft Content Management Server\Client” (see below for file content)

                    proxyaddress = "
    http://proxyaddress:port" bypassonlocal = "true" />



  • Never doubt thy debugger

    Missing ASP.NET Tab in IIS Management Console


    On a Windows 2003 64bit machine with both .NET Framework 1.1 and 2.0 installed, you are tying to configure a website on IIS, but you are unable to find the tab to specify ASP.NET settings.

    Researched turned out this being a bug that is closed as "won't fix".

    If you are gong to run IIS 32-bits on WOW64, MMC Support for ASP.Net snap-in is currently not allowed.
    We are in the process of writing a KB article to document this.
    In general the tab is giving you the UI to configure the application to run different versions. You could use the specific version of aspnet_regiis.exe utility to configure this.
    The utility is aspnet_regiis -i under C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727, if you want your application to run under 2.0.
    There are several command switches to configure specific sites or directory only.
    If you see these problems on 32-bit OS there's a known workaround:

    • Manually run the install for ASP.NET: ASPNET_regiis -i
    • Register the dll for the MMC: regsvr32.exe "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mmcaspext.dll" "rundll32.exe" "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\webengine.dll",RegisterAspNetMMC
    • From a command prompt run: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regasm.exe C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\AspNetMmcExt.dll /tlb:AspNetMMCExt.tlb
    • Change the About value in "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MMC\SnapIns\{fedb2179-2335-48f1-aa28-5cda35a2 b36d}" from {7D23CCC6-A390-406F-AB67-2F8B7558F6F7} to {7D23CCC6-A390-406F-AB67-2F8B7558F6F6}


    UPDATE (5th November, 2006)
    Just found this recently published KB article as official documentation:;en-us;919283&sd=rss&spid=8940


    UPDATE (23rd April, 2008)

    Tom (and Jeremy and Vandana) has a solution, check it out



  • Never doubt thy debugger

    Http compression and WinForm controls as legacy ActiveX


    The following is the summary of a couple of cases I worked on a while ago, there are some details which I'll need to investigate thoroughly... anyway those are the facts so far.

    I have a rich WinForms UserControl which is embedded into a web page. Since installing .NET 2.0 on the clients, the control stopped loading completely.
    - I disabled security completely using caspol -s off => no effect
    - I enabled fusion logging => no single entry generated
    - I enabled the IEHost log => nothing created
    - Changed to another client machine => same issues, same results
    - I started writing a new UserControl from scratch and deployed it to the same server. The control could also not be loaded.

    I deployed the same test project to another 2003 server in the same domain, with equal patch levels (SP1 and latest patches installed) and it worked. Perhaps a naming issue?
    - I tried to change the names => no result
    - I compared the HTTP requests to the different server => nothing special

    - The issues stated above are reproducible from any client, such it should be a server or framework issue.
    - I even have a customer which experienced the same problems
    - The problem exists for two completely different client applications

    To again clarify my problem:
    - I'm definitely sure that I'm using the 2.0 tools and not the 1.1 policy / binding / whatever tools.
    - I'm sure it is not a security issue, at least not one of the caspol which I disabled completely using "caspol -s off"
    - I'm sure the control gets downloaded by the browser into the temporary IE directories and I'm sure that the downloaded version matches the dll's I deployed onto the server
    - Windows Firewall is completely disabled through Group Policy
    - Virus Scanner has been temporarily turned off, on both client and server
    - I'm sure that the problem is not dependant on the control code itself It just doesn't load into the IEHost which I could conclude from none of the logs, neither IEHost-log nor binding-log are being created at all.

    My remaining and only problem is why does it not load from that specific server. It must be something within the communication and not the control itself. Last update: I currently did a network trace and found one significant difference between the two servers: one is doing chunked HTTP response encoding, the other one not. I disabled my browser doing HTTP 1.1 and the control loads (HTTP 1.0 does not allow chunked encoding!).


    This is a known problem with Windows Forms controls embedded in Internet Explorer, along with HTTP compression enabled on the web server, and has nothing to do with the installation of .NET Framework 2.0 (the same issues applies also for version 1.1).  The second test server, where the application worked fine, was not configured to use http compression.

    Troubleshooting the problem I found that the dll is downloaded in IE temporary folder with the name specified in ClassID (SimpleControl.dll#SimpleControl.UserControl1), and it does not show up using “gacutil /ldl” if I disable http compression (I tired “Compress static files” with and without “Compress applications files” with no difference), SimpleControl.dll is downloaded in IE temporary folder it also shows up with gacutil.
    A second workaround is to package your assembly into a CAB file (like we used to do with ActiveX controls before the .NET arrival): you can find further reference on how to create and deploy a CAB file at
    Walkthrough: Creating a CAB file.

    To check if you are using http compression in IIS 6.0, do the following (Enabling HTTP Compression):

    1. In IIS console double click the local computer, right click the Web Sites folder and the click Properties
    2. Click the Service tab, and in the HTTP Compression section select the Compress application files checkbox to enable compression for dynamic files
    3. Select the Compress static files checkbox to enable compression for static files



  • Never doubt thy debugger

    Watch your symbols!


    This morning I had an open discussion with a customer regarding symbols and their importance in our job (our intended also as a developer, not just as a support specialist). This customer sent in a dump for a memory leak problem he has in his web site (ASP.NET with COM components, calls to Web Services etc...).

    I have to admit that a few times in the past I went through a dump without any symbols for the application (luckily I always have access to both internal and external symbol server for the OS, .NET Framework etc...), and even sometimes I've been able to find the cause of the problem anyway (sometimes it's quite obvious, it you have memory fragmentation, debug="true" in web.config, too many dynamic assemblies caused by XML/XSLT stuff etc...), but there are occasions where the call stack is completely messy and the real problem quite hard to discover.

    Also more important is to have matching symbols: debugging with non-matching symbols could be much worse than debugging without symbols at all, and the analysis could take a completely wrong direction, wasting time and efforts without helping sorting out the problem... and you'll get a bad support experience when you'll call us to ask for support.

    To give some background to the ones who don't have much experience on this topic, here are a couple or links which may help you:

    So, take good care of your symbols! :-)



Page 1 of 1 (9 items)