Newsgroup: it.comp.lang.c
Titolo: info di debug per numeri di linea (URGENTE!)

Salve ho un problema urgente!!!!
Uso il compilatore cygwin per dei sorgenti in C.
Nel mio programma uso delle funzioni (fatte da altri, molto tempo fa)
che mi permettono, in base al numero di linea del codice C, di
risalire
all'indirizzo di memoria.
Per es.:
****** file sorgente.c ******
1: #include ...
2: #include ...
ecc
ecc
30: int func1() {
...
...
40: } /* fine func1 */
*******************************
Poi ad es. la func1 si trovera' all'indirizzo 0x34A.
adesso quando il file viene preprocessato, solitamente la func1 non si
trovera' piu' alle linee 30-40, ma piu' in avanti, per l'espansione
delle direttive di include ecc ecc... e quindi quando chiedo
l'indirizzo
della linea 30 da' dei risultati sballati.
Quelle funzioni che devo usare fanno riferimento ai VECCHI
numeri di linea, quelli cioe' del sorgente originale, non
preprocessato.
Esiste un qualche flag, una qualche opzione o direttiva da dare al
compilatore in modo
tale che i numeri di linea si riferiscano al sorgente gia'
preprocessato??
Grazie.



Come stai usando quelle funzioni?  Includi il file sorgente delle 
funzioni con la direttiva:   #include "file.c"?
Questo è sbagliato ed appunto crea la numerazione errata.
Se vuoi evitare tale comportamento devi compilare ogni file 
separatamente oppure creare una libreria per quelle funzioni.
Se così non fosse mi sembra un comportamento del compilatore alquanto 
strano.
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   < 
http://giovanni.homelinux.net/
 >

 wrote:

Innanzitutto grazie per la risposta rapida!
Si, in pratica io ho dei sorgenti C da analizzare, e ci sono direttive
tipo:
#include "system.h"
#include "sys/alt_alarm.h"
#include "ee.h"
(fatti da altri e che non posso modificare)
in piu' ho alcune funzioni (sempre scritte da altri) che dato un num
di linea
mi dicono l'indirizzo di memoria.
Crecavo una pezza d'appoggio con le direttive al compilatore
senza dover riscrivere tutto daccato, anche perche' con gli esempi
funzionava tutto senza problemi.
Come posso, come mi consigli tu, compilare ogni file separatamente,
con qualche direttiva al compilatore?
Purtroppo non posso stare li' a passare giorni interi a studiarmi le
varie direttive. Se mi puoi rispondere non ti ringraziero' mai
abbastanza.

 ringraziero' mai abbastanza.
Non riesco a capire se in realtà il codice delle funzioni di cui 
cerchi l'indirizzo si trova in file .c inclusi da altri file .c. 
Oppure se le funzioni per la ricerca della posizione in memoria 
semplicemente sbagliano ad interpretare gli indirizzi perché gli 
#include .... dopo il preprocessing fanno spostare il numero della 
linea.  Se è questo il caso o il compilatore sbaglia o le funzioni 
stesse sono bacate.


 mi dicono l'indirizzo di memoria.
L'indirizzo di memoria di cosa?
Il preprocessore inserisce nel file di output i numeri di riga del file 
di input. Questo permette al compilatore di riferirsi ad i numeri di 
riga corretti, quando visualizza i messaggi di errore. Allo stesso modo, 
da codice, puoi fare riferimento ai numeri di riga con delle macro 
specifiche (mi pare sia __LINE__ e __FILE__ ti d� il nome del file).
E.

 stesse sono bacate.
In realta' TUTTO. Devo pare un parsing di TUTTE le funzioni del
programma C,
sia quelli nel file .c sia in quelli INCLUSI con #include.
Io penso che sbaglino perche' gli #include spostano il numero di
linea,
ma pensavo che il compilatore si riferisse al num di linea quando il
file era gia'
PREPROCESSATO.
Su bug delle funzioni che uso (non le ho fatte io) non penso perche'
con gli esempi
che avevo funzionava bene. Avevo dei sorgenti in C con degli #include,
e quando
chiedevo l'indirizzo di una funzione avendone il num di linea faceva
riferimento
al codice gia' preprocessato.
Ho cercato un po', ho visto l'opzione -g, che dovrebbe inserire le
info di debug
nell'oggetto. Sono sulla buona strada?

 E.
Mi riferisco all'indirizzo di memoria a cui cominciano e finiscono
le varie funzioni. Per es. se la funzione
int func1() si trova nel sorgente src.c alla linea 30,
con queste funzioni che mi sono state date, se metto come parametro
il nome del file "src.c" e la linea 30, mi restituiva l'indirizzo di
memoria
a cui e' allocata la func1.
Purtroppo non e' cosi' semplice, in quanto devo fare tutto questo
lavoro in JAVA.
Il problema era appunto la compilazione del codice C che mi sballava i
numeri di linea.
Percio' ho chiesto qui.


Con questo intendi dire che fai un preprocessing con un tool in java?
Se è questo il problema è il tool sbaglia.  Il preprocessore del 
compilatore come ti ho detto introduce delle informazioni che fanno si 
che il numero delle linee sia corretto.  Se usi l'opzione -g del 
compilatore vengono generate le informazioni di debug ed i numeri di 
linea corrispondono ai numeri del sorgente.
Esempio (file src.c):
#include <stdio.h>
int main(void)
{
   printf)"hello world!\n");
   return 0;
}
Generando il file preprocessato con
$ cc -E src.c -o src.i
si ottiene:
# 1 "x.c"
# 1 "/usr/include/stdio.h"	<-- passa al file stdio.h
# 28 "/usr/include/stdio.h"
# 1 "/usr/include/features.h"
# 330 "/usr/include/features.h"
   ......................
   ......................
extern void funlockfile (FILE *__stream);
# 912 "/usr/include/stdio.h"	<-- il file stdio.h ha 912 linee
# 2 "x.c"	<-- il contatore delle linee viene riportato a 2
int main(void)
{
   printf)"hello world!\n");
   return 0;
}
Se ne hai voglia studia il preprocessore C sviluppato per sostituire 
il preprocessore di un vecchio compilatore intel.  Lo trovi qui:
http://giovanni.homelinux.net/development/index.html


 wrote:

No. Faccio fare al preprocessore C tutto il compito di espansione, poi
mi servo (parzialmente)
di un parser in Java per scansionare i sorgenti C. Da questa scansione
ottengo
tutte le funzioni, e all'interno delle varie funzioni, i cicli for,
while, do, gli if, ecc ecc...
che poi rielaboro per i fatti miei.
Per "numeri del sorgente" intendi il sorgente ORIGINALE,quello cioe'
con
tutti gli #include?

 #include?
Si.  Come puoi vedere dall'esempio il preprocessore C produce le 
direttive per riallineare il conto delle linee.
# 2 "src.c"
serve per informare che la linea successiva deve essere conteggiata 
come linea 2 del file src.c
In alternativa lo standard C prevede:
#line 2 "src.c"
Il tuo parser deve cercare le direttive così formate e quindi 
comportarsi di conseguenza.


 tutti gli #include?
Ma io ancora non riesco a capire. Tu vuoi ottenere l'indirizzo di 
memoria in cui verr� caricata la funzione al momento dell'esecuzione, 
giusto?
Dunque in prima istanza devi andare a leggere i dati nei file OBJ, 
compilati con opzioni di debug. E' questo che fai?
Ora io non so esattamente quali informazioni trovi in questi files, ma 
sarei piuttosto propenso a pensare che gi� l� dentro trovi tutte le 
informazioni che ti servono ovvero nome del file sorgente e numero di 
riga, di ogni funzione e di ogni blocco di codice. IMHO deve essere 
cos�, perch� ho notato che il debugger individua sempre correttamente la 
  riga di codice corrispondente al punto di esecuzione del programma, 
mentre gli ambienti di sviluppo (anche quelli molto blasonati) spesso si 
sbagliano ad individuare la giusta "occorrenza" di una funzione (penso a 
funzioni "overloaded" alle macro o alla gestione dei "namespace"), 
proprio perch� cercano di parsare il codice sorgente.
E.

 E.
Si. L'indirizzo della funzione, ma non solo.
Mi servono anche i rami then e else, i corpi dei for, dei while, ecc
ecc.
Ecco perche' devo fare il parsing dei sorgenti e non posso affidarmi
solo
al file obj. Solo che con gli esempi che avevo per es. il main si
trovava
alla riga 1390 del file ESPANSO e con le funzioni che mi hanno dato
per trovare
l'indirizzo di memoria funzionava bene solo con i numeri di linea del
sorgente ESPANSO,
mentre con i sorgenti con cui ho a che fare adesso funziona solo con i
numeri
di linea del sorgente NON espanso.
Percio'avevo chiesto se ci fossew qualche direttiva che facesse cio',
visto
che con gli esempi aveva funzionato. Bisognerebbe vedere con quali
direttive
sono stati compilati, ma, manco a dirlo, non so rintracciarne gli
autori.

 al file obj. 
 > [...]
Onestamente non capisco il senso di quello che dici. Questo mi fa 
pensare che neanche tu abbia ben chiaro qual � il problema che devi 
risolvere.
E.

 non so rintracciarne gli autori.
Compilando con l'opzione -E viene prodotto un file che è l'espansione 
del sorgente C.  Però non è detto che i compilatori producano tutti lo 
stesso numero di linee e dovresti anche sapere quale compilatore e 
quale versione dello stesso è stato usato.
Lo stesso compilatore gcc produce risultati diversi in funzione della 
versione della libreria che stai usando.  Il motivo per cui vi sono le 
direttive '#line ..." è per fare in modo che gli strumenti di debug 
possano essere sempre allineati ai sorgenti, indipendentemente 
dall'ambiente su cui stai lavorando.
