Reindirizzare il debugger al codice utente quando si passa attraverso il codice del motore in C ++

0

Ho un progetto (C ++, Visual Studio 2015) in cui sto pensando di fare in modo che l'API di una libreria utilizzi lambdas o oggetti funzione in modo che l'utente abbia un posto dove inserire i punti di interruzione di debug per sapere quale codice utente di livello più alto corrisponde al codice di livello inferiore un motore è attualmente in esecuzione. Prima di farlo, voglio assicurarmi che non manchi un modo migliore per ottenere la stessa funzionalità di reindirizzamento del debugger dal codice di implementazione al codice utente.

Quando eseguo il debug di un programma strutturato tra "codice utente" e un interprete generico o "codice motore", il debugger mostrerà i dettagli di basso livello nel circuito interno del motore, quando ciò che preferirei vedere è il codice utente che ha generato l'oggetto espressione che il motore sta ora valutando.

(Ciò può accadere anche quando il codice utente è in realtà anche C ++, ad esempio nel caso di calcoli posticipati: quando viene valutato l'oggetto che avvolge un calcolo differito, la funzione utente che lo ha creato è fuori dallo stack di chiamata. )

Quali tecniche potrebbero essere disponibili per un motore o un interprete per comunicare al debugger (modi portatili o risposte specifiche per Visual Studio), "hey, so che stiamo effettivamente passando attraverso il file del motore X.cpp linea N, ma potresti forse comportarti come se avessimo fatto irruzione nel debugger nel file Y.ZZZ sulla riga M? "

Ad esempio, immagina se ci fosse un sovraccarico di __debugbreak () che accetta un nome di file e un argomento di numero di riga. (Diverso dal file corrente e dal numero di riga, dovrebbe essere un valore di runtime.)

In un precedente progetto ho scritto un wrapper o shim tra gdb e il debugger visivo Code :: Blocks, che eseguiva questa sostituzione di informazioni sul numero di file e di linea. Funzionava (quando gdb interrompeva il codice del motore, il wrapper reindirizzava l'interfaccia utente visiva al codice utente in base ai dati interni al motore), ma ci voleva troppo tempo per sviluppare e mantenere il programma shim.

La cosa reale che ho in mente per il mio progetto attuale è di far sì che il motore (che già riguarda comunque il calcolo differito) faccia uso esplicito di lambda nella sua API rivolta all'utente. Se l'utente fornisce necessariamente i callback, consentirebbe al motore di eseguire il threading nel codice utente ogni volta che si tratta di eseguire un passaggio che implica un'espressione fornita dall'utente. L'idea è che se un'operazione può potenzialmente generare un'eccezione o qualche altro risultato di interesse, funziona il file: riga della funzione dell'utente e parte del contesto di quella funzione utente (qualsiasi cosa si trovi nella chiusura lambda) di nuovo in pila in modo che sarà lì quando si verifica la condizione.

Sembra complicato, ma è molto simile allo stile di passaggio continuo: più semplice da programmare che da spiegare a parole. Anche così, voglio assicurarmi che non mi manchi una soluzione migliore prima di andare lì.

    
posta Dennis 12.10.2017 - 17:27
fonte

0 risposte

Leggi altre domande sui tag