Come individuare il codice sorgente che ha implementato una determinata funzione? [chiuso]


14

Mi chiedevo quali sono alcune tecniche per individuare quale codice ha implementato una funzionalità specifica, su un'applicazione desktop.

Sono uno sviluppatore junior, con solo esperienza di programmazione professionale sulla programmazione web. Nel Web è più facile farlo. Ad esempio, "ispezioni" un pulsante con gli strumenti del browser e puoi vedere cosa viene fatto quando fai clic su di esso. E quindi, supponendo che tu abbia il codice sorgente completo, puoi approfondire la gerarchia delle chiamate.

Ma come si fa nelle applicazioni desktop? Almeno, senza doversi tuffare nella base di codice completa?


6
Invece di leggere il codice, a volte è possibile utilizzare un debugger. Come funziona (e quanto è intuitivo per te) dipende dalla lingua, dal debugger e dall'interfaccia del debugger utilizzati. In ogni caso, l'uso di un debugger è un'arte da imparare, ma una volta appreso è uno strumento molto potente. Dovrei imparare a usarne uno da solo.
amon

E dove devo impostare i punti di interruzione?
py_script

La configurazione del breakpoint dipende interamente dalla tua applicazione e da come è organizzata.

2
In realtà può essere un po 'difficile "ispezionare" e vedere dove e come sono state realizzate le interfacce Web, con nuovi sistemi orientati agli oggetti come Backbone.js e modelli, che stanno diventando sempre più popolari.
NoBugs

1
@jeffo Quando fai, ad esempio, File-> Apri in un'applicazione (diciamo Writer di LibreOffice) come puoi trovare qual è la sequenza di chiamate dietro quella?
py_script

Risposte:


21

Traccia indietro

La traccia posteriore sta individuando un endpoint a un evento associato alla funzione (vedere di seguito). Una volta lì, un punto di interruzione viene inserito nel debugger. La funzione viene attivata e quando il debugger si arresta. Lo stack di chiamate viene rivisto per tracciare indietro il percorso di chiamata. Mentre si cammina sullo stack di chiamate, è possibile prendere appunti sugli stati variabili o posizionare nuovi punti di interruzione per ispezionare nuovamente l'evento.

La funzione viene nuovamente attivata e il debugger si interrompe nei nuovi punti di interruzione. È quindi possibile ripetere la traccia indietro o eseguire la traccia avanti fino al raggiungimento dell'obiettivo.

Pro e contro

  • È sempre più facile camminare nello stack di chiamate e vedere come sei arrivato da qualche parte.
  • Potrebbero esserci milioni di condizioni che devono essere vere prima di raggiungere un endpoint. Se conosci già l'endpoint, ti sei risparmiato un sacco di lavoro.
  • Se la funzionalità non è attiva. Potresti non raggiungere mai l'endpoint e il tempo può essere sprecato cercando di capire il perché.

Endpoint Discovery

Per eseguire il debug di una funzione devi sapere dove è stato raggiunto l'obiettivo finale nel codice sorgente. Solo da questo punto puoi tornare indietro per vedere come è arrivato il codice. Un esempio; Per capire come viene eseguito l'annullamento. Sai dove nel codice le cose sono annullate, ma non sai come le cose ci arrivano . Questo sarebbe un candidato per il backtracing per capire come funziona la funzione.

Traccia in avanti

La traccia in avanti sta individuando un punto iniziale per un evento associato a una funzione (vedi sotto). Una volta lì, i messaggi di registrazione vengono inseriti nel codice sorgente o vengono impostati i punti di interruzione. Questo processo si ripete man mano che avanzi più lontano da punto di partenza fino a quando non scopri l' obiettivo per la funzione.

Pro e contro

  • È il punto di partenza più semplice per trovare una funzione.
  • La complessità del codice riduce l'efficacia della traccia in avanti. Più condizioni ci sono nel codice maggiore è la possibilità che tu vada nella direzione sbagliata.
  • La traccia in avanti spesso determina l'impostazione di punti di interruzione che verranno attivati ​​da eventi non correlati. Interrompere il processo di debug e interferire con la ricerca.

Start Point Discovery

È possibile utilizzare parole chiave, identificatori dell'interfaccia utente (ID pulsante, nomi di finestre) o listener di eventi facili da trovare associati alla funzione. Ad esempio, potresti iniziare con il pulsante utilizzato per attivare un annullamento funzione di .

Processo Di Eliminazione

Puoi pensare a questo come al punto centrale rispetto alle posizioni del punto iniziale e finale . Esegui un processo di eliminazione quando sai già che viene utilizzato un pezzo di codice in una funzione, ma non è né l'inizio né la fine della funzione.

La direzione che prendi dal punto centrale dipende dal numero di voci ed uscite. Se il blocco di codice viene utilizzato in molti punti, la traccia indietro da questa posizione potrebbe richiedere molto tempo poiché devono essere ispezionati tutti. Quindi si utilizza un processo di eliminazione per ridurre questo elenco. In alternativa, è possibile eseguire una traccia in avanti da questo punto, ma anche in questo caso se il pezzo di codice si dirama in molti punti questo può anche essere un problema.

Devi ridurre le indicazioni di posizione non seguendo percorsi che chiaramente non verrebbero eseguiti per la funzione. Passando questo codice e posizionando i punti di interruzione solo dove è probabilmente correlato alla funzione.

Punto medio debug del richiede spesso funzionalità IDE più avanzate. La capacità di vedere la gerarchia del codice e le dipendenze. Senza quegli strumenti è difficile da fare.

Pro e contro

  • I punti medi sono spesso la prima porzione di codice che ti viene in mente quando pensi alla funzione. Ti dici "Ah, questo deve usare XXXX per funzionare".
  • I punti centrali possono rivelare i punti di partenza nel modo più semplice.
  • I punti medi possono essere un modo semplice per recuperare il percorso verso una funzione quando vengono persi a causa di modifiche di sincronizzazione o threading.
  • I punti di mezzo possono portarti a codice che non conosci. Ti costa tempo per imparare cosa sta succedendo.

Grazie Matteo, ottimo approccio. Ma come si trova un punto di partenza (scusate se è ovvio per tutti tranne me)?
py_script

@py_script Con quale linguaggio di programmazione hai problemi?
Reactgular

Non si tratta di un problema specifico che ho, ma il mio principale linguaggio di programmazione desktop è Java, quindi andiamo con esso
py_script

11

Supponendo che la funzione sia legata ad alcune cose dell'interfaccia utente, come un pulsante o un menu, ciò che tendo a fare segue (molto noioso ma funziona). Questo sta esaminando il codice sorgente, non usando un debugger .

  1. Cerca il testo (si spera distintivo) sul pulsante, ad es. "Super Feature X3".
  2. Questo è probabilmente in un file con qualche costante, ad es SUPER_BUTTON_3 = "Super Feature X3". Per riferimento futuro, ricordare questo nome di file.
  3. Potrebbe esserci un altro livello (anche di due) di astrazione, continua a cercare per ottenere la "vera" stringa che viene utilizzata dal pulsante. Nota come questo viene fatto per il futuro.
  4. Ora cerca su quella costante. Spero che tu abbia trovato il pulsante. Forse è qui che collegano ActionListener. (Sto prendendo Java-ese qui, YMMV, ma il concetto è ancora valido)
  5. Se necessario, cerca quel pulsante e alla fine troverai dove si collega a un ascoltatore.
  6. Forse quell'ascoltatore reindirizza davvero ad altri ascoltatori (la funzionalità "reale") in base alla costante, in tal caso, segui tale if / else o case case. NOTA : se è presente una questione di invio centrale, questo è un ottimo posto per impostare i punti di interruzione .
  7. Infine, dovresti essere al codice effettivo.

Come notato da @amon, a volte un debugger è più semplice ...


Interessante ... per fortuna tali nomi sono solitamente codificati nel codice :)
py_script

3
  • Se riesci a trovare qualsiasi codice correlato, puoi utilizzare il tuo software di controllo del codice sorgente per mostrarti l'intero commit o i commit nelle vicinanze che lo hanno aggiunto. Ciò dovrebbe mostrare tutto ciò che era necessario per implementare quella funzione.

  • Un modo semplice per trovare un punto di partenza è guardare attraverso la tua base di codice cercando il testo sul pulsante.

  • Spesso, le persone inseriscono un ID problema dal loro tracker dei problemi nei loro messaggi di commit. Se riesci a trovare un problema che descrive la richiesta di funzione, puoi cercare commit con quell'ID problema.


È un approccio intelligente, ma penso che funzioni solo negli ambienti aziendali. E se hai solo un tarball?
py_script
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.