2009-04-08 25 views
8

Qualcuno ha aggiunto un pass a gcc? o non proprio un passaggio ma aggiungendo un'opzione per fare alcune cose brutte ... :-) ...Aggiunta di un passaggio a gcc?

Ho ancora lo stesso problema a chiamare una funzione appena prima di tornare da un altro ... quindi mi piacerebbe investigarlo implementando qualcosa in gcc ...

Cheers.

EDIT: Aggiungere un passaggio a un compilatore significa rivisitare l'albero per eseguire alcune ottimizzazioni o alcune analisi. Vorrei emulare il comportamento di __cyg_profile_func_exit ma solo per alcune funzioni e poter accedere al valore di ritorno originale.

Quindi ho intenzione di provare a migliorare la mia domanda. Mi piacerebbe emulare un comportamento molto simile a quello di AOSD. La programmazione AOSD o Aspect consente di aggiungere preoccupazioni trasversali (il debugging è una preoccupazione trasversale).

int main(int argc, char ** argv) { 
    return foo(argc); 
} 

int foo(int arg_num) { 
    int result = arg_num > 3 ? arg_num : 42; 
    return result; 
} 

int dbg(int returned) { 
    printf("Return %d", returned); 
} 

Vorrei poter dire, mi piacerebbe attivare la funzione dbg dopo la funzione foo è stato eseguito. Il problema è come dire al compilatore di modificare il flusso di controllo ed eseguire dbg. dbg dovrebbe essere eseguito tra return e foo (argc) ...

Questo è veramente come __cyg_profile_function_exit ma solo in alcuni casi (e il problema in __cyg_profile_function_exit è che non si può facilmente vedere e modificare il valore restituito).

+0

Err ... Con chi ora? –

+0

Qualcuno una volta non ha dimostrato un hack che inserisce codice dannoso quando si è compilato da fonti (e quelle fonti potrebbero essere prive del codice errato)? –

+0

Non ho idea di cosa tu stia parlando, e so qualcosa su C, gcc e compilatori. –

risposta

4

Se siete ancora interessati ad aggiungere un passaggio GCC, è possibile iniziare a leggere il materiale GCC Wiki quasi che:

+0

grazie ... sapevo che questi riferimenti però ... Volevo qualcosa di meglio-documentato più come un tutorial ... Guardare le patch che implementano i passaggi è piuttosto ingombrante ... grazie però – LB40

+0

Hmm ... Al meglio delle mie conoscenze (occasionalmente contribuisco a GCC) se esistesse un tutorial del genere, sarebbe immediatamente collegato da quelle pagine. –

1

Per rispondere alla tua domanda: gcc è una piattaforma di compilazione molto popolare per fare ricerche sui compilatori, quindi sì, sono sicuro che qualcuno l'ha fatto.

Tuttavia, non penso che questo sia stato fatto in un fine settimana. L'aggancio alla generazione del codice di gcc non è qualcosa che dovresti fare durante il fine settimana. (Non sono sicuro di quale sia il tuo scopo e quanto tempo sei disposto a investire.) Se vuoi davvero hackerare gcc per fare ciò che vuoi, sicuramente inizi a discuterlo su uno dei gcc mailing lists.

Suggerimenti: non dare per scontato che le persone abbiano letto le altre domande. Se vuoi fare riferimento a una domanda, aggiungi un link ad essa se vuoi che la gente la trovi.

+0

Sono abbastanza sicuro che qualcuno lo abbia già fatto prima: -) ... Volevo solo evitare alcuni momenti dolorosi chiedendo questa community. In realtà la documentazione di gcc fornisce un sacco di patch che rappresentano passaggi insignificanti. Ma volevo trovare altre precisioni. La mia domanda era davvero troppo generica. scusa .. – LB40

0

Il GCC, GNU Compiler Collection, è una suite di grandi dimensioni e non credo che l'hacking del codice sorgente sia la risposta ai problemi di ricerca in una singola applicazione.

Sembra che si stia cercando di più, per strumenti di debug o di profilazione, come ad esempio gdb e i vari front-end (xgdb, ddd) e e gprof. Memoria/limiti strumenti di controllo come recinzione elettrica, glibc memcheck, valgrind e mudflap potrebbero aiutare se questo è un problema di memoria o puntatore. L'abilitazione dei flag del compilatore per gli avvisi e gli standard C più recenti potrebbe essere utile -std=c99 -Wall -pedantic.

non riesco a capire cosa si intende per

ho ancora lo stesso problema circa richiamo di una funzione poco prima ritorno da un'altra.

Quindi non sono certo quello che stai cercando. Puoi dare un esempio banale o pseudo-codice?

I.e.

#include <stdio.h> 
void a(void) { 
    b(); 
} 
void b(void) { 
    printf("Hello World\n"); 
} 
int main(int ac, char *av[]) { 
    a(); 
    return 0; 
} 
1

È una domanda interessante. Tratterò i concetti attorno alla domanda piuttosto che rispondere direttamente alla domanda perché, beh, non ne so molto di gcc internals.

Probabilmente hai già esplorato alcune manipolazioni di livello superiore del codice sorgente per ottenere ciò che desideri ottenere; una specie di

int main(int argc, char ** argv) { 
    return dbg(foo(argc)); 
} 

inserito con una macro sulla funzione "pippo", forse. Se stai cercando un hack del compilatore, però, probabilmente non vuoi modificare il sorgente.

Ci sono alcune estensioni gcc discusse here che suonano un po 'come quello che stai cercando. Se gcc ha qualcosa che fa quello che vuoi, probabilmente sarà documentato nell'area linguaggio extensions in linguaggio C della documentazione. Non sono riuscito a trovare nulla che assomigliasse esattamente a quello che hai descritto, ma forse dal momento che capisci meglio ciò che stai cercando, saprai meglio come trovarlo.

Uno script gdb farebbe un ottimo lavoro di output del debug, ma sembra che abbia piani più grandi di quelli di printf. Inserire una logica significativa nel codice sembra essere quello che stai cercando.

Che mi ricorda alcuni trucchi di linker dinamici che ho incontrato di recente. La libreria interposing potrebbe inserire il codice attorno alle chiamate di funzione senza influire sulla fonte originale. L'esempio che ho incontrato era su Solaris, ma probabilmente c'è un analogo su altre piattaforme.

appena incontrato l'opzione -finstrument funzioni documentate here

-finstrument-funzioni

Generare chiamate strumentazione per l'entrata e l'uscita alle funzioni. Subito dopo la funzione e appena prima dell'uscita dalla funzione, le seguenti funzioni di profilatura verranno chiamate con l'indirizzo della funzione corrente e il suo sito di chiamata. (Su alcune piattaforme, __builtin_return_address non funziona al di là della funzione corrente, quindi le informazioni sul sito chiamata potrebbe non essere disponibile per le funzioni di profiling altrimenti.)

  void __cyg_profile_func_enter (void *this_fn, 
             void *call_site); 
      void __cyg_profile_func_exit (void *this_fn, 
             void *call_site); 

ma credo che questo non funziona perché sei non è in grado di modificare il valore di ritorno dalle funzioni di profilazione.

+0

la funzione -finstrument consente di utilizzare __cyg_profile_function_exit, penso di aggiungere un'opzione e un attributo a gcc per fare la mia versione. Ho usato interporre prima per malloc e gratis ma il problema è che return è una parola chiave, quindi non puoi catturarla. – LB40

+0

Hmm ... non capisco davvero. Stai dicendo che devi eseguire dbg() dopo foo() SOLO quando "return foo();" e non durante altre, ad esempio, "if (foo()) {}" chiama? – veefu

+0

Non so, penso che l'interposizione avrebbe funzionato bene per te. Qual è la differenza tra l'inserimento del codice per modificare l'istruzione 'return' di X() e l'interposizione di un'altra X() che richiama la prima X() ma modifica il ritorno ricevuto? È lo stesso per il chiamante, giusto? – veefu

1

È necessario utilizzare GCC? LLVM sembra che funzioni. È scritto in C++, ed è molto facile da write a pass.

+0

sì ... conosco questo lavoro ... Sto cercando di minimizzare l'impatto della mia modifica sugli sviluppatori (ma anche la ricompilazione di gcc può essere complicata) ... ho intenzione di provare LLVM per vedere ... grazie ... – LB40

3

Solo per riferimento futuro: Prossimi versioni di gcc (4.4.0+) fornirà il supporto per plugins specifico significato per i casi d'uso come l'aggiunta di optimization passes al compilatore senza dover avviare l'intero compilatore.

6 maggio 2009: GCC può ora essere esteso utilizzando un framework di plugin generico su piattaforme host che supportano oggetti caricabili dinamicamente. (vedi gcc.gnu.org)

+0

nice ... grazie mille ... Vado a vedere che .. – LB40

+0

solo per le tue informazioni: l'infrastruttura è già installata, quindi se non ti interessa procurarti i sorgenti dal loro repository, allora può iniziare immediatamente – none