Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. How to get local variables and object instance that threw unhandled exception

How to get local variables and object instance that threw unhandled exception

Scheduled Pinned Locked Moved .NET (Core and Framework)
helpcsharpwinformscomdata-structures
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    dybs
    wrote on last edited by
    #1

    A coworker and I are working on a logging system for unhandled exceptions in our code (screenshots, logging system information, detailed exception info, etc) using the Application.ThreadException handler (our main app is in WinForms). From the exception, I can get the MethodInfo for the method that threw the exception, and from that get the DeclaringType of the class, and from that get all the class member variables and their values. Only one problem...I need to pass an instance of the class to the FieldInfo.GetValue method, but I can't find a way to get access to that instance in the ThreadException event handler. I spent a few hours this evening going over the System.Reflection documentation and put toegether a small console app to test a few theories, but I haven't found anything for getting a reference to a class instance from a MethodInfo, MethodBody, or Module object (and yes, I used the AppDomain.UnhandledException event for the console test app instead of Application.ThreadException). Knowing the values of the class variables when the exception occurs would be very useful for debugging. Any ideas? I'm also trying to find a way to get the current values for the function parameters and local variables when the exception occurs. I know, Reflection won't help since these values are all on the stack at runtime, and Reflection works off of compile-time metadata, but there must be some way to get this information. I found this thread[^] that mentions using the Debugging API, but I didn't see anything in that documentation that looked like it would help either. Any suggestions on this one? I'm using VS2005 SP1 on XP Pro SP3 and Win7 Pro. Thanks, Dybs

    The shout of progress is not "Eureka!" it's "Strange... that's not what i expected". - peterchen

    L 1 Reply Last reply
    0
    • D dybs

      A coworker and I are working on a logging system for unhandled exceptions in our code (screenshots, logging system information, detailed exception info, etc) using the Application.ThreadException handler (our main app is in WinForms). From the exception, I can get the MethodInfo for the method that threw the exception, and from that get the DeclaringType of the class, and from that get all the class member variables and their values. Only one problem...I need to pass an instance of the class to the FieldInfo.GetValue method, but I can't find a way to get access to that instance in the ThreadException event handler. I spent a few hours this evening going over the System.Reflection documentation and put toegether a small console app to test a few theories, but I haven't found anything for getting a reference to a class instance from a MethodInfo, MethodBody, or Module object (and yes, I used the AppDomain.UnhandledException event for the console test app instead of Application.ThreadException). Knowing the values of the class variables when the exception occurs would be very useful for debugging. Any ideas? I'm also trying to find a way to get the current values for the function parameters and local variables when the exception occurs. I know, Reflection won't help since these values are all on the stack at runtime, and Reflection works off of compile-time metadata, but there must be some way to get this information. I found this thread[^] that mentions using the Debugging API, but I didn't see anything in that documentation that looked like it would help either. Any suggestions on this one? I'm using VS2005 SP1 on XP Pro SP3 and Win7 Pro. Thanks, Dybs

      The shout of progress is not "Eureka!" it's "Strange... that's not what i expected". - peterchen

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      There's no easy way built-in to do this, but.. As an alternative, there's a Data[^] property on the exception. Perhaps you could put the internal state of the object that's throwing the exception in there?

      I are Troll :suss:

      D 1 Reply Last reply
      0
      • L Lost User

        There's no easy way built-in to do this, but.. As an alternative, there's a Data[^] property on the exception. Perhaps you could put the internal state of the object that's throwing the exception in there?

        I are Troll :suss:

        D Offline
        D Offline
        dybs
        wrote on last edited by
        #3

        Eddy, Thanks for the reply. In my case that won't really work because I need this information in the UnhandledException handler, and by the time I get to this point (the first time I actually have an exception to look at), I no longer have access to the object that threw the exception. I can certainly use this where I can handle an exception more gracefully and still want to log it with more details, but my goal is to get as much info as I can for unhandled exceptions. Thanks, Dybs

        The shout of progress is not "Eureka!" it's "Strange... that's not what i expected". - peterchen

        L 1 Reply Last reply
        0
        • D dybs

          Eddy, Thanks for the reply. In my case that won't really work because I need this information in the UnhandledException handler, and by the time I get to this point (the first time I actually have an exception to look at), I no longer have access to the object that threw the exception. I can certainly use this where I can handle an exception more gracefully and still want to log it with more details, but my goal is to get as much info as I can for unhandled exceptions. Thanks, Dybs

          The shout of progress is not "Eureka!" it's "Strange... that's not what i expected". - peterchen

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          dybs wrote:

          my goal is to get as much info as I can for unhandled exceptions

          Ditto, and you're right - if the information contained helps with the debugging-proces. There's no easy anwer to your question, once one says that it's technically possible one has to answer whether it's worth the effort.

          dybs wrote:

          In my case that won't really work because I need this information in the UnhandledException handler, and by the time I get to this point (the first time I actually have an exception to look at), I no longer have access to the object that threw the exception.

          I have created a small console-application to test with;

          class Program
          {
          static Form myForm = new Form();
          static Button myButton = new Button();

          \[STAThread\]
          public static void Main(string\[\] args)
          {												
              myButton.Click += delegate 
              {
                  new MyTextCache().DoLoadStuff();
              };
              myForm.Controls.Add(myButton);
          	
              AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(logEx);
              Application.Run(myForm);
          }
          
          static void logEx(object sender, UnhandledExceptionEventArgs e)
          {
              Exception ex = (Exception)e.ExceptionObject;
              Console.WriteLine("Exception: " + e.ExceptionObject.GetType().ToString());
              if (ex.Data.Count > 0)
              {
                  foreach(var item in ex.Data)
                  {
                      var entry = (System.Collections.DictionaryEntry)item;
                      Console.WriteLine("Parameter: " + entry.Value.ToString());
                  }
              }
          }
          

          }

          Rather simple, just creates a form with a button and logs any exceptions on the console. The key here is looping the Data property. We know that we can fill it when we throw an exception ourselves. Now, imagine that there's an unexpected exception thrown by a .NET class in the MyTextCache.DoLoadStuff method. To add the info, we'd need to catch it, attach the desired information, and rethrow it. The MyTextCache could be adapted like shown below. There's a local exception-handler that doesn't handle the FileNotFound-exception, but instead adds a reference to the object;

          using System.Runtime.Serialization;
          using System.Runtime.Serialization.Formatters.Binary;
          using System.Windows.Forms;

          [Serializable()]
          class MyTextCache: ISerializable
          {
          #region variable

          D 1 Reply Last reply
          0
          • L Lost User

            dybs wrote:

            my goal is to get as much info as I can for unhandled exceptions

            Ditto, and you're right - if the information contained helps with the debugging-proces. There's no easy anwer to your question, once one says that it's technically possible one has to answer whether it's worth the effort.

            dybs wrote:

            In my case that won't really work because I need this information in the UnhandledException handler, and by the time I get to this point (the first time I actually have an exception to look at), I no longer have access to the object that threw the exception.

            I have created a small console-application to test with;

            class Program
            {
            static Form myForm = new Form();
            static Button myButton = new Button();

            \[STAThread\]
            public static void Main(string\[\] args)
            {												
                myButton.Click += delegate 
                {
                    new MyTextCache().DoLoadStuff();
                };
                myForm.Controls.Add(myButton);
            	
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(logEx);
                Application.Run(myForm);
            }
            
            static void logEx(object sender, UnhandledExceptionEventArgs e)
            {
                Exception ex = (Exception)e.ExceptionObject;
                Console.WriteLine("Exception: " + e.ExceptionObject.GetType().ToString());
                if (ex.Data.Count > 0)
                {
                    foreach(var item in ex.Data)
                    {
                        var entry = (System.Collections.DictionaryEntry)item;
                        Console.WriteLine("Parameter: " + entry.Value.ToString());
                    }
                }
            }
            

            }

            Rather simple, just creates a form with a button and logs any exceptions on the console. The key here is looping the Data property. We know that we can fill it when we throw an exception ourselves. Now, imagine that there's an unexpected exception thrown by a .NET class in the MyTextCache.DoLoadStuff method. To add the info, we'd need to catch it, attach the desired information, and rethrow it. The MyTextCache could be adapted like shown below. There's a local exception-handler that doesn't handle the FileNotFound-exception, but instead adds a reference to the object;

            using System.Runtime.Serialization;
            using System.Runtime.Serialization.Formatters.Binary;
            using System.Windows.Forms;

            [Serializable()]
            class MyTextCache: ISerializable
            {
            #region variable

            D Offline
            D Offline
            dybs
            wrote on last edited by
            #5

            Thanks for the detailed response! I'm looking more into the data dictionary now and serializing the objects. One other question. I notices after you throw add the values to the Data dictionary, you use

            throw e;

            Doesn't this "reset" the stack track to the line where you rethrow the exception? Can you just use

            throw;

            instead? Or would a simple throw not include your changes to the dictionary? Thanks, Dybs

            The shout of progress is not "Eureka!" it's "Strange... that's not what i expected". - peterchen

            L 1 Reply Last reply
            0
            • D dybs

              Thanks for the detailed response! I'm looking more into the data dictionary now and serializing the objects. One other question. I notices after you throw add the values to the Data dictionary, you use

              throw e;

              Doesn't this "reset" the stack track to the line where you rethrow the exception? Can you just use

              throw;

              instead? Or would a simple throw not include your changes to the dictionary? Thanks, Dybs

              The shout of progress is not "Eureka!" it's "Strange... that's not what i expected". - peterchen

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              dybs wrote:

              Thanks for the detailed response! I'm looking more into the data dictionary now and serializing the objects.

              My pleasure. Tracking the items in a dictionary would indeed be a nice alternative :)

              dybs wrote:

              Doesn't this "reset" the stack track to the line where you rethrow the exception?

              It does! That was sloppiness in my example.

              dybs wrote:

              Or would a simple throw not include your changes to the dictionary?

              It also includes the change if you omit the exception variable. Just verified it, just to be on the safe side.

              I are Troll :suss:

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups