Dot Net Thoughts

November 29, 2007

Debug and Release Builds

Filed under: csharp,Debugging,Uncategorized — dotnetthoughts @ 9:41 pm
Tags: , ,

Occassionally, I find old code concepts rattling around in my head that just don’t apply in today’s world. My most recent one was the difference between release and debug builds.

Back in VB6 days, one of the big reasons for creating a debug build was the generation of the pdb file. The pdb (portable database) file contained information about the names of items such as variables, classes and methods. Furthermore, it contained information about where these values were located in the code. Without the pdb file, all of this information was unavailable.

Imagine my surprise when I ran some code without a pdb file the other day, and I received a stack trace containing method names. With a little further thought, though, I realized it wasn’t that surprising. When disassembling a dll with ILDASM, I can see all of the method and variable names with or without a pdb file present. It turns out that the inclusion of a pdb file will allow you to trace a bug to a module and line number, but it is no longer needed for artifact names.

Release builds now contain pdb files by default. So what is the difference between the two build types? To help figure this out, I generated a very simple HelloWorld class and compiled it as both a release and a debug build. This class contained two methods.

       

        static void Main(string[] args) 
        { 
            Console.WriteLine(SayHello("Bob")); 
            Console.ReadLine(); 
        }               

        static string SayHello(string name) 
        { 
            return String.Format("Hello {0}!", name); 
        }       

Opening the Main method of the release dll in ILDasm yields a pretty straight forward implementation of the code. In the decompilation, you can see the creation of the string, the loading of the parameter, the string formatting, and the return of the value.

       

  .method private hidebysig static string 
          SayHello(string name) cil managed 
  { 
    // Code size       12 (0xc) 
    .maxstack  8 
    IL_0000:  ldstr      "Hello {0}!" 
    IL_0005:  ldarg.0 
    IL_0006:  call       string [mscorlib]System.String::Format(string, 
                                                                object) 
    IL_000b:  ret 
  } // end of method Program::SayHello       

The debug code looks almost exactly the same, but it includes a few differences to help assist in debugging. A local variable is initialized to hold the value of parameter so that it is available to a debugger. Also added are several nop (no operation) and a br_s (branch) method. These set points within the application on which a breakpoint can be set.

       

  .method private hidebysig static string 
          SayHello(string name) cil managed 
  { 
    // Code size       17 (0x11) 
    .maxstack  2 
    .locals init ([0] string CS$1$0000) 
    IL_0000:  nop 
    IL_0001:  ldstr      "Hello {0}!" 
    IL_0006:  ldarg.0 
    IL_0007:  call       string [mscorlib]System.String::Format(string, 
                                                                object) 
    IL_000c:  stloc.0 
    IL_000d:  br.s       IL_000f    IL_000f:  ldloc.0 
    IL_0010:  ret 
  } // end of method Program::SayHello       

I expected that tweaking the code to call a few subroutines would at least lead to some inlining optimizations within the IL. The differences between the Debug and Release versions of the IL were similar to those above. So where were the optimizations?

The only other major difference between the IL versions are the values stored in the DebuggingModes attribute. This attribute links back to the debug compilation flags that can be set when compiling a project. Since these are the only differences in the IL, the optimizations must occur within the JIT compiler itself. Scott Hanselman has an excellent post on compiled release and debug that is well worth reading.

That would be it for today! Good luck and code safe!

MW

November 10, 2007

TransactionScope and Unit Tests

Filed under: Uncategorized — dotnetthoughts @ 6:29 am
Tags: , , , , ,

Writing unit tests to validate a data access layer (DAL) can be a time consuming (but life saving) task. One of the biggest challanges of DAL unit tests is assuring that you have consistent data to pull from the database. Dedicating a database with static data for unit tests doesn’t always work. As unit tests are added to the project, data may need to be added to the database. This can cause previously created tests to fail, and a lot of time can be lost trying to resync everything.

One technique for getting around the unit test database consistency issue is to write data to the database you expect to find. The steps for doing this would be:

  • Begin a transaction in your unit test.
  • Write the data to the database that your data access layer will need.
  • Test the data access layer functionality against the inserted data.
  • Roll back the transaction.

Using a transaction has a couple of distinct advantages. Since you are running in the scope of an uncommitted transaction, your fellow developers running unit tests will not see your added data (isolation). Also, rolling back the transaction places the database back to the original state in which you found it.

Managing transactions by explicitly attaching them to the connection object doesn’t always work well when testing a data access layer. Since the DAL often contains code to retrieve its own connection, the following sequence often occurs:

  • Begin a transaction in your unit test.
  • Write the data to the database that your data access layer will need.
  • Call the Data Access Layer. The Data Access layer creates its own connection.
  • The DAL attempts to read the new data from the database. It is blocked, though, because it is in a different transaction than the unit test transaction, and will not be able to complete until the DAL commits.

The TransactionScope object helps alleviate this problem. It sits on top of the Distributed Transaction Coordinator, and will assign any code running within its context to the same transaction. In other words, a TransactionScope context within your unit tests will force your data access layer code to run within the same context. Isolation is maintained from other developers, but your DAL can access and manipulate the data as needed. (This does require that you have the Distributed Transaction Coordinator Service running on the box that handles the transaction.)

To demonstrate, let’s assume that I have a DAL method that I want to test that returns all users from a database. This method gets its own connection, retrieves the users, and returns them as a DataSet.

public DataSet GetUsers() 
{ 
    DataSet dataSet = new DataSet(); 
    string connectionString = GetConnectionString();      

    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
        connection.Open(); 
        string sql = "SELECT * FROM [User]"; 
        SqlCommand command = new SqlCommand(sql, connection); 
        SqlDataAdapter adapter = new SqlDataAdapter(command); 
        adapter.Fill(dataSet); 
    }      

    return dataSet; 
}

Here is the unit test to test this code. It doesn’t test nearly all of the functionality you would want to check in a real unit test, but it does demonstrate the TransactionScope. Note that the TransactionScope object doesn’t have an explicit RollBack() method. The Rollback occurs if the TransactionScope object is disposed without Complete() being called on it. This occurs at the end of the using block.

[TestMethod()] 
public void GetUsersTest() 
{ 
    string connectionString = GetConnectionString();     

    using (TransactionScope ts = new TransactionScope()) 
    { 
        using (SqlConnection connection = 
            new SqlConnection(connectionString)) 
        { 
            connection.Open(); 
            DataLayer dataAccessLayer = new DataLayer();     

            DataSet dataSet = dataAccessLayer.GetUsers(); 
            AddNewUser("Fred", connection);     

            dataSet = dataAccessLayer.GetUsers(); 
            DataRow[] dr = dataSet.Tables[0].Select("[UserName] = 'Fred'"); 
            Assert.AreEqual(1, dr.Length); 
        } 
    } 
}

Hope this is helpful. Good luck and code safe!

MW

October 27, 2007

Where Did My Exception Occur?

Filed under: Debugging — dotnetthoughts @ 7:19 am
Tags: , , , , ,

A couple of times a day, this blog takes a hit from someone trying to figure out how to programmatically determine on what line number an exception occurred. Determining this information actually turns out to be a fairly straight forward operation.

The one caveat for retrieving exception line numbers is that your application must have access to the portable database (pdb) file generated when the code is compiled. In C#, the default is to create this file for both a release and debug build. Unless you actively make a decision to exclude this file, you should be able to find it alongside your application or dll in your bin/<buildtype> directory.

The key to determining the line number on which an exception occurs is to check out the stack trace. A stack trace contains the history of all of the method calls made in your application up to a given point in time. If debug information exists, the stack trace can also display the file, module, and line number on which an exception occured. There are two ways to access the stack trace information:  a string directly from the exception, and StackTrace object from the System.Diagnostics namespace.

At the bottom of this post is sample code which accesses stack trace information directly from an exception object. The Main method calls GetValue. GetValue calls DivideByZero, which throws an exception. The exception is caught in the Divide method and is displayed on the console. When I run the code on my computer, the following stack trace is returned:


at System.Decimal.FCallDivide(Decimal& result, Decimal d1, Decimal d2)
at System.Decimal.Divide(Decimal d1, Decimal d2)
at System.Decimal.op_Division(Decimal d1, Decimal d2)
at StackTrace.Program.Divide(Decimal a, Decimal b) in C:\DebuggingPresentation\StackTrace\StackTrace\Program.cs:line 36
at StackTrace.Program.GetValue() in C:\DebuggingPresentation\StackTrace\StackTrace\Program.cs:line 23

This StackTrace contains a snapshot of my application at the point in time the error occured. The most recent call exists at the top of the stack. Reading from the bottom up, we can see that GetValue (line 23) called Divide (line 36). Our application triggered three method calls into the Decimal object, itself.

Viewing the stack trace string directly from an Exception object has a couple of drawbacks. For starters, we can only see the stack trace to the point in time that the exception was handled in our code. The stack trace does not show that Main initially called GetValue(). In our application, this is trivial to figure out, but if GetValue() can be called from multiple methods, we may want to be able to see higher up the stack. Also, we may want to persist our exception information by file, module and line number. We could probably come up with some crazy regular expression to pull this information out, but it wouldn’t be much fun to say the least.

The StackTrace object in the System.Diagnostics namespace allows us to see the entire stack trace above an exception when it occurs. Let’s modify the code in the Catch block to use a StackTrace object. The ‘true’ parameter indicates that we do want access to the file name, module name, and line number.

catch (DivideByZeroException ex) 
{ 
   System.Diagnostics.StackTrace st = 
      new System.Diagnostics.StackTrace(true); 

   result = st.ToString(); 
}

When we call the ToString() method of this StackTrace object, we now get to see the entire stack up to the point the exception was handled.


at StackTrace.Program.GetValue() in C:\DebuggingPresentation\StackTrace\StackTrace\Program.cs:line 29
at StackTrace.Program.Main(String[] args) in C:\DebuggingPresentation\StackTrace\StackTrace\Program.cs:line 15
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile,
Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

If we want to pull out line or module information on a specific frame, we can iterate over the Frames object exposed by the stack trace. If we tweak the Catch block one more time, we can see how we can pull out individual pieces of data. This could potentially be used to automatically log our exceptions to a database should a problem occur. Note that in this example, I’m going to pass in my exception to the constructor of the StackTrace object, indicating that I want to take a look at the StackTrace of this particular exception.

catch (DivideByZeroException ex) 
{ 
   StringBuilder sb = new StringBuilder(); 
   System.Diagnostics.StackTrace st = 
      new System.Diagnostics.StackTrace(ex, true);     

   foreach (System.Diagnostics.StackFrame frame in st.GetFrames()) 
   { 
       sb.AppendLine( frame.GetFileName() + ": " + 
         frame.GetMethod() + ": " + frame.GetFileLineNumber()); 
    } 
    result = sb.ToString(); 
}

Using this code gives me my “custom” Stack trace information.


: Void FCallDivide(System.Decimal ByRef, System.Decimal, System.Decimal): 0
: System.Decimal Divide(System.Decimal, System.Decimal): 0
: System.Decimal op_Division(System.Decimal, System.Decimal): 0
C:\DebuggingPresentation\StackTrace\StackTrace\Program.cs: System.Decimal Divide(System.Decimal, System.Decimal): 45
C:\DebuggingPresentation\StackTrace\StackTrace\Program.cs: System.String GetValue(): 25

So, there you have it. A fairly simple way to get your error line numbers! Good luck with it, and code safe!

Mike

——————-Sample Code here!——————————————–

    class Program 
    { 
        static void Main(string[] args) 
        { 
            Console.WriteLine(GetValue()); 
            Console.ReadLine(); 
        }          

        static string GetValue() 
        { 
            string result = String.Empty;          

            try 
            { 
                result = Divide(3M, 0M).ToString(); 
            } 
            catch (DivideByZeroException ex) 
            { 
               result = ex.StackTrace; 
            }          

            return result; 
        }          

        static decimal Divide(decimal a, decimal b) 
        { 
            return (a / b); 
        } 
    }

October 20, 2007

Doubles, Decimals, and Dividing by Zero

Filed under: Misc Thoughts — dotnetthoughts @ 7:02 am
Tags: , , , , , , , ,

“.Net Exception Divide by zero” often comes up as a search criteria when this blog is hit. (I use division by zero a lot when I’m writing about errors and exception handling. It’s easy to create, and it’s easy to understand.) I couldn’t quite figure out exactly why anybody would be querying on it directly. I think I’ve figured it out, though.

Last week, I was typing up a division example for the blog. For whatever reason, I used double instead of decimal for my input parameters and return value.

   private static double Divide(double i, double j) 
      { 
         return (i / j); 
      }

When I passed in values of 5 and 0 for this method, I was expecting a divide by zero exception. Instead, my console app ran just fine and printed the word Infinity on my screen. I was totally caught off guard by this result. If you pull out an old calculus book, you’ll find that mathematicians often will say that the value of 1/x, as x approaches 0, is infinity (a standard limit), but that 1/0 is undefined. (You can’t take one object and break it into groups of zero.)

When I run the same code above using decimals, instead of doubles, I get a divide by zero exception. This is what I would expect.

With a little bit of thought and poking around, I think that there is a method behind the madness.

Doubles are floating point types. These types are specifically engineered never to throw an exception. Instead, they return values such as infinity, positive infinity, negative infinity, and not a number. Why?

I suspect that the reason has to do with precision. The double type supports numbers as small as +-5*10-324 and as large as +-1.7*10308. Its precision, however is only 15 to 16 digits. Due to the way that floating points are handled, you can’t ever be totally sure exactly what value your Double contains for very large or small numbers. For example, the following code prints out a value of 9.99988867182683E-321 in my output window when I run it:

   private static void DoublePrecision()  
   { 
       double double1 = 1 * Math.Pow((double)10, (double)-320); 
       Trace.WriteLine("double1: " + double1.ToString()); 
   }

This loss of precision means that the compiler itself can’t determine whether a value truly is zero, or if it is a really small number quite close to zero. Mathematically, 1/(10-324)2 is 1/10-648. If the first equation were plugged into .Net, the the result wouldn’t be infinity, but it would be greater than the double can deal with. The convention seems to be to return infinity for my initial divide by zero question.

Decimals, on the other hand, support numbers as small as +-1*10-28 and as large as +-7.9*1028. A decimal’s precision is 28 to 29 significant digits. Since the precision is equal to the exponential power of the range supported, the compiler knows the value it holds in the register is accurate, at least to defined precision. If it thinks it has a zero, it actually has a zero, and can safely throw a DivideByZero error if you try to use it to divide. This added precision is why Microsoft encourages decimals for financial and scientific values.

I’m making some educated guesses behind the thinking of the writers of the IEEE 754 standard, which defines floating types, but I don’t suspect I’m too far off. Let me know if you have any insights!

Good luck and code safe!

Mike

September 29, 2007

Xml Code Snippets

A couple of months ago, I was giving a presentation about Web Services at the Portland Area Code Camp. The presentation was going okay, but I had the dreaded right-after-lunch time slot. The room was a little bit sleepy, to say the least. As I assembled a class, I typed prop and pressed tab twice. Studio diligently dropped a new property skeleton into my code. Suddenly, the room woke up. Everybody wanted to know what the cool add-in was that I was using, and where they could get it from. When I told them it was built into studio, they were elated. I don’t know if any of them remembered anything I had to say about Web Services, but I do know several of them went home and learned about snippets.

Xml Code Snippets are simply keyboard shortcuts for repetitive tasks that you may need to do in the IDE. If you open up the Studio IDE and select Edit–>Intellisense–>Insert Snippet (or press <ctrl>k – <crtl>x), a list of snippets available on the machine appear. Selecting prop, for example, from the list of available C# snippets creates a skeleton property, complete with member variable, into the class.

snippet.JPG

The property snippet highlights three values when dropped on the screen. The type of the property, the name of the property, and the name of the member variable. In the image above, myVar is highlighted. When I modify this variable name and tab off of it, the myVar in the getter and the setter will be updated automatically.

One of the neat things about Snippets is that you can create your own, or update the existing snippets. The included snippets are defined by default in %Program Files%\Microsoft Visual Studio 8\VC#\Snippets\1033\Visual C#. Modifying a snippet in this location will change the snippet for all users using the machine. Snippets can be modified for individual users by placing them in %MyDocuments%\Visual Studio 2005\Code Snippets\Visual C#\My Code Snippets. You can also define your own locations for storing snippets in the Code Snippet Management Window (<ctrl>k – <ctrl>b).

I’ve updated the property code snippet on my machine to take care of a couple of annoyances that I run into when debugging.

First of all, if I’m debugging a method in which I’m passing several properties on an object as parameters, I always have to watch the IDE go down into the getter, and step through retrieving the member variable. Microsoft has given us the ability to automatically move over these steps by adding a DebuggerStepThrough attribute to our code.

Secondly, an object’s data is exposed via the property itself. I don’t need to see the internal variables displayed when I’m using the data tips window. Once again, Microsoft will let us do that with the DebuggerBrowsable attribute.

To update the code snippet on my machine, I simply do the following.

1. Copy the property snippet (prop.snippet) from the location under program files into the location under MyDocuments.
2. Open up the snippet. I’ll see that there are two major areas to the snippet itself. The <Header> element in the Xml provides information about the snippet, and how it will be accessed. The snippet element declares what values the snippet will collect, and how it will apply them.
3. Modify the CDATA section of the Code element to include my new debugger attributes. When I’m done updating, my new Code element appears as follows. (Note that I’m using the fully qualified names so that I don’t have to include System.Diagnostics in every scenario where I want to use my snippet.


<Code Language="csharp">
<![CDATA[[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] private $type$ $field$;
 public $type$ $property$
 {
  [System.Diagnostics.DebuggerStepThrough]
  get { return $field$;}
  [System.Diagnostics.DebuggerStepThrough]
  set { $field$ = value;}
 }
 $end$]]>
</Code>

If I shut down and restart my browser at this point in time, my new snippet appears on the snippet menu.

Microsoft has released a lot of snippet add-ons for visual studio which can be found at http://msdn2.microsoft.com/en-us/vstudio/aa718338.aspx.

Code safe!

 MW

Next Page »

Create a free website or blog at WordPress.com.