Estoy escribiendo una biblioteca que me gustaría ser portátil. Por lo tanto, no debe depender de glibc o extensiones de Microsoft o cualquier otra cosa que no esté en el estándar. Tengo una buena jerarquía de clases derivadas de std :: exception que utilizo para manejar errores en lógica y entrada. Saber que un tipo particular de excepción fue arrojado a un número de línea y archivo en particular es útil, pero saber cómo llegó la ejecución sería potencialmente mucho más valioso, así que he estado buscando formas de adquirir el seguimiento de la pila.Rastreo de pila portátil C++ en la excepción
Soy consciente de que estos datos están disponibles en la construcción con glibc utilizando las funciones de execinfo.h (ver question 76822) ya través de la interfaz StackWalk en C de Microsoft aplicación ++ (ver question 126450), pero me gustaría mucho para evitar cualquier cosa eso no es portátil
Estaba pensando en implementar esta funcionalidad a mí mismo en esta forma:
class myException : public std::exception
{
public:
...
void AddCall(std::string s)
{ m_vCallStack.push_back(s); }
std::string ToStr() const
{
std::string l_sRet = "";
...
l_sRet += "Call stack:\n";
for(int i = 0; i < m_vCallStack.size(); i++)
l_sRet += " " + m_vCallStack[i] + "\n";
...
return l_sRet;
}
private:
...
std::vector<std::string> m_vCallStack;
};
ret_type some_function(param_1, param_2, param_3)
{
try
{
...
}
catch(myException e)
{
e.AddCall("some_function(" + param_1 + ", " + param_2 + ", " + param_3 + ")");
throw e;
}
}
int main(int argc, char * argv[])
{
try
{
...
}
catch (myException e)
{
std::cerr << "Caught exception: \n" << e.ToStr();
return 1;
}
return 0;
}
¿Es esta una idea terrible? Significaría mucho trabajo agregar bloques try/catch a cada función, pero puedo vivir con eso. No funcionaría cuando la causa de la excepción es la corrupción de la memoria o la falta de memoria, pero en ese punto estás bastante jodida de todos modos. Puede proporcionar información engañosa si algunas funciones en la pila no detectan excepciones, se agregan a la lista y vuelven a lanzar, pero al menos puedo garantizar que todas las funciones de mi biblioteca lo hacen. A diferencia de una traza de pila "real", no obtendré el número de línea en las funciones de llamada, pero al menos tendría algo.
Mi principal preocupación es la posibilidad de que esto cause una desaceleración incluso cuando no se lanzan excepciones. ¿Todos estos bloques de prueba/captura requieren una configuración y extracción adicionales en cada invocación de función, o se manejan de alguna manera en tiempo de compilación? ¿O hay otros problemas que no he considerado?
Consulte la http://www.gotw.ca/gotw/047.htm de Herb Sutter para obtener otra perspectiva. – AJG85