Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 246629
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T21:11:19+00:00 2026-05-11T21:11:19+00:00

My question is really the same as this one Finding out what exceptions a

  • 0

My question is really the same as this one “Finding out what exceptions a method might throw in C#”. However, I would really like to know if anyone knows of a way to determine the stack of all the exceptions that may be thrown by a given method. I am hoping for a tool or utility that I can analyze code at compile time or through reflection like FxCop, StyleCop, or NCover. I do not need this information at run time I just want to make sure we are trapping exceptions and logging them correctly in out code.

We are currently trapping the exceptions that we know about and logging all the wild cards. This does work well; however, i was just hoping someone has used or knows of a tool that can discover this information.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T21:11:19+00:00Added an answer on May 11, 2026 at 9:11 pm

    Following up to my previous answer, I’ve managed to create a basic exception finder. It utilises a reflection-based ILReader class, available here on Haibo Luo’s MSDN blog. (Just add a reference to the project.)

    Updates:

    1. Now handles local variables and the stack.
      • Correctly detects exceptions returned from method calls or fields and later thrown.
      • Now handles stack pushes/pops fully and appropiately.

    Here is the code, in full. You simply want to use the GetAllExceptions(MethodBase) method either as an extension or static method.

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Reflection;
    using System.Reflection.Emit;
    using System.Text;
    using ClrTest.Reflection;
    
    public static class ExceptionAnalyser
    {
        public static ReadOnlyCollection<Type> GetAllExceptions(this MethodBase method)
        {
            var exceptionTypes = new HashSet<Type>();
            var visitedMethods = new HashSet<MethodBase>();
            var localVars = new Type[ushort.MaxValue];
            var stack = new Stack<Type>();
            GetAllExceptions(method, exceptionTypes, visitedMethods, localVars, stack, 0);
    
            return exceptionTypes.ToList().AsReadOnly();
        }
    
        public static void GetAllExceptions(MethodBase method, HashSet<Type> exceptionTypes,
            HashSet<MethodBase> visitedMethods, Type[] localVars, Stack<Type> stack, int depth)
        {
            var ilReader = new ILReader(method);
            var allInstructions = ilReader.ToArray();
    
            ILInstruction instruction;
            for (int i = 0; i < allInstructions.Length; i++)
            {
                instruction = allInstructions[i];
    
                if (instruction is InlineMethodInstruction)
                {
                    var methodInstruction = (InlineMethodInstruction)instruction;
    
                    if (!visitedMethods.Contains(methodInstruction.Method))
                    {
                        visitedMethods.Add(methodInstruction.Method);
                        GetAllExceptions(methodInstruction.Method, exceptionTypes, visitedMethods,
                            localVars, stack, depth + 1);
                    }
    
                    var curMethod = methodInstruction.Method;
                    if (curMethod is ConstructorInfo)
                        stack.Push(((ConstructorInfo)curMethod).DeclaringType);
                    else if (method is MethodInfo)
                        stack.Push(((MethodInfo)curMethod).ReturnParameter.ParameterType);
                }
                else if (instruction is InlineFieldInstruction)
                {
                    var fieldInstruction = (InlineFieldInstruction)instruction;
                    stack.Push(fieldInstruction.Field.FieldType);
                }
                else if (instruction is ShortInlineBrTargetInstruction)
                {
                }
                else if (instruction is InlineBrTargetInstruction)
                {
                }
                else
                {
                    switch (instruction.OpCode.Value)
                    {
                        // ld*
                        case 0x06:
                            stack.Push(localVars[0]);
                            break;
                        case 0x07:
                            stack.Push(localVars[1]);
                            break;
                        case 0x08:
                            stack.Push(localVars[2]);
                            break;
                        case 0x09:
                            stack.Push(localVars[3]);
                            break;
                        case 0x11:
                            {
                                var index = (ushort)allInstructions[i + 1].OpCode.Value;
                                stack.Push(localVars[index]);
                                break;
                            }
                        // st*
                        case 0x0A:
                            localVars[0] = stack.Pop();
                            break;
                        case 0x0B:
                            localVars[1] = stack.Pop();
                            break;
                        case 0x0C:
                            localVars[2] = stack.Pop();
                            break;
                        case 0x0D:
                            localVars[3] = stack.Pop();
                            break;
                        case 0x13:
                            {
                                var index = (ushort)allInstructions[i + 1].OpCode.Value;
                                localVars[index] = stack.Pop();
                                break;
                            }
                        // throw
                        case 0x7A:
                            if (stack.Peek() == null)
                                break;
                            if (!typeof(Exception).IsAssignableFrom(stack.Peek()))
                            {
                                //var ops = allInstructions.Select(f => f.OpCode).ToArray();
                                //break;
                            }
                            exceptionTypes.Add(stack.Pop());
                            break;
                        default:
                            switch (instruction.OpCode.StackBehaviourPop)
                            {
                                case StackBehaviour.Pop0:
                                    break;
                                case StackBehaviour.Pop1:
                                case StackBehaviour.Popi:
                                case StackBehaviour.Popref:
                                case StackBehaviour.Varpop:
                                    stack.Pop();
                                    break;
                                case StackBehaviour.Pop1_pop1:
                                case StackBehaviour.Popi_pop1:
                                case StackBehaviour.Popi_popi:
                                case StackBehaviour.Popi_popi8:
                                case StackBehaviour.Popi_popr4:
                                case StackBehaviour.Popi_popr8:
                                case StackBehaviour.Popref_pop1:
                                case StackBehaviour.Popref_popi:
                                    stack.Pop();
                                    stack.Pop();
                                    break;
                                case StackBehaviour.Popref_popi_pop1:
                                case StackBehaviour.Popref_popi_popi:
                                case StackBehaviour.Popref_popi_popi8:
                                case StackBehaviour.Popref_popi_popr4:
                                case StackBehaviour.Popref_popi_popr8:
                                case StackBehaviour.Popref_popi_popref:
                                    stack.Pop();
                                    stack.Pop();
                                    stack.Pop();
                                    break;
                            }
    
                            switch (instruction.OpCode.StackBehaviourPush)
                            {
                                case StackBehaviour.Push0:
                                    break;
                                case StackBehaviour.Push1:
                                case StackBehaviour.Pushi:
                                case StackBehaviour.Pushi8:
                                case StackBehaviour.Pushr4:
                                case StackBehaviour.Pushr8:
                                case StackBehaviour.Pushref:
                                case StackBehaviour.Varpush:
                                    stack.Push(null);
                                    break;
                                case StackBehaviour.Push1_push1:
                                    stack.Push(null);
                                    stack.Push(null);
                                    break;
                            }
    
                            break;
                    }
                }
            }
        }
    }
    

    To summarise, this algorithm recursively enumerates (depth-first) any methods called within the specified one, by reading the CIL instructions (as well as keeping track of methods already visited). It maintains a single list of collections that can be thrown using a HashSet<T> object, which is returned at the end. It additionally maintains an array of local variables and a stack, in order to keep track of exceptions that aren’t thrown immediately after they are created.

    Of course, this code isn’t infallible in it’s current state. There are a few improvements that I need to make for it to be robust, namely:

    1. Detect exceptions that aren’t thrown directly using an exception constructor. (i.e. The exception is retrieved from a local variable or a method call.)
    2. Support exceptions popped off the stack then later pushed back on.
    3. Add flow-control detection. Try-catch blocks that handle any thrown exception should remove the appropiate exception from the list, unless a rethrow instruction is detected.

    Apart from that, I believe the code is reasonably complete. It may take a bit more investigation before I figure out exactly how to do the flow-control detection (though I believe I can see how it operates at the IL-level now).

    These functions could probably be turned into an entire library if one was to create a full-featured “exception analyser”, but hopefully this will at least provide a sound starting point for such a tool, if not already good enough in its current state.

    Anyway, hope that helps!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 121k
  • Answers 121k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer You can see the naming conventions laid out here. Cake… May 12, 2026 at 12:29 am
  • Editorial Team
    Editorial Team added an answer I tested it on my machine, on both the class… May 12, 2026 at 12:29 am
  • Editorial Team
    Editorial Team added an answer I don't know about Qt, but there is an easy… May 12, 2026 at 12:29 am

Related Questions

Whenever I see a problem that would be shared by others, with a solution
I'm rewriting our NAnt build scripts to make them cleaner and simpler, as well
I'd appreciate some opinions on a concern I have. I have a [User] table
Well I run a small video website and on the actual video page there

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.