Domanda

Stiamo producendo un codice portabile (win+macOs) e stiamo cercando come renderlo più robusto dato che ogni tanto si blocca...(overflow o inizializzazioni errate di solito) :-(

Stavo leggendo che Google Chrome utilizza un processo per ogni scheda, quindi se qualcosa va storto il programma non si blocca completamente, ma solo quella scheda.Penso che sia abbastanza carino, quindi potrei provarlo!

Quindi mi chiedevo se qualcuno avesse qualche suggerimento, aiuto, elenco di lettura, commento o qualcosa che possa aiutarmi a creare codice C++ più robusto (portatile è sempre meglio).

Nello stesso argomento mi chiedevo anche se esiste una libreria portatile per i processi (come boost)?

Bene, molte grazie.

È stato utile?

Soluzione

Ho sviluppato su numerose app C++ multipiattaforma (la più grande è 1,5 milioni di righe di codice ed è in esecuzione su 7 piattaforme: AIX, HP-UX PA-RISC, HP-UX Itanium, Solaris, Linux, Windows, OS X) .In realtà hai due problemi completamente diversi nel tuo post.

  1. Instabilità.Il tuo codice non è stabile.Aggiustalo.

    • Usa i test unitari per trovare problemi logici prima che ti uccidano.
    • Utilizza i debugger per scoprire cosa causa gli arresti anomali se non è ovvio.
    • Utilizza boost e librerie simili.In particolare, i tipi di puntatore ti aiuteranno a evitare perdite di memoria.
  2. Codifica multipiattaforma.

    • Ancora una volta, quando possibile, utilizzare le librerie progettate per questo scopo.In particolare per eventuali bit della GUI.
    • Utilizzare standard (ad es.ANSI vs gcc/MSVC, thread POSIX vs modelli di thread specifici di Unix, ecc.) il più possibile, anche se richiede un po' più di lavoro.Ridurre al minimo il codice specifico della piattaforma significa meno lavoro complessivo e meno API da apprendere.
    • Isolare, isolare, isolare.Evita il più possibile #ifdef in linea per piattaforme diverse.Inserisci invece il codice specifico della piattaforma nella propria intestazione/sorgente/classe e utilizza il tuo sistema di compilazione e #include per ottenere il codice giusto.Ciò aiuta a mantenere il codice pulito e leggibile.
    • Se possibile, usa i tipi interi C99 invece di "long", "int", "short", ecc. - altrimenti ti morderà quando passi da una piattaforma a 32 bit a una a 64 bit e i long cambiano improvvisamente da 4 byte a 8 byte.E se questo viene mai scritto sulla rete/disco/ecc, ti imbatterai in incompatibilità tra le piattaforme.

Personalmente, prima stabilizzerei il codice (senza aggiungere altre funzionalità) e poi affronterei i problemi multipiattaforma, ma dipende da te.Tieni presente che Visual Studio dispone di un eccellente debugger (il codice base menzionato sopra è stato portato su Windows proprio per questo motivo).

Altri suggerimenti

La risposta di Chrome riguarda più la mitigazione degli errori e non la qualità del codice.Fare quello che sta facendo Chrome è ammettere la sconfitta.

  1. Un migliore QA che va oltre il semplice test del programmatore sul proprio lavoro.
  2. Test unitari
  3. Test di regressione
  4. Leggi le migliori pratiche utilizzate da altre aziende.

Per essere sinceri, se il tuo software si blocca spesso a causa di overflow e inizializzazioni errate, allora hai un problema di qualità di programmazione molto semplice che non sarà facilmente risolto.Sembra banale e meschino, non è mia intenzione.Il punto è che il problema con il codice errato deve essere la tua preoccupazione principale (e sono sicuro che lo sia).Cose come Chrome o l'uso liberale della gestione delle eccezioni per individuare i difetti del programma non fanno altro che distrarti dal vero problema.

Non menzioni quale sia il progetto target;avere un processo per scheda non significa necessariamente un codice più "robusto".Dovresti mirare a scrivere codice solido con test indipendentemente dalla portabilità: leggi solo come scrivere un buon codice C++ :)

Per quanto riguarda la sezione sulla portabilità, assicurati di eseguire i test su entrambe le piattaforme fin dal primo giorno e assicurati che non venga scritto nuovo codice finché i problemi specifici della piattaforma non vengono risolti.

Davvero, davvero non vuoi fare quello che sta facendo Chrome, richiede un gestore di processi che probabilmente è MOLTO eccessivo per quello che desideri.

Dovresti esaminare l'utilizzo dei puntatori intelligenti di Boost o di un altro strumento che fornirà il conteggio dei riferimenti o la raccolta dei rifiuti per C++.

In alternativa, se si verificano frequenti arresti anomali, potresti prendere in considerazione la possibilità di scrivere parti critiche non prestazionali della tua applicazione in un linguaggio di scripting con collegamenti C++.

Scott Meyers' C++ efficace E C++ più efficace sono molto belli e divertenti da leggere.

Quello di Steve McConnell Codice completato è uno dei preferiti di molti, incluso Jeff Atwood.

Le librerie Boost sono probabilmente una scelta eccellente.Un progetto in cui lavoro li utilizza.Ho usato solo il threading WIN32 da solo.

Sono d'accordo con Torlack.

Una cattiva inizializzazione o overflow sono segni di codice di scarsa qualità.

Google ha fatto così perché a volte non c'era modo di controllare il codice eseguito in una pagina (a causa di plugin difettosi, ecc.).Quindi, se utilizzi plug-in di bassa qualità (succede), forse la soluzione Google farà al caso tuo.

Ma un programma senza plugin che si blocca spesso è semplicemente scritto male, o molto, molto complesso, o molto vecchio (e manca molto tempo di manutenzione).Devi fermare lo sviluppo e indagare su ogni singolo incidente.Su Windows, compila i moduli con PDB (database di programmi) e ogni volta che si blocca, collegagli un debugger.

È necessario aggiungere anche test interni.Evita lo schema:

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

   // do the processing.
}

Questo è un pessimo design perché l'errore c'è e tu semplicemente lo eviti, questa volta.Ma la funzione successiva senza questa protezione andrà in crash.Meglio schiantarsi prima per essere più vicini all'errore.

Su Windows invece (deve esserci un'API simile su MacOS)

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

   // do the processing.
}

(non utilizzare questo codice direttamente...Mettilo in una definizione per evitare di consegnarlo a un cliente ...) Puoi scegliere l'API di errore che si adatta a te (eccezioni, debutto, asserzione, ecc.), Ma usarlo per fermare il momento in cui il codice sa che qualcosa non va.

Evita l'API C quando possibile.Utilizzare idiomi C++ (RAII, ecc.) e librerie.

Eccetera..

PS:Se usi le eccezioni (che è una buona scelta), non nasconderle all'interno di un catch.Non farai altro che peggiorare il tuo problema perché l'errore è lì, ma il programma proverà a continuare e probabilmente a volte si bloccherà e nel frattempo corromperà tutto ciò che tocca.

Puoi sempre aggiungere la gestione delle eccezioni al tuo programma per rilevare questo tipo di errori e ignorarli (sebbene i dettagli siano specifici della piattaforma) ...ma questa è davvero un’arma a doppio taglio.Considera invece che il programma rilevi le eccezioni e crei file di dump per l'analisi.

Se il tuo programma si è comportato in modo inaspettato, cosa sai del tuo stato interno?Forse la routine/thread che si è bloccato ha danneggiato alcune strutture di dati chiave?Forse se rilevi l'errore e provi a continuare, l'utente salverà tutto ciò su cui sta lavorando e commetterà il danneggiamento sul disco?

Oltre a scrivere un codice più stabile, ecco un'idea che risponde alla tua domanda.

Sia che tu stia utilizzando processi o thread.Puoi scrivere un piccolo/semplice programma watchdog.Quindi gli altri tuoi programmi si registrano con quel watchdog.Se un processo o un thread muore, può essere riavviato dal watchdog.Ovviamente vorrai fare qualche test per assicurarti di non continuare a riavviare lo stesso thread difettoso.cioè:riavvialo 5 volte, quindi dopo la quinta, spegni l'intero programma e accedi al file / syslog.

Crea la tua app con simboli di debug, quindi aggiungi un gestore di eccezioni o configura Dr Watson per generare dump di arresti anomali (esegui drwtsn32.exe /i per installarlo come debugger, senza /i per visualizzare la finestra di dialogo di configurazione).Quando la tua app si arresta in modo anomalo, puoi verificare dove è andato storto in Windbg o Visual Studio visualizzando uno stack di chiamate e le variabili.

Google per il server dei simboli per maggiori informazioni.

Ovviamente puoi usare la gestione delle eccezioni per renderlo più robusto e usare puntatori intelligenti, ma correggere i bug è la cosa migliore.

Ti consiglio di compilare una versione Linux ed eseguirla Valgrind.

Valgrind terrà traccia delle perdite di memoria, delle letture di memoria non inizializzate e di molti altri problemi di codice.Lo consiglio vivamente

Dopo oltre 15 anni di sviluppo Windows, di recente ho scritto la mia prima app C++ multipiattaforma (Windows/Linux).Ecco come:

  • STL
  • Aumento.In particolare il filesystem e le librerie di thread.
  • Un'interfaccia utente basata su browser.L'app "fa" HTTP, con l'interfaccia utente composta da XHTML/CSS/JavaScript (stile Ajax).Queste risorse sono incorporate nel codice del server e fornite al browser quando richiesto.
  • Numerosi test unitari.Non proprio TDD, ma vicino.Questo in realtà ha cambiato il modo in cui mi sviluppo.

Ho usato NetBeans C++ per la build Linux e ho ottenuto un port Linux completo in pochissimo tempo.

Costruiscilo con l'idea che l'unico modo per uscire è che il programma si blocchi e che possa bloccarsi in qualsiasi momento.Quando lo costruisci in questo modo, l'arresto anomalo non perderà mai/quasi mai alcun dato.Ho letto un articolo a riguardo un anno o due fa.Purtroppo non ho un link ad esso.

Combinalo con una sorta di crash dump e ricevilo via email in modo da poter risolvere il problema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top