08/11/2025 - Kiss ha scritto:
....................
Quali strategie di debug avanzato adottate quando un errore non è immediatamente riproducibile?
Quali strumenti o tecniche specifiche del linguaggio hanno funzionato meglio nella vostra esperienza reale?
Avete mai incontrato bug così particolari da dover ripensare l’architettura o le dipendenze di una libreria/framework?
Ti posso parlare di Delphi (linguaggio che uso maggiormente) in ambiente Windows 64 bit (e APP a 64 bit), dove devo interfacciarmi con vari hardware (direttamente con RING0 e con IOCTL), con svariate librerie e con i miei stessi moduli creati negli anni.
Usare debugger integrati (Delphi ha secondo me un ottimo debugger) o debugger esterni (tipo x64dbg) non mi ha aiutato nei casi peggiori.
Gestire e verificare bug di logica (tipo deve accader a,b,c invece accade b,a,c) sono complessi se legati ad eventi asincroni e il debugger per sua natura non ti può aiutare (mia esperienza personale ...)
In Delphi fortunatamente i LEAK sono semplicissimi (bhè diciamo abbastanza semplici) da trovare e questo non è mai stato un problema, anche senza usare alcun debugger.
Per tutti i bug che non si riescono a scovare facilmente io uso un metodo vecchio come il mondo: traccio su file o direttamente su console (ossia il terminale di Windows) gli eventi notevoli che mi interessano fino a raggiungere il nocciolo del problema.
Quando traccio: sono passato di qua in questo microsecondo, gli stati sono 1, 2, 6; sono passato di la in questo microsecondo, gli stati sono 3, 2, 7; etc ... riesco sempre a risolvere il problema. Ora in pratica non uso quasi mai il debugger (lo uso solo quando mi sento pigro e mi scoccia scrivere "writeln (......)").
Tieni presente che giusto per farti un esempio pratico io sviluppo applicazioni che usano direttamente in hardware (cioè sul PC) encoder di linea, telecamere (sino a 16 contemporaneamente in linea), comunicano con PLC (massimo jitter 2 millisecondi), dispositivi di illuminazione, librerie di visione artificiale, etc ...
Un ciclo di programma (diciamo una elaborazione completa di tutte quelle informazioni) viene completato in meno 90 millisecondi a cicli di 140 millisecondi e un singolo ciclo compre acquisizione immagini (5 Mpx x 6 camere (normalmente) x 2 immagini a camera) e comando singolarizzato di ogni dispositivo di illuminazione durante ogni foto (fino a 72 dispositivi contemporaneamente), elaborazione, produzione risultati ed invio a PLC. Il tutto seguendo l'encoder.
Ovviamente dentro l'applicazione c'è tutta la logica che espressa così in due parole sembra semplice).
Capisci bene che: l'encoder che perde passi per colpa della meccanica, una foto che non arriva per colpa dei disturbi di trasmissione (o peggio che mai arriva in ritardo), il PLC che non risponde all'invio dei dati, la temperatura dei core del processore che fà cadere le prestazioni, un bug nella nuova versione della libreria che a caso ti dà risultati errati, il cliente pazzo che fà andare il tutto al doppio della velocità massima consentita così fà più produzione, etc , etc, etc .... di bug ne possono accadere e di ogni.
Ora, ci sono voluti anni, non ho più alcun problema in quanto ciò che è stato acquisito lo applico a priori a tutte le applicazioni (anche quando magari non è necessario).
Di rado, ma veramente di rado tipo 1 o due volte l'anno, mi capita di usare appunto il "writeln" per scrivere sul terminale i dati necessari per l'analisi ... e quasi sempre l'errore è della mia valutazione: tipo corro a 120 in autostrada e invece in realtà vado al massimo a 100 perchè ci sono i tir, i lavori in corso, quelli che vanno a 70 all'ora in sorpasso, ....
P.S.: dimenticavo, ci sono anche i problemi legati alla profilazione, ossia ai colli di bottiglia che si possono formare in parti (o meglio momenti) del software per svariati motivi ... quelli io li analizzo monitorando i tempi specifici con i "TStopWatch" cioè i timer ad alta risoluzione da 100 nanosecondi (dall'API QueryPerformanceCounter).
Non ho usato addon di profilazione (anche se sò che sono utili in diverse situazioni) perchè non ne ho mai avuto necessità.