How to track an object which is Out of Scope while Debugging ?

In Mastering in Visual Studio 2010 Debugging article I have discussed about the basic of Object ID creation while debugging. I received some request from some readers to explain the use of “Make Object ID” in details. In this blog post I am going explain how we can track an Object which is already out of scope using by creating a Object ID while debugging.

By using “Make Object ID” option we are informing Visual Studio Debugger to keep track of that object no matter it’s within scope or out of scope for the current context.  We can create “Object ID” either from Locals, Autos or from Watch Windows. Object ID is a integer number followed by a pound (#) sign. When we create Object ID for an particular object, Visual Studio Debugger ( CLR Debugging Services )  use an integer value to uniquely identify the object. This “Object ID” allows you to get the object details even if it is out of scope.

Let’s explore this with the help of below code block

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CreateObjectIDDemoApps
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> students = new List<Student> {
                new Student { Roll = 1, Name = "Abhijit", Address = "Hyderabad" },
                new Student { Roll = 2, Name = "Kunal", Address = "Pune" },
                 new Student { Roll = 3, Name = "Abhishek", Address = "Kolkata" },
                  new Student { Roll = 4, Name = "Rahul", Address = "Delhi" }
            };

            foreach (Student stud in students)
            {
                Console.Write(stud.ToString());
            }
        }

        class Student
        {
            public int Roll { get; set; }
            public string Name { get; set; }
            public string Address { get; set; }
            public override string ToString()
            {
                return "Roll : " + this.Roll.ToString() + "\tName : " + this.Name + "\tAddress : " + this.Address + "\n";
            }
        }
    }
}

As per the above code we have a list of Student object. I will show you how we can create new object ID for any specific object and can track them even though went out of scope. 

Creating Object ID

To make an Object Id, You have to view the object from Watch Window, then Right Click > Context Menu, select  “Make Object ID”.

1

The watch window will display a number with the pound (#) sign .

2

The Object ID number will increment based on the object ID Creation. Which means for the next object ID the identification number will be like 2#,3# etc. 

Using Object ID

You have already created an Object ID ( 1#) for a particular student object from list of Student objects. let’s have a look how to use that object Id.  You can easily type the object id in watch window to get the details value of that object.

3

So as per the above image you can see 1# object ID showing the details of the student object with Roll= 1, for which we have created that Object ID.

If you look into the details, you can see, though current break point showing the student details with Roll=3, still 1# Object ID pointing to Student Object with Roll 1, because of 1# object id now uniquely identifying one of the student object.

4

Creating and Using Object ID for Multiple Objects

You can create and use the multiple Object ID using same process that I have discussed. If you want to keep track of more than one object you can use it.

5

When Object goes Out of Scope ?

Till now I have discussed how to create an Object Id and How to use them. Now let’s discuss about the actual use if Object ID. As I have already said,”Object Id is used to track any object even if the object is Out of Scope”. In my above example both the object ID and the actual object was in the scope of current context. Let’s have a look when the object goes out of scope and what is the behavior of Object ID on that time. 

To explore this, Just put a break point out side of foreach statement, where “stud” object is not in the scope. Run the application and Create an object Id for the first object of student lists. Wait till when debugger hits the breakpoint next to foreach statement.

6

Above image is the quick summary of the track of object when object goes out of scope. From the image you can see, “Stud” object is not getting evaluated as it is not in the current scope, but Object ID (1#) is still active which show the actual values of the object for which ID was created. You can also click on the “Refresh” icon with the values of “stud” object to get the updated value. But, If you click on that icon, you will get the message “The name ‘stud’ does not exist in the current context” as shown in below.

7

But you can get the same object values from the Object ID. Though your actual object goes out of scope but it’s not collected by the GC, Object ID still keep the track of that object as the object still present in memory. You will get the message “Can’t evaluated object” once the actual object collected by the GC.

Working with “Out Of Scope” Object ?

You can access any variables or methods from the object Id’s as  ((ClassName)ObjectID#).Properties or ((ClassName)ObjectID#).Method().  As per our example we can access Roll for that Object as shown in below

8

Similarly we can access the same variables from “Immediate Window” as well.

9

Conditional Break Point with Object ID

You can also set conditional  break points with the created object Ids. I have explained about how to use conditional break points over  Mastering in Visual Studio 2010 Debugging – Conditional Breakpoint article.  We have to use the same way that I have mentioned while discussed about the accessing Object ID.

10

Above conditions tell the Visual Studio Debugger that,  If the Object with Object ID 1# having Roll =1, then only hit the break point.

Note: While using Conditional breakpoint you have to make sure you are creating the Object ID before debugger hit the conditional break points. Otherwise you will get the error message with “Object ID not found” as shown in below

11

Delete Object ID

You can delete the object using the similar way that you have used for the creating an Object Id. Right Click on the Object Instance for which you have already created the Object Id, you will get “Delete Object ID” Option

12

If you delete the Object Id with a specific number does not means the next created ID will be the same ID that You have deleted. which means, Let say, you have 3 Object ID’s 1#, 2# and 3#. You have delete the object ID 2#. Now if you create another new Object ID, new ID will be 4# not 2#. Which indicates, one Object ID is used to uniquely Identify a particular object Instance, not for the same object again or for other object. The same ID can only be used once GC collects that object.

13

Summary : In this blog post I have explained how we can use Object ID to keep track of an Out of Scope Object. By using “Make Object ID” option we are informing Visual Studio Debugger to Keep track of that object no matter it’s within scope or out of scope. When we create Object ID for an particular object, Visual Studio Debugger ( CLR Debugging Services )  use an integer value to uniquely identify the object. This “Object ID” allows you to get the object details even if it is out of scope.  If you received the message “Can’t evaluate the Object Values” while working with “Object ID”, it means that Object has been garbage collected. This is another way where you can identify that an Object has been garbage collected.

Hope this will help you !

Thanks !

AJ

21 comments

  1. Pingback: DotNetShoutout
  2. AJ,

    Great post.
    I’ll have to go an try this out myself. It’s one thing to read about it, do it makes it real (at least that how it works for me).
    Thanks,
    I look forward to more handy tips.
    Craig

    Like

  3. Very interesting. There’s another way to do something similar to this. Suppose your in some random debugger context and want to call a method “isValid” that takes an integer argument (ex: 23), is in the namespace “BAR”, and lives in the “foo” DLL. You can call it by typing this in the watch window: {,,foo}BAR::isValid(23)

    Like

Leave a comment