Estoy tratando de agregar una excepción no controlada en el controlador .net (c#), que debe ser tan útil para el usuario como sea posible. Los usuarios finales son en su mayoría programers tan sólo necesitan un toque de qué objeto se que la manipulación incorrecta.

Estoy desarrollando un windows similar a la de windows XP informe de error cuando una aplicación se bloquea, pero que da como mucho inmediatos información como sea posible imediatly acerca de la excepción.

Mientras que el seguimiento de la pila permite a mí (ya tengo el código fuente) para identificar el origen del problema, los usuarios no tienen él y por lo que se pierden sin más información. No hace falta decir que tienen que gastar un montón de tiempo de apoyo de la herramienta.

Hay un par de sistema de excepciones como la de KeyNotFoundException arrojados por el Diccionario de la colección que realmente me incomodan, ya que no se incluyen en el mensaje de la llave que había encontrado. Puedo llenar mi código con toneladas de bloques try catch, pero a su vez agresivo y es mucho más código para mantener, por no hablar de un montón más de las cadenas que terminan siendo localizada.

Finalmente la pregunta: hay alguna manera de obtener (en tiempo de ejecución), los valores de los argumentos de cada función en el seguimiento de pila de llamadas?
Eso por sí solo puede resolver el 90% de las llamadas de soporte.

  • Esto ya ha sido respondido, pero para referencia en el futuro también me gustaría añadir un puntero a Raymond Chen excelente artículo del blog ¿Cuando un objeto se vuelve disponible para la recolección de basura? Entre otras cosas, se señala que de manera fiable la recopilación de los valores de los argumentos de la traza de la pila es imposible, ya que los argumentos pueden ser recogidos, mientras que la referencia a los métodos están todavía en ejecución.
  • He visto que esta stackoverflow.com/questions/2696691/…, pero no sé cómo conseguir el StackTrace de la Exception objeto. El que tiene es un String.
InformationsquelleAutor Caerbanog | 2008-10-01

11 Comentarios

  1. 7

    No creo que el Sistema.Los diagnósticos.StackFrame suministros argumento de información (excepto la firma del método).

    Podría instrumento de la problemática de las llamadas con el registro de seguimiento a través de la AOP, o incluso el uso de la excepción a la interceptación de las características de forma condicional de registro sin tener que basura de su código. Eche un vistazo alrededor de http://www.postsharp.org/.

  2. 6

    Del mismo modo, no he encontrado nada para derivar los parámetros automáticamente en tiempo de ejecución. En lugar de ello, he utilizado un complemento de Visual Studio para generar código de forma explícita que los paquetes de los parámetros, como este:

    public class ExceptionHandler
    {
        public static bool HandleException(Exception ex, IList<Param> parameters)
        {
            /*
             * Log the exception
             * 
             * Return true to rethrow the original exception,
             * else false
             */
        }
    }
    
    public class Param
    {
        public string Name { get; set; }
        public object Value { get; set; }
    }
    
    public class MyClass
    {
        public void RenderSomeText(int lineNumber, string text, RenderingContext context)
        {
            try
            {
                /*
                 * Do some work
                 */
                throw new ApplicationException("Something bad happened");
            }
            catch (Exception ex)
            {
                if (ExceptionHandler.HandleException(
                        ex, 
                        new List<Param>
                        {
                            new Param { Name = "lineNumber", Value=lineNumber },
                            new Param { Name = "text", Value=text },
                            new Param { Name = "context", Value=context}
                        }))
                {
                    throw;
                }
            }
        }
    }

    EDIT: o, alternativamente, haciendo que el parámetro HandleException una matriz de parámetros:

    public static bool HandleException(Exception ex, params Param[] parameters)
    {
       ...
    }
    
    ...
    if (ExceptionHandler.HandleException(
                        ex, 
                        new Param { Name = "lineNumber", Value=lineNumber },
                        new Param { Name = "text", Value=text },
                        new Param { Name = "context", Value=context}
                        ))
    {
        throw;
    }
    ...

    Es un poco de un dolor de generar el código extra para pasar explícitamente los parámetros para el controlador de excepciones, pero con el uso de un complemento al menos puede automatizar.

    Un atributo personalizado puede ser utilizado para anotar todos los parámetros que usted no desea que el add-in para pasar a la excepción de controlador:

    public UserToken RegisterUser( string userId, [NoLog] string password )
    {
    }

    2ª EDICIÓN:

    Mente, me había olvidado por completo de AVICode:

    http://www.avicode.com/

    Que el uso de la interceptación de llamadas técnicas para proporcionar exactamente este tipo de información, entonces debe ser posible.

  3. 3

    Lamentablemente no se puede obtener los valores reales de los parámetros de la pila de llamadas, excepto con herramientas de depuración en realidad se adjunta a la solicitud. Sin embargo usando el StackTrace y el entorno de pila de objetos en el Sistema.El diagnóstico puede caminar por la pila de llamadas y leer todos los métodos invocados y los nombres de los parámetros y tipos. Para hacer esto sería como:

    System.Diagnostics.StackTrace callStack = new System.Diagnostics.StackTrace();
    System.Diagnostics.StackFrame frame = null;
    System.Reflection.MethodBase calledMethod = null;
    System.Reflection.ParameterInfo [] passedParams = null;
    for (int x = 0; x < callStack.FrameCount; x++)
    {
        frame = callStack.GetFrame(x);
        calledMethod = frame.GetMethod();
        passedParams = calledMethod.GetParameters();
        foreach (System.Reflection.ParameterInfo param in passedParams)
            System.Console.WriteLine(param.ToString()); 
    }

    Si usted necesita valores reales, entonces usted va a necesitar tomar minidumps y analizar les tengo miedo. Información sobre la obtención de volcado de información se puede encontrar en:

    http://www.debuginfo.com/tools/clrdump.html

    • El problema con esto es que usted está consiguiendo la pila desde el interior de la Captura, no la pila en el momento de la excepción.
  4. 2

    No es una herramienta de software de redgate, que se ve muy prometedor.

    http://www.red-gate.com/products/dotnet-development/smartassembly/

    Actualmente estamos recogiendo a nuestros clientes informes de error por correo electrónico y yo a veces lucha con algunos datos importantes que faltan (en su mayoría muy variables básicas, como el id del registro actual para que yo pueda reproducir el error). Yo aun no probado esta herramienta, pero a mi entender se hace lo que recoge los valores de los argumentos y variables locales de la pila.

  5. 1

    Yo no creo que exista un mecanismo incorporado. La recuperación de cada fotograma de la traza de la pila, a la vez que permite determinar el método en la traza, sólo le da el reflejo del tipo de información sobre ese método. No hay información de los parámetros. Creo que esto es por qué algunas excepciones, en particular, ArgumentException, et. al. proporciona un mecanismo para especificar el valor del argumento que participan en la excepción, ya que no hay manera fácil de llegar.

  6. 1

    teóricamente es posible hacer lo que usted desea tomar ventaja de el archivo Ejecutable Portable (PE) formato de archivo para obtener los tipos de variables y las compensaciones, pero me encontré con un [documentación] de la pared tratando de hacer de este un par de años atrás. Buena suerte!

  7. 1

    Si usted podría hacer lo que usted está buscando, usted sería derrotar en una parte integral de .RED de seguridad.

    La mejor opción en el caso, adjuntar un depurador o el analizador (cualquiera de ellos puede tener acceso a esos valores). La primera puede ser conectado, éstos deben estar activo antes de que se inicie el programa.

    • +1 por mencionar un tema interesante (de seguridad); pero podría elaborar un poco más sobre cómo se iba a romper la seguridad, o más bien, ¿por qué usted considera que el aspecto «integral»?
  8. 1

    Ya que los usuarios finales son los desarrolladores, que les puede proporcionar con una versión que permite el registro de todos los valores de clave/argumentos que se pasan. Y proporciona un mecanismo para que puedan activar/desactivar el registro.

  9. 0

    No soy consciente de nada de eso, pero quería a mí mismo. Yo suelo hacer yo cuando lanzar excepciones, pero si no es tuyo para lanzar, entonces usted puede estar fuera con el resto de nosotros.

  10. 0

    Una vez que tenga la excepción de las dos cosas que usted está interesado en son de Sistema.Los diagnósticos.StackTrace y del Sistema.Los diagnósticos.StackFrame

    Hay un MSDN ejemplo aquí

    • Ok, pero cuando tengo la Exception no veo una manera de obtener la StackTrace objeto. El StackTrace en la excepción es la representación de Cadena serializada de la pila de llamadas.
    • href=»https://msdn.microsoft.com/en-us/library/4ce0ktkk(v=vs 110).aspx» >msdn.microsoft.com/en-us/library/4ce0ktkk(v=vs 110).aspx
    • te refieres a que debo construir StackTrace objeto mediante la excepción, ya que el parámetro del constructor? Creo que voy a probar que
  11. 0

    No sé una manera de obtener los valores de los argumentos de cada función en la pila de llamadas de seguimiento, pero una solución sería la captura de la excepción específica (KeyNotFoundException en tu ejemplo) y volver a lanzar en una nueva Excepción. Que permite asociar cualquier información adicional que usted desee

    Por ejemplo:

    Dim sKey as String = "some-key"
    Dim sValue as String = String.Empty
    
    Try
       sValue = Dictionary(sKey)
    Catch KeyEx As KeyNotFoundException
       Throw New KeyNotFoundException("Class.Function() - Couldn't find [" & sKey & "]", KeyEx)
    End Try

    Agradezco su declaración acerca de la localización de las cadenas de error, pero si tu audiencia está ‘en su mayoría de programadores, a continuación, la convención ya se dicta una comprensión de inglés en cierto grado (con razón o sin ella -, pero eso es otro debate!)

    • Sí, yo sé que puedo, pero que es exactamente lo que estoy tratando de evitar. Última concluyó he hecho yo tengo unos 200+ llamadas tablas de hash y se va a acelerar apenas cotidiana. Estoy pensando de una función auxiliar, pero todavía se ve feo y sólo resuelve el KeyNotFoundException.
    • Tal vez una función auxiliar es el camino a seguir, lo siento no pude (agregado a mis Favoritos, por lo que puedo comprobar-volver a ver lo que usted decide) :o)

Dejar respuesta

Please enter your comment!
Please enter your name here