Question

Nous produisons un code portable (win + macOs) et nous essayons de le rendre plus précis car il se bloque de temps en temps ... (généralement avec débordements ou mauvaises initialisations): - (

Je lisais que Google Chrome utilise un processus pour chaque onglet. Par conséquent, en cas de problème, le programme ne se bloque pas complètement, mais uniquement cet onglet. Je pense que c'est assez chouette, alors je pourrais essayer!

Je me demandais donc si quelqu'un avait des astuces, de l'aide, une liste de lecture, des commentaires ou quelque chose qui pourrait m'aider à construire davantage de code Rubust C ++ (portable, c'est toujours mieux).

Dans le même sujet, je me demandais également s'il existait une bibliothèque portable pour les processus (comme boost)?

Bien merci beaucoup.

Était-ce utile?

La solution

J'ai développé de nombreuses applications C ++ multiplates-formes (la plus grande de 1,5 million de lignes de code et fonctionnant sur 7 plates-formes: AIX, PA-RISC HP-UX, Itanium HP, UX, Solaris, Linux, Windows, etc.). OS X). Vous avez en fait deux problèmes totalement différents dans votre message.

  1. Instabilité. Votre code n'est pas stable. Répare le.

    • Utilisez les tests unitaires pour détecter les problèmes de logique avant qu'ils ne vous tuent.
    • Utilisez les débogueurs pour découvrir la cause des blocages si cela n’est pas évident.
    • Utilisez boost et des bibliothèques similaires. Les types de pointeurs vous aideront notamment à éviter les fuites de mémoire.
  2. Codage multiplateforme.

    • Encore une fois, utilisez des bibliothèques conçues pour cela lorsque cela est possible. Particulièrement pour les bits d'interface graphique.
    • Utilisez les normes (par exemple ANSI vs gcc / MSVC, threads POSIX vs modèles de threads spécifiques à Unix, etc.) autant que possible, même si cela nécessite un peu plus de travail. Réduire au minimum le code spécifique à votre plate-forme signifie moins de travail global et moins d’API à apprendre.
    • Isolez, isolez, isolez. Évitez autant que possible les #ifdefs en ligne pour différentes plates-formes. Au lieu de cela, collez du code spécifique à la plate-forme dans son propre en-tête / source / classe et utilisez votre système de construction et #includes pour obtenir le bon code. Cela aide à garder le code propre et lisible.
    • Si possible, utilisez les types entiers C99 à la place de "long", "int", "court", etc. bit un et long change soudainement de 4 octets à 8 octets. Et si cela est déjà écrit sur le réseau / disque / etc, vous rencontrerez une incompatibilité entre les plates-formes.

Personnellement, je stabilisais d'abord le code (sans ajouter de fonctionnalités supplémentaires), puis je réglais les problèmes multi-plateformes, mais cela dépend de vous. Notez que Visual Studio a un excellent débogueur (la base de code mentionnée ci-dessus a été portée sous Windows uniquement pour cette raison).

Autres conseils

La réponse de Chrome concerne davantage la réduction des défaillances que la qualité du code. Faire ce que Chrome fait, c'est admettre sa défaite.

  1. Une meilleure assurance qualité, c'est bien plus qu'un simple programmeur qui teste son propre travail.
  2. Test unitaire
  3. Test de régression
  4. Renseignez-vous sur les meilleures pratiques que d’autres les entreprises utilisent.

Pour être franc, si votre logiciel plante souvent à cause de débordements et de mauvaises initialisations, vous rencontrez un problème de base de qualité de programmation qui ne sera pas facilement résolu. Cela semble un hasch et moyen, ce n'est pas mon intention. Mon point est que le problème avec le code incorrect doit être votre principale préoccupation (ce qui est, j'en suis sûr). Des choses comme Chrome ou libérale utilisent la gestion des exceptions pour attraper la faille du programme ne font que vous distraire du vrai problème.

Vous ne mentionnez pas le projet cible; avoir un processus par onglet ne signifie pas nécessairement plus "robuste" code du tout. Vous devriez viser à écrire du code solide avec des tests, quelle que soit la portabilité. Lisez simplement comment écrire du bon code C ++:)

En ce qui concerne la section sur la portabilité, assurez-vous de tester les deux plates-formes dès le premier jour et qu'aucun nouveau code n'est écrit jusqu'à ce que les problèmes spécifiques à la plate-forme soient résolus.

Vous ne voulez vraiment pas faire ce que Chrome fait, cela nécessite un gestionnaire de processus qui est probablement BEAUCOUP pour ce que vous voulez.

Vous devriez envisager d'utiliser des pointeurs intelligents de Boost ou un autre outil fournissant un comptage de références ou un garbage collection pour C ++.

Sinon, si vous rencontrez des problèmes de plantage fréquents, vous pouvez envisager de rédiger des parties critiques de votre application non performantes dans un langage de script doté de liaisons C ++.

Les C ++ effectifs et Plus efficaces du C ++ de Scott Meyers sont très bons et amusants à lire.

Le code Code Complete de Steve McConnell est un favori de beaucoup, y compris Jeff Atwood.

Les bibliothèques Boost sont probablement un excellent choix. Un projet où je travaille les utilise. Je n'ai utilisé que le threading WIN32 moi-même.

Je suis d'accord avec Torlack.

Une mauvaise initialisation ou des débordements sont des signes d'un code de mauvaise qualité.

Google l'a fait de cette façon car parfois, il n'existait aucun moyen de contrôler le code exécuté dans une page (à cause de plugins défectueux, etc.). Donc, si vous utilisez des plug-ins de mauvaise qualité (cela arrive), la solution de Google vous conviendra peut-être.

Mais un programme sans plugins qui plante souvent est simplement mal écrit, ou très très complexe, ou très vieux (et manque beaucoup de temps de maintenance). Vous devez arrêter le développement et enquêter sur chaque crash. Sous Windows, compilez les modules avec des PDB (bases de données de programmes) et attachez-y un débogueur à chaque plantage.

Vous devez également ajouter des tests internes. Évitez le motif:

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

   // do the processing.
}

La conception est très mauvaise car l’erreur est là et vous l’évitez, cette fois . Mais la prochaine fonction sans cette garde va planter. Mieux vaut planter plus tôt pour être plus proche de l'erreur.

À la place, sous Windows (une API similaire doit exister sous MacOS)

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

   // do the processing.
}

(n'utilisez pas ce code directement ... Mettez-le dans une définition pour éviter de le transmettre à un client ...) Vous pouvez choisir l’API d’erreur qui vous convient (exceptions, DebugBreak, assert, etc.), mais utilisez-la pour arrêter le moment où le code détecte que quelque chose ne va pas.

Évitez l’API C chaque fois que possible. Utilisez les idiomes C ++ (RAII, etc.) et les bibliothèques.

Etc ..

P.S .: Si vous utilisez des exceptions (ce qui est un bon choix), ne les cachez pas dans une capture. Votre problème ne fera qu'aggraver le problème, car l'erreur est là, mais le programme essaiera de continuer et risque de planter quelquefois après, et de corrompre tout ce qu'il touche entre-temps.

Vous pouvez toujours ajouter une gestion des exceptions à votre programme pour capturer ces types de défauts et les ignorer (bien que les détails soient spécifiques à la plate-forme) ... mais il s’agit bien d’une arme à deux tranchants. Pensez plutôt à ce que le programme récupère les exceptions et crée des fichiers de vidage pour analyse.

Si votre programme s'est comporté de manière inattendue, que savez-vous de votre état interne? Peut-être que la routine / thread qui s'est écrasé a corrompu une structure de données clé? Peut-être que si vous attrapez l'erreur et essayez de continuer, l'utilisateur sauvegardera tout ce sur quoi il travaille et commettra la corruption sur le disque?

En plus d'écrire du code plus stable, voici une idée qui répond à votre question.

Si vous utilisez des processus ou des threads. Vous pouvez écrire un programme de surveillance petit / simple. Ensuite, vos autres programmes s'inscrivent auprès de ce chien de garde Si un processus meurt ou un thread meurt, il peut être redémarré par le chien de garde. Bien sûr, vous voudrez peut-être faire un test pour vous assurer de ne pas continuer à redémarrer le même fil de discussion. c'est-à-dire: redémarrez-le 5 fois, puis après le 5, arrêtez l'ensemble du programme et connectez-vous dans le fichier / syslog.

Construisez votre application avec les symboles de débogage, puis ajoutez un gestionnaire d'exceptions ou configurez Dr Watson pour qu'il génère des vidages sur incident (exécutez drwtsn32.exe / i pour l'installer en tant que débogueur, sans que / i ouvre la boîte de dialogue de configuration). Lorsque votre application se bloque, vous pouvez vérifier si elle a mal tourné dans Windbg ou dans Visual Studio en consultant un répertoire d'appels et des variables.

google pour le serveur de symboles pour plus d'informations.

Évidemment, vous pouvez utiliser la gestion des exceptions pour la rendre plus robuste et utiliser des pointeurs intelligents, mais il est préférable de corriger les bugs.

Je vous conseillerais de compiler une version Linux et de l'exécuter sous Valgrind .

Valgrind suivra les fuites de mémoire, les lectures de mémoire non initialisées et de nombreux autres problèmes de code. Je le recommande vivement.

Après plus de 15 ans de développement Windows, j'ai récemment écrit ma première application C ++ multiplate-forme (Windows / Linux). Voici comment:

  • STL
  • Boost. En particulier les bibliothèques de systèmes de fichiers et de threads.
  • Une interface utilisateur basée sur un navigateur. L'application "fait" HTTP, avec l'interface utilisateur composée de XHTML / CSS / JavaScript (style Ajax). Ces ressources sont incorporées dans le code du serveur et servies au navigateur si nécessaire.
  • Tests unitaires copieux. Pas tout à fait TDD, mais proche. Cela a réellement changé ma façon de me développer.

J’ai utilisé NetBeans C ++ pour la construction Linux et j’ai eu un port Linux complet en un rien de temps.

Construisez-le avec l’idée que le seul moyen de quitter le programme est de faire planter le programme et qu’il peut se bloquer à tout moment. Lorsque vous le construisez de cette façon, le crash ne perdra jamais / presque jamais de données. J'ai lu un article à ce sujet il y a un an ou deux. Malheureusement, je n'ai pas de lien vers cela.

Associez-le à une sorte de vidage sur incident et envoyez-le par e-mail afin que vous puissiez résoudre le problème.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top