Pregunta

Estamos produciendo un código portátil (win+macOs) y estamos buscando cómo hacer que el código sea más robusto ya que falla de vez en cuando...(normalmente se desbordan o inicializan mal) :-(

Estaba leyendo que Google Chrome usa un proceso para cada pestaña, por lo que si algo sale mal, el programa no falla por completo, solo esa pestaña.Creo que es bastante interesante, ¡así que podría intentarlo!

Así que me preguntaba si alguien tiene algunos consejos, ayuda, lista de lectura, comentario o algo que pueda ayudarme a crear código C++ más robusto (lo portátil siempre es mejor).

En el mismo tema, también me preguntaba si existe una biblioteca portátil para procesos (como boost).

Bueno muchas gracias.

¿Fue útil?

Solución

He desarrollado en numerosas aplicaciones C++ multiplataforma (la más grande tiene 1,5 millones de líneas de código y se ejecuta en 7 plataformas: AIX, HP-UX PA-RISC, HP-UX Itanium, Solaris, Linux, Windows, OS X). .De hecho, tienes dos problemas completamente diferentes en tu publicación.

  1. Inestabilidad.Tu código no es estable.Arreglalo.

    • Utilice pruebas unitarias para encontrar problemas lógicos antes de que lo maten.
    • Utilice depuradores para descubrir qué está causando los fallos si no es obvio.
    • Utilice boost y bibliotecas similares.En particular, los tipos de puntero le ayudarán a evitar pérdidas de memoria.
  2. Codificación multiplataforma.

    • Nuevamente, utilice bibliotecas diseñadas para esto cuando sea posible.Particularmente para cualquier bit de GUI.
    • Utilice estándares (p. ej.ANSI vs gcc/MSVC, subprocesos POSIX versus modelos de subprocesos específicos de Unix, etc.) tanto como sea posible, incluso si requiere un poco más de trabajo.Minimizar el código específico de su plataforma significa menos trabajo general y menos API para aprender.
    • Aislar, aislar, aislar.Evite los #ifdefs en línea para diferentes plataformas tanto como sea posible.En su lugar, inserte el código específico de la plataforma en su propio encabezado/fuente/clase y use su sistema de compilación y #includes para obtener el código correcto.Esto ayuda a mantener el código limpio y legible.
    • Utilice los tipos de enteros C99 si es posible en lugar de "largo", "int", "corto", etc.; de lo contrario, le molestará cuando pase de una plataforma de 32 bits a una de 64 bits y los largos cambien repentinamente. de 4 bytes a 8 bytes.Y si eso alguna vez se escribe en la red/disco/etc., entonces se encontrará con incompatibilidad entre plataformas.

Personalmente, primero estabilizaría el código (sin agregar más funciones) y luego me ocuparía de los problemas multiplataforma, pero eso depende de usted.Tenga en cuenta que Visual Studio tiene un excelente depurador (el código base mencionado anteriormente se transfirió a Windows solo por ese motivo).

Otros consejos

La respuesta de Chrome tiene más que ver con la mitigación de fallas y no con la calidad del código.Hacer lo que hace Chrome es admitir la derrota.

  1. Mejor control de calidad que es más que solo un programador probando su propio trabajo.
  2. Examen de la unidad
  3. Pruebas de regresión
  4. Lea las mejores prácticas que usan otras compañías.

Para ser franco, si su software falla con frecuencia debido a desbordamientos y malas inicializaciones, entonces tiene un problema de calidad de programación muy básico que no se solucionará fácilmente.Eso suena hastiado y cruel, esa no es mi intención.Mi punto es que el problema con el código incorrecto tiene que ser su principal preocupación (que estoy seguro de que lo es).Cosas como Chrome o el uso liberal del manejo de excepciones para detectar fallas en el programa solo lo distraen del problema real.

No menciona cuál es el proyecto objetivo;tener un proceso por pestaña no significa necesariamente un código más "robusto".Deberías intentar escribir código sólido con pruebas independientemente de la portabilidad; solo lee sobre cómo escribir un buen código C++ :)

En cuanto a la sección de portabilidad, asegúrese de realizar pruebas en ambas plataformas desde el primer día y asegúrese de que no se escriba ningún código nuevo hasta que se resuelvan los problemas específicos de la plataforma.

Realmente no quieres hacer lo que Chrome está haciendo, requiere un administrador de procesos que probablemente sea MUY excesivo para lo que quieres.

Debería investigar el uso de punteros inteligentes de Boost u otra herramienta que proporcione recuento de referencias o recolección de basura para C++.

Alternativamente, si falla con frecuencia, quizás desee considerar escribir partes críticas de su aplicación que no sean de rendimiento en un lenguaje de secuencias de comandos que tenga enlaces C++.

Scott Meyers C++ efectivo y C++ más eficaz son muy buenos y divertidos de leer.

Steve McConnell Código completo es el favorito de muchos, incluido Jeff Atwood.

Las bibliotecas Boost son probablemente una excelente opción.Un proyecto en el que trabajo los utiliza.Yo solo he usado subprocesos WIN32.

Estoy de acuerdo con Torlack.

Una mala inicialización o desbordamientos son signos de código de mala calidad.

Google lo hizo así porque, a veces, no había forma de controlar el código que se ejecutaba en una página (debido a complementos defectuosos, etc.).Entonces, si estás usando complementos de baja calidad (sucede), tal vez la solución de Google sea buena para ti.

Pero un programa sin complementos que falla a menudo simplemente está mal escrito, es muy, muy complejo o muy antiguo (y le falta mucho tiempo de mantenimiento).Debes detener el desarrollo e investigar todos y cada uno de los fallos.En Windows, compile los módulos con PDB (bases de datos de programas) y, cada vez que falle, adjunte un depurador.

También debes agregar pruebas internas.Evite el patrón:

doSomethingBad(T * t)
{
   if(t == NULL) return ;

   // do the processing.
}

Este es un diseño muy malo porque el error está ahí y simplemente lo evitas. esta vez.Pero la siguiente función sin esta protección fallará.Es mejor fallar antes para estar más cerca del error.

En cambio, en Windows (debe haber una API similar en MacOS)

doSomethingBad(T * t)
{
   if(t == NULL) ::DebugBreak() ; // it will call the debugger

   // do the processing.
}

(No uses este código directamente...Póngalo en una definición para evitar entregarlo a un cliente ...) Puede elegir la API de error que le convenga (excepciones, break, afirmar, etc.), pero úselo para detener el momento en que el código sabe que algo está mal.

Evite la API C siempre que sea posible.Utilice modismos y bibliotecas de C++ (RAII, etc.).

Etc..

PD.:Si usa excepciones (que es una buena opción), no las oculte dentro de un catch.Sólo empeorará el problema porque el error está ahí, pero el programa intentará continuar y probablemente a veces se bloqueará después y corromperá todo lo que toque mientras tanto.

Siempre puedes agregar manejo de excepciones a tu programa para detectar este tipo de fallas e ignorarlas (aunque los detalles son específicos de la plataforma)...pero eso es en gran medida un arma de dos filos.En su lugar, considere hacer que el programa detecte las excepciones y cree archivos de volcado para su análisis.

Si su programa se ha comportado de manera inesperada, ¿qué sabe sobre su estado interno?¿Quizás la rutina/hilo que falló ha corrompido alguna estructura de datos clave?¿Quizás si detecta el error e intenta continuar, el usuario guardará todo en lo que esté trabajando y enviará la corrupción al disco?

Además de escribir código más estable, aquí tienes una idea que responde a tu pregunta.

Ya sea que esté utilizando procesos o subprocesos.Puede escribir un programa de vigilancia pequeño/simple.Entonces sus otros programas se registran con ese organismo de control.Si algún proceso muere, o un hilo muere, el perro guardián puede reiniciarlo.Por supuesto, querrás realizar algunas pruebas para asegurarte de no seguir reiniciando el mismo hilo con errores.es decir:reinícielo 5 veces, luego, después de la quinta, cierre todo el programa e inicie sesión en el archivo/syslog.

Cree su aplicación con símbolos de depuración, luego agregue un controlador de excepciones o configure Dr Watson para generar volcados de memoria (ejecute drwtsn32.exe /i para instalarlo como depurador, sin /i para abrir el cuadro de diálogo de configuración).Cuando su aplicación falla, puede inspeccionar dónde salió mal en Windbg o Visual Studio viendo una pila de llamadas y variables.

Busque en Google el servidor de símbolos para obtener más información.

Obviamente, puede usar el manejo de excepciones para hacerlo más robusto y usar punteros inteligentes, pero lo mejor es corregir los errores.

Le recomendaría que compilara una versión de Linux y la ejecutara en Valgrind.

Valgrind rastreará pérdidas de memoria, lecturas de memoria no inicializadas y muchos otros problemas de código.Lo recomiendo altamente.

Después de más de 15 años de desarrollo de Windows, recientemente escribí mi primera aplicación C++ multiplataforma (Windows/Linux).Así es cómo:

  • STL
  • Aumentar.En particular, el sistema de archivos y las bibliotecas de subprocesos.
  • Una interfaz de usuario basada en navegador.La aplicación 'hace' HTTP, con la interfaz de usuario que consta de XHTML/CSS/JavaScript (estilo Ajax).Estos recursos están integrados en el código del servidor y se entregan al navegador cuando es necesario.
  • Numerosas pruebas unitarias.No del todo TDD, pero cerca.En realidad, esto cambió mi forma de desarrollarme.

Utilicé NetBeans C++ para la compilación de Linux y obtuve un puerto Linux completo en muy poco tiempo.

Constrúyalo con la idea de que la única forma de salir es que el programa falle y que puede fallar en cualquier momento.Cuando lo construyes de esa manera, al fallar nunca o casi nunca se perderán datos.Leí un artículo al respecto hace uno o dos años.Lamentablemente, no tengo un enlace a él.

Combine eso con algún tipo de volcado de memoria y pídale que se lo envíe por correo electrónico para que pueda solucionar el problema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top