Monday, March 29, 2010

Using WindDbg and Sosex to Identify an ASP.NET Deadlock

This post will show how to use create an ASP.NET deadlock and then then use WinDbg and sosex to identify it the idea is to practice this before needing it when debugging a production server :)


The environment for my test is

  1. Create a new web application and put this in the code behind for Default.aspx:
    public partial class _Default : Page
    {
        /// <summary>
        /// Locks on page load.
        /// </summary>
        protected void Page_Load(object sender, EventArgs e)
        {
            object lockA = new object();

            object lockB = new object();

            ThreadStart firstJob = new ThreadStart(() => this.DualLockingCall(lockA, lockB));
            Thread firstThread = new Thread(firstJob);
            firstThread.Name = "firstThread";
            firstThread.Start();

            ThreadStart secondJob = new ThreadStart(() => this.DualLockingCall(lockB, lockA));
            Thread secondThread = new Thread(secondJob);
            secondThread.Name = "secondThread";
            secondThread.Start();

            Thread.Sleep(Timeout.Infinite);
        }

        /// <summary>
        /// lock on a then lock on b.
        /// </summary>
        /// <param name="onThis">The first instance to lock on.</param>
        /// <param name="onThat">The second instance to lock on.</param>
        private void DualLockingCall(object onThis, object onThat)
        {
            lock (onThis)
            {
                lock (onThat)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(5));
                }
            }
        }
    }
  2. Navigate to the url like localhost/projectName/Default.aspx
  3. Open a command prompt and navigate to the debugging tools for windows directory.
  4. Run this command adplus -pn w3wp.exe -o c:\ -hang
    1. The hang command takes a memory dump immediately.  It doesn't wait for a hang.
  5. Note the output directory.  It should be the last line adplus printed out.
  6. Run windbg and press ctrl+d to open a memory dump.  Navigate to the dump adplus just created.
  7. type .loadby sos mscorwks - This will load the sos.dll from the same directory mscorwks was loaded from.
  8. type .load pathToSosex\sosex.dll
  9. type !dlk
  10. On my machine I get this output:
    *** WARNING: Unable to verify checksum for LockItUp.DLL
    *** ERROR: Module load completed but symbols could not be loaded for LockItUp.DLL
    Deadlock detected:
    CLR thread 8 holds sync block 0000000002583228 OBJ:00000001bf1f2be0[System.Object]
                 waits sync block 00000000025831e0 OBJ:00000001bf1f2bf8[System.Object]
    CLR thread 9 holds sync block 00000000025831e0 OBJ:00000001bf1f2bf8[System.Object]
                 waits sync block 0000000002583228 OBJ:00000001bf1f2be0[System.Object]
    CLR Thread 8 is waiting at LockItUp._Default.DualLockingCall(System.Object, System.Object)(+0x25 IL)(+0x74 Native)
    CLR Thread 9 is waiting at LockItUp._Default.DualLockingCall(System.Object, System.Object)(+0x25 IL)(+0x74 Native)

    1 deadlock detected.
Easy cheesy in this simulated test eh?



Monday, March 22, 2010

A Test of My Mettle

I attended my first Toastmaster's meeting last Wednesday and experienced special guest Ed Hearn deliver an inspirational thought provoking speech entitled: "The Courage to Try."

Mr. Hearn gave examples of individuals achieving seemingly impossible goals such as Wilma Rudolph winning three Olympic Gold medals despite having a severe physical disability as a child.  In each example the actors overcame daunting obstacles to realize fantastic goals.

During the speech I was thinking about people's opportunities in life, and how I did not have to struggle to complete High School, College, or get a professional job.  I've taken advantage of opportunities which were nearly given to me, but I haven't made my own opportunities.  Mr. Hearn's speech combined with some of my other experiences have made me realize the goals I attempt in life are low risk or low effort. When I take on large (1,000+ hours) personal projects I give up on the projects after investing a small (10-700 hours) amount of effort into them compared to the amount of effort required for completion.  I'm assuming I give up because I don't see results and overvalue the opportunity cost.  IE.  I think "Hmmmmmm...... I've spent 50 hours on this which I could have spent completing items x,y, and z on my todo list instead.  It may take another 500 hours to achieve my goal, or I may not even be able to achieve my goal," and sack the project.

I am not sure if this new thinking will bear fruit.  Unless I can talk myself into believing there is significant value in the act of trying I'm not sure I can justify the cost of the attempt.  Maybe because I plan for the worst and hope for the best.  Under this mentality I assume the 1000+ hours invested will not achieve the stated objective.

Monday, March 15, 2010

Viewing ASP.NET Adaptive Rendering

I remembered when ASP.NET launched hearing about adaptive rendering.  Using ASP.NET I did not notice different renderings.  This post shows how one can observe ASP.NET adaptive renderings using fiddler.

The software used for this post is:
  • Visual Studio 2008 SP1
  • Windows Server 2008 R2 Standard
  • Fiddler v2.2.8.6 64-bit
  • IE 8.0
  1. Using Visual Studio create a new ASP.NET Web Application
  2. Modify Default.aspx.cs as follows:
    public partial class _Default : Page


    {
        /// <summary>
        /// Ignores this pages children and demonstrates different HtmlWriters based on
        /// different request strings.
        /// </summary>
        /// <param name="writer">An HtmlWriter passed by ASP.NET.</param>
        protected override void Render(HtmlTextWriter writer)
        {
            writer.Write(HttpContext.Current.Request.Browser.TagWriter.ToString());

            writer.AddStyleAttribute(HtmlTextWriterStyle.Color, "Red");
            writer.RenderBeginTag(HtmlTextWriterTag.P);
            writer.Write("Red text");
            writer.RenderEndTag();
        }
    }
  3. Run the project and note the port it runs on.  In my case the url is http://localhost:56449.  Running in IE 8 I see:
    System.Web.UI.HtmlTextWriter


    Red text
  4. In Fiddler enter Request Builder, build and execute the following request:
    Get http://ipv4.fiddler:YOURPORT HTTP/1.1
    User-Agent: Mozilla(compatible;MSIE 3.0;)
     Host: ipv4.fiddler:YOURPORT
  5. In the Web Sessions click the session resulting from your request
  6. Select the Inspectors tab and select TextView.  On my machine I see:
    System.Web.UI.Html32TextWriter<p><font color="Red">Red text</font></p>
    Since we specified our user-agent as MSIE 3.0 ASP.NET is rendering the style color using the font tag.
  7. Go back to Fiddler Request Builder, build and execute the following request:
    Get http://ipv4.fiddler:YOURPORT HTTP/1.1
    User-Agent: Mozilla(compatible;MSIE 4.0;)
     Host: ipv4.fiddler:YOURPORT
  8. In the Web Sessions click the session resulting from your request
  9. Select the Inspectors tab and select TextView. On my machine I see:
    System.Web.UI.HtmlTextWriter<p style="color:Red;">Red text</p>
  10. There are a couple of differences between the two responses:
    1. HtmlTextWriter was used whereas in the previous request it was an Html32TextWriter.
    2. ASP.NET renedered the style color using CSS instead of the font tag.

To undestand the mechanics making this happen 4 Guys From Rolla have an article describing the details.

Above I used ipv4.fiddler instead of localhost to enable seeing traffic sent to localhost as described in Fiddler's help.

Monday, March 1, 2010

Equal but different JavaScript style

Someone at work pointed out this surprise in JavaScript: [] == ![] evaluates to true.

Reading this I thought it was stating something is equal to the opposite of itself.  For non technical readers can things be equal without being the same?  Currencies?  People?  In English do people sometimes say same but mean equal?

In programming worlds things which are not the same might be equal, but I expect something that is the opposite of itself to definitely not be equal to itself.  For example 1 is not equal to !1  I decided to discover how can this be?

I started by firing up a debugger and looking at the types [] and ![].  ![] is false*.

Then I went to the ECMA-262 spec:

Section 11.9.1 The Equals Operator (==) points us to 11.9.3 abstract equality comparison.

11.9.3 The Abstract Equality Comparison Algorithm
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
7.If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

9.3 ToNumber
  Given Argument Type Boolean The result is 1 if the argument is true. The result is +0 if the argument is false.

Going back to 11.9.3

9. If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.

Section 9.1 ToPrimitive:
For input type Object

Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.

Section 8.12.8 DefaultValue

When the [[DefaultValue]] internal method of O is called with hint Number, the following steps are taken:

  1. Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf".
  2. If IsCallable(valueOf) is true then,
    1. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list.
    2. If val is a primitive value, return val.
  3. Let toString be the result of calling the [[Get]] internal method of object O with argument "toString".
  4. If IsCallable(toString) is true then,
    1. Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list.
    2. If str is a primitive value, return str.
  5. Throw a TypeError exception.

valueOf defined in Section 15.2.4.4 does not return a primitive so toString() from step 3 is called resulting in ""

Going back to 11.9.3

5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.

Section 9.3.1 ToNumber Applied to the String Type informs us that whitespace returns 0.

The leaves us with ([].toString() == "") == (![] == 0) which can be confirmed in a debugger and also results in [] == ![] resulting in true.



*To know why ![] is false
See section 11.4.9

11.4.9 Logical NOT Operator ( ! )
The production UnaryExpression : ! UnaryExpression is evaluated as follows:
1.Let expr be the result of evaluating UnaryExpression.
2.Let oldValue be ToBoolean(GetValue(expr)).
3.If oldValue is true, return false.
4.Return true.

Step 2 ToBoolean(GetValue(expr))
Takes us to Section 9.2 ToBoolean where: for Argument Type Object the result is true.