Metodi di debug del codice (situazione da incubo)


16

Sono spesso incaricato di eseguire il debug di un'applicazione nel mio lavoro. È un'applicazione BI che implementiamo nelle aziende, che include un ambiente di test e un ambiente di produzione. Mi chiedo se ci sono app / strumenti / metodi che le persone possono suggerire, sulla base di questi vincoli:

  1. Il debugger non può essere utilizzato sul sito client o localmente, poiché il software dipende da applicazioni di terze parti personalizzate per le quali non abbiamo ambienti di test. (EDIT: per essere onesti, in alcuni casi è possibile eseguire il debug a livello locale. Se non utilizziamo altro che il codice principale. Gran parte del codice problematico risiede in una dll che incapsula comunicazioni specifiche di terze parti: socket, pipe di processo, chiamate soap, logica personalizzata che modifica il comportamento del codice principale. In genere durante un'implementazione o un miglioramento per un client, scriveremmo un nuovo codice in quest'area.)

  2. Non esiste praticamente alcuna registrazione nelle nostre app. Non ci sono test unitari.

  3. Il controllo versione ha solo 1 versione della soluzione completa (utilizzando source safe 2005). Quindi non è possibile ottenere una versione precedente dell'intera soluzione, solo singoli file. (A meno che qualcuno non sappia come aggirare questo).

  4. Non è possibile riprodurre localmente, spesso i tempi non possono essere riprodotti nell'ambiente di test (è molto probabile che test e produzione non siano la stessa versione).

  5. Esiste un'alta probabilità che la versione utilizzata dal client sia diversa da quella su sorgente sicura. Questo perché i singoli file vengono aggiornati, che hanno una logica personalizzata incorporata per quel client specifico. Spesso ciò che accade è un aggiornamento a un binario, che richiede modifiche a molti altri binari, ma quando viene eseguito un commit, nessuno ha alcuna documentazione o conoscenza di questo. Un errore piuttosto comune che vedo è la funzione / metodo non trovato o la chiamata del metodo ha troppi / troppi parametri specificati in un ambiente client.

  6. Questa è una soluzione .net VB

  7. Impossibile installare alcun software sui siti client, ma è possibile localmente

  8. La nostra applicazione è estremamente personalizzabile, ma purtroppo la logica di personalizzazione è distribuita su tutte le classi e file, dal front-end fino al livello dati, comprese le modifiche personalizzate apportate al database in base al client.

  9. Non ci sono praticamente commenti nel codice. Non c'è documentazione sull'architettura. Nessuna documentazione sull'API. L'unica cosa che abbiamo sono centinaia e centinaia di catene di e-mail che spiegano in qualche modo cosa sta succedendo. Le uniche persone che conoscono il codice sono quelle che lo hanno originariamente scritto, ma non sono più sviluppatori per dire, quindi non vengono coinvolti così tanto.

E prima di dirlo ... sì, lo so; Voglio sparare anche a me stesso. Non aiuta che ci sia il codice spaghetti, centinaia di avvisi del compilatore e polimorfismo rotto che DAVVERO dovrebbe essere riparato, ma non ho voce in capitolo.

Il tipo più comune di errori in cui mi imbatto sono errori di riferimento null, cast non validi e mancate corrispondenze della firma di funzioni / funzioni mancanti. A volte sono fortunato e il visualizzatore di eventi registra la classe, il metodo e il messaggio di eccezione. Non è il più utile, ma è ancora qualcosa. I peggiori sono gli errori che non hanno traccia, nessuna procedura di riproduzione oltre a uno screenshot e sono messaggi di errore generici come quelli sopra menzionati. A volte non è possibile scoprire perché si sono verificati, solo per pregare che l'ambiente non sia configurato correttamente e che sparirà più tardi.

So che questo viene fuori come un po 'di rabbia, e in una certa misura lo è. Ma sono alla disperata ricerca di opzioni. Ci sono altri metodi / strumenti che posso usare?


43
Hai un curriculum?
Robert Harvey,

5
+1 per "Voglio sparare anche a me stesso". Source Safe 2005, ahi. Beh, almeno dovresti "concentrarti" sulla meravigliosa lezione di storia - sei fondamentalmente un viaggiatore nel tempo! Imparerai le lezioni di un decennio di conoscenza attentamente sviluppata di "quindi è per questo che non lo facciamo più". Godspeed, cavalletta.
BrianH,

7
Dato il requisito n. 1, l'unico modo per essere efficaci nel debug di questo pasticcio è essere chiaroveggenti. Scherzi a parte, non esiste un proiettile magico che non farà altro che un tiro al piattello. In un certo senso questo dovrebbe toglierti una certa pressione, dal momento che il debug è necessariamente una questione di fortuna. O il tuo management ti ordinerà di essere fortunato? Chiaramente questo non è sostenibile, quindi dovresti cercare altre opportunità.
Charles E. Grant,

14
Ecco alcuni consigli di carriera reali: trascorri troppo tempo in una casa che ha orribili pratiche di ingegneria del software e probabilmente verrai incolpato dalla direzione per essere un cattivo sviluppatore per i problemi che inevitabilmente ne conseguono. Ci sono stato e sono sicuro che anche altri lo sono. Nel migliore dei casi, porta a cattive abitudini di sviluppo.
Gort il robot il

2
come gestisco queste situazioni: se non vengo pagato molto al di sopra del mercato, vado a cercare qualcos'altro da fare.
Kevin Cline il

Risposte:


22

Il consiglio di Robert Harvey è probabilmente il migliore, ma poiché i consigli di carriera sono fuori tema, darò quale risposta può essere data:

Sei in fondo a una montagna molto ripida coperta di rovi, fango e irritabili capre di montagna. Non c'è modo semplice. Se vuoi arrivare in cima, devi forzare la tua scalata di un passo tremendamente doloroso alla volta.

Sembra che tu sappia esattamente come dovrebbero funzionare le cose . Se nessun altro ti aiuterà, di nuovo (ignorando i consigli di carriera), l'unica scelta è iniziare a sistemare queste cose da solo.

In primo luogo, nonostante tutto ciò che è santo, procurati quel materiale in un sistema di controllo della versione reale . Praticamente qualsiasi cosa tranne Source Safe, che è ben noto come un mucchio puzzolente di immondizia. gitè gratuito e può essere impostato abbastanza facilmente. Non è possibile risolvere i problemi della mancanza di controllo della versione in passato, ma almeno impedire che il problema continui nel futuro.

Quindi, guarda nella registrazione. Trova, o nel caso peggiore, scrivi un sistema di registrazione e inizia a usarlo. Utilizzare uno che può essere utilizzato anche sui siti client, quindi quando le cose vanno lateralmente hai almeno qualcosa.

E inizia a scrivere test, almeno per le nuove modifiche apportate.

Non c'è zucchero che lo ricopre: qui non c'è risposta che non implichi molto lavoro o che consideri questo come una questione di carriera.


Credetemi, non vorrei altro che aggiungere asserzioni, guardie e registrazione, probabilmente riscrivere anche il livello dati (sto scrivendo un validatore di configurazione per diagnosticare problemi tipici di configurazione). Sfortunatamente non dipende da me. Posso fare una richiesta per mettere qualcosa al sicuro, ma la risposta tipica è "le tue intenzioni sono buone, ma questo non è qualcosa su cui dovremmo concentrarci". Purtroppo, sono solo un junior con 1/2 anni di esperienza. Scalerò questa montagna per un po '.
Igneous01

9
@ Igneous01 Onestamente, prova a trovare una montagna diversa da scalare. Le condizioni di lavoro in altri luoghi potrebbero non essere perfette, ma immagino che almeno la maggior parte siano significativamente migliori di quelle che stai vivendo. Se i tuoi gatekeeper rifiutano i tuoi miglioramenti con "questo non è qualcosa su cui dovremmo concentrarci", è la loro decisione da prendere e raccoglieranno i risultati di quella politica fallita (stanno già perdendo tonnellate di denaro in termini di tempo di sviluppo perso) . La domanda è: vuoi restare con loro fino a quando non lo fanno?
cmaster - ripristina monica il

6
E tieni presente che quando le cattive politiche falliscono, tutti i soggetti coinvolti sembrano cattivi, anche quelli che non sono d'accordo.
Gort the Robot

1
Sì, avvia la registrazione e la traccia. Inizia anche a documentare e ad aggiungere commenti. A poco a poco, tutto si sommerà. Inoltre, dici che sei abbastanza fortunato da avere ancora alcuni dei programmatori originali in azienda, se non la squadra. Spingi la direzione a ottenere loro se possibile, convincili che preferirebbero produrre alcuni documenti piuttosto che affrontarli costantemente con domande.
Mawg dice di reintegrare Monica il

4
@ Igneous01: corri, non camminare. Questo posto è malato e ti farà star male.
Ripristina Monica - M. Schröder il

8

1) Il debugger non può essere utilizzato sul sito client ...

È perfettamente normale.

... o localmente

Questo è un problema.

2) Non c'è praticamente nessuna registrazione effettuata nelle nostre app.

La registrazione è il debug della produzione.

Non ci sono test unitari.

Oh caro. Tutto in comune, però.

3) Il controllo versione ha solo 1 versione della soluzione completa

Quindi non stai usando il controllo versione.

4) Impossibile riprodurre localmente, spesso i tempi non possono essere riprodotti nell'ambiente di test (alta probabilità che test e produzione non siano la stessa versione).

Pertanto, solo l'ambiente client distribuito mostra gli errori.

In tal caso, è necessario il logging disgnostico incorporato nel codice dell'applicazione che (a) intercetta e [completamente] registra errori [fatali] e (b) può essere "chiamato" su richiesta per produrre ulteriori, continui, diagnostici utili in rintracciare i problemi.

5) Esiste un'alta probabilità che la versione utilizzata dal client sia diversa da quella su sorgente sicura.

Ancora una volta, non stai semplicemente usando il controllo della versione a tuo vantaggio.

8) La nostra applicazione è estremamente personalizzabile

È abbastanza tipico.

Le differenze specifiche del sito devono essere gestite tramite il controllo versione "Branching".

9) Non ci sono praticamente commenti nel codice.

Ancora una volta, è fin troppo comune, perché gli sviluppatori scrivono codice "auto-documentante", vero?
O, almeno, il codice che comprendono il giorno in cui lo scrivono.

Non c'è documentazione sull'architettura.

Oh caro.

Nessuna documentazione sull'API.

Oh caro, oh caro.

E prima di dirlo ... sì, lo so; Voglio sparare anche a me stesso.

No; vuoi sparare alle persone che hanno scritto tutta questa roba, creato un pasticcio non documentato e non sostenibile e poi sono passati a pascoli nuovi, lasciando dietro di sé il caos incontrollabile.

Il tipo più comune di errori in cui mi imbatto sono errori di riferimento null, cast non validi e mancate corrispondenze della firma di funzioni / funzioni mancanti.

I riferimenti null e i cast non validi sono errori di runtime; in una certa misura, dovresti aspettarteli e il fatto che li stai ricevendo spesso suggerisce una mancanza di programmazione difensiva (o un surplus di ottimismo) da parte degli autori originali.

La mancata corrispondenza della firma della funzione dovrebbe causare una generazione non funzionante ; quelli dovrebbero causare "build rotte" e non dovrebbero mai uscire dalla porta!


2
"
Codifica

Gli errori di runtime sono causati più da una mancanza di comprensione che da una mancanza di programmazione difensiva. La programmazione difensiva è solo un modo per nascondere il fatto che il codice non funziona.
user253751

1
"Nessuna documentazione sull'architettura" di solito significa "nessuna architettura" ...
gnasher729,

The site-specific differences should be managed through Version Control "Branching".- Non credo sia il modo migliore di procedere. L'uso dei file di configurazione e degli interruttori di funzionalità sembra essere più comune e più facile da ragionare.
sixtyfootersdude,

5

Inizia con la registrazione. Questo avrà il massimo impatto. Implementare un framework di registrazione nella base di codice, come Log4Net o simile. Inizia a registrare cosa fa il codice.

Il debug dovrebbe essere possibile localmente. In caso contrario, lavorare su come ottenere i file di simboli (PDB) in modo da poter eseguire il debug in DLL di terze parti per ottenere un quadro completo dei problemi che si verificano. Strumenti come WINDBG possono indicare quali DLL sono problematiche in caso di arresto anomalo del sistema. È possibile configurare qualsiasi server per eseguire un dump della memoria in caso di arresto anomalo. È fondamentalmente un'istantanea di ciò che stava accadendo quando si è verificato il problema. Si possono esaminare le discariche localmente per trovare indizi su ciò che stava accadendo. Se il debug non è possibile, lavorare per renderlo possibile. Documentare i passaggi necessari per il debug. A volte su sistemi complessi, è necessario un sacco di installazione per eseguire il debug completo.

Bug tracking ... Se non ne usi uno, inizia a usarne uno. Questo va di pari passo con un adeguato sistema di controllo della versione. Fondamentalmente, inizia a monitorare i difetti e le revisioni del tuo codice. Inizia a creare una cronologia del sistema.

Eseguire l'analisi del codice statico. Investi in uno strumento come ReSharper. Indicherà rapidamente tutte le possibili eccezioni di riferimento null e altre pratiche di codifica errate. Può aiutare a ottenere il codice in una forma migliore con pochi clic e automatizzare elementi noiosi come la formattazione del codice, la denominazione delle variabili, ecc. Misura il tuo codice, scopri dove sono i punti caldi per il refactoring tramite metriche del codice.

Rifattore e test unitari. Suppongo che probabilmente la maggior parte del codice scritto non è molto testabile, quindi non mi preoccuperei di provare ad aggiungere test per questo. Qualsiasi nuovo codice, crea un progetto di test e inizia a scrivere test, sia unità che integrazione. Se i test unitari falliscono, fallire la compilazione. Quindi, mentre fai il refactor, dovrebbero esserci dei test. Una cosa con i test è che si può scrivere un test per chiamare qualsiasi metodo ed eseguire il debug in quel metodo senza caricare l'intera applicazione o base di codice. Questo è utile per aiutare a risolvere i problemi.

Documentare ogni conoscenza tribale secondo necessità. Il codice dovrebbe essere auto-documentato, quindi i commenti devono essere scarsi, ma molti sistemi hanno modi "insoliti" di fare le cose, segnalali in un codice WIKI o altro tipo di archivio informale. Inoltre, considera di elaborare standard e pratiche di codifica. Applicare tali standard tramite un set di strumenti come Resharper. Poiché la maggior parte del codice probabilmente non segue standard e linee guida, implementare gli standard sul nuovo codice scritto.

Dal tuo nuovo, lo tratterei come un giro di servizio. Da 6 mesi a 2 anni, quindi fai la scelta di rimanere o andare avanti. Soddisfatti di rendere le cose leggermente migliori rispetto al giorno prima.


4

Innanzitutto, tutto quanto sopra ... idem.

Alcune euristiche:

  • Usa il controllo del codice sorgente sul tuo computer di sviluppo. È la cosa migliore che abbia fatto. Non è un sostituto per il controllo della versione del progetto, che abbiamo. È uno strumento che offre un'incredibile libertà di sperimentare, hackerare, risolvere problemi senza problemi contemporaneamente ma indipendentemente, ecc. Sono più bravo a usare il controllo della versione perché ho la libertà di essere audace, rovinare e imparare.
  • Nella misura in cui aggiungi commenti, dai la priorità agli elementi dell'interfaccia pubblica, per sfruttare l'intellisense. Fallo mentre decifri durante le tue avventure di debug.
  • Sii persistente con rifatturazioni minori. Prima o poi, per un dato pezzo di codice, arriverai a una massa critica che consente grandi rifatturazioni come ASCIUGARE il codice ridondante tra le classi.
  • Non mescolare la riformattazione del codice e le modifiche effettive nella stessa versione eseguono il commit dei controlli.
  • Principi solidi
    • Non ignorare mai la singola responsabilità. Ben fatto, questo è il percorso verso la promessa di oggetti orientati; A PARER MIO.
    • Ignora sempre Apri / Chiuso.
    • Non stiamo parlando di nuovo codice qui.
    • La creazione di interfacce senza una progettazione mirata ostacola la manutenzione.
  • refactoring
  • Alcuni file di codice richiedono una riformattazione completa, una ridenominazione variabile, ecc. Prima ancora di tentare il debug. Non essere timido nell'usare il menu refactor di Visual Studio senza unit test.
  • L'unica documentazione che non può essere fuori luogo è nei file di codice.
  • Quando si ottiene il controllo della versione, prevedere il piano VC. E documentalo! E inventare una convenzione di denominazione per filiali, tag che metterà in evidenza le principali versioni del software e le pietre miliari.
  • Usa una buona attrezzatura
  • Fai pratica con il debugging Rubber Ducky
  • A volte la cosa peggiore che può succedere è che non ti licenzino.

modificare

Sviluppo di applicazioni Brownfield in .NET

Prova questo libro. Una copertina iniziale da leggere è probabilmente la migliore. Questo libro ti aiuterà a pensare al quadro generale, alle possibilità e allo sviluppo di piani di attacco strategici e tattici.

Sporge

Rimani, diciamo, 1,5 anni se puoi; abbastanza a lungo per sapere se stai facendo progressi esperienziali. Saprai se stai acquisendo 2 anni di esperienza o 6 mesi di esperienza 4 volte.

Essendo "junior con 1/2 anni di esperienza", sono preoccupato che un potenziale datore di lavoro lo vedrà come un salvataggio anticipato perché non si può hackerarlo. Una cosa è dire che hai imparato z, y, x, hai preso dei nomi e preso a calci in culo - ma non ti è stato permesso di contribuire alle tue capacità; e un altro semplicemente rischiando di dissuadere il lavoro, il codice, la gestione, ecc. a titolo di spiegazione.

Potrei essere fuori base su questo, ma il mio "miglior tempo e il peggiore dei tempi" è stato il mio primo lavoro, che è risultato essere un codice letteralmente non mantenibile. Avevo un grande supervisore (tutto il resto proveniva dal programma di gestione in-breeding) che mi ha dato lo spazio per riscrivere alcuni programmi chiave. Quell'esperienza è stata rivelazione.

fine Modifica


+1 per Non mescolare la riformattazione del codice e le modifiche effettive nella stessa versione, il controllo impegna - ottimo consiglio
kiwiron

0

Direi che (5) è quello che devi risolvere per primo. Se non sai quale codice è in esecuzione in produzione, non hai modo sicuro di riprodurre e risolvere i problemi. Ciò rende pericolose qualsiasi altra modifica introdotta, poiché potrebbe causare problemi che non è possibile prevedere e che non è possibile riprodurre.

Potrebbe essere necessario eseguire alcuni lavori investigativi e forse il reverse engineering per capire quale versione o versioni di codice e quali librerie sono distribuite. (E hai bisogno di un sistema di compilazione e distribuzione coerente per portare tutto il codice distribuito in linea con il controllo del codice sorgente in futuro.)

Potrebbe essere necessario creare più ambienti di test per replicare le varie distribuzioni. (Naturalmente la soluzione più semplice è quella di creare una nuova build pulita e distribuirla costantemente ovunque, ma sembra che questo non sia possibile?)

Solo quando si conoscono le versioni esatte distribuite e si hanno ambienti di test corrispondenti, si dovrebbe iniziare a provare a correggere / migliorare il codice.

La tua prossima priorità dovrebbe essere quella di consolidare in un'unica base di codice che può essere distribuita ovunque. Sembra che tu abbia distribuito varie versioni di codice a causa della personalizzazione? È necessario consolidare in un'unica versione e quindi utilizzare gli switch di configurazione per la logica personalizzata.

Successivamente, è possibile iniziare a migliorare attentamente la base di codice per consentire un debug più semplice. L'aggiunta della registrazione è probabilmente il miglioramento meno rischioso.

Ti consigliamo di aggiungere test automatici, ma gli unittest sono spesso difficili da aggiungere a un progetto che inizialmente non è progettato per il test. Consiglio invece di iniziare con test di integrazione automatizzati end-to-end. Questi sono più difficili da configurare, ma non richiedono di riprogettare la soluzione, quindi sono meno rischiosi.


0

Ignorando i problemi che hai nel tuo team, sembra che il primo ad affrontare sia il debug del codice corrispondente a ciò che è in produzione. Altrimenti potresti inseguire un bug che era già stato corretto nel codice che hai nel tuo "Controllo del codice sorgente". Dato che questo è .NET, puoi facilmente "decompilare" i file binari di produzione per confrontare il codice con quello che hai. Non è un compito facile, ma se ci riesci è un argomento forte per un migliore strumento di controllo del codice sorgente in grado di taggare le versioni rilasciate.


Quando intendi decompilare, intendi usare qualcosa come IDA Pro per visualizzare il codice macchina? Probabilmente sarei l'unico ad usarlo perché nessuno qui conosce il montaggio (e conosco le basi).
Igneous01,

Bene, poiché si tratta di .NET, i binari non sono codice macchina, ma sono in CIL ( en.wikipedia.org/wiki/Common_Intermediate_Language ). Questo può essere abbastanza facilmente e accuratamente riconvertito in codice c # o VB, specialmente se non è stato offuscato. Puoi provarlo con ILSpy per esempio ( ilspy.net ) ma probabilmente ci sono altri strumenti che potresti usare.
20c
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.