www.mikrocontroller.net

Forum: Compiler & IDEs Info über Lesezugriffe auf Variablen


Autor: Schnapphase (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

zu Optimierungszwecken versuche ich herauszufinden, ob eine bestimmte 
Variable abc in meinem Code irgendwann mal gelesen wird. Also, es kann 
ja sein, dass die Variable nur geschrieben wird - das wäre in Ordnung 
und interessiert mich nicht. Mich interessieren die Lesezugriffe.

Der Code wird generiert und ist sehr umfangreich, händische Prüfung 
scheidet da leider aus. (Gibt ja auch Zeiger auf die Variable, 
Funktionsübergaben, structs und arrays die indirekt auf die Variable 
zugreifen etc etc). Debugging ist auch nicht möglich.

Daher dachte ich: Der Compiler kann ja zumindest Warnungen anzeigen, 
wenn eine Variable nicht benutzt wird. Dazu muss er ja auch die Zugriffe 
prüfen. Kann ich mir beim Compilieren irgend ein Output-file erzeugen, 
dessen Informationen mir bei meinem Problem helfen?

Oder hat jemand vll eien ganz andere Idee, mein Problem zu lösen?

Autor: Bernhard R. (barnyhh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schnapphase schrieb:
> Daher dachte ich: Der Compiler kann ja zumindest Warnungen anzeigen,
> wenn eine Variable nicht benutzt wird. Dazu muss er ja auch die Zugriffe
> prüfen. Kann ich mir beim Compilieren irgend ein Output-file erzeugen,
> dessen Informationen mir bei meinem Problem helfen?

Ich unterstelle, daß es sich um
1. AVR-8-Bit Prozessoren,
2. die Programmiersprache "C",
3. den Compiler gcc unter Windows
handelt.

Die .lss Datei (?) - erzeugbar per Checkbox in den Compileroptionen - 
enthält genau diese Informationen: Suchen auf den Variablennamen in der 
Datei, Art des Zugriffs prüfen, fertig.

Für globale Daten ist die .map Datei ebenfalls brauchbar.

Bernhard

Autor: Schnapphase (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

fast richtig - geht aber um TriCore ;) Sonst passt's, gcc unter Windows 
und ja, C. Sorry, hätte ich noch erwähnen können.

Die .map Datei spuckt er mir auch aus, da sehe ich aber nur, in welchen 
Objects die Variable verwendet wird. Es wird aber nicht zwischen Lese- 
und Schreibzugriff unterschieden.

Eine .lss Datei hab ich noch nie gesehen. und Checkboxen hab ich bei 
meinem gcc auch nicht, ist dir evtl das zugehörige Flag für gcc bekannt?

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein grep mit Variablennamen über alle .c-Files liefert dir schonmal alle 
Zeilen, in denen die Variable vorkommen. Die musst du dann absuchen. Bei 
Zugriffen über Pointern, memcopy, unions, und ähnlichen Spielchen kommen 
die dann noch hinzu.

Oder mal doxygen über die Quellen laufen lassen, dessen output ist auch 
ganz hilfreich, um solche Fragen zu beantworten.

Auch schön ist ein hardware-debugger mit break on read ;)

Oliver

Autor: Schnapphase (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank erstmal für deine Hilfe.

Mein Problem ist, dass die Prüfung wirklich 100%ig korrekt sein muss. 
Der Debugger fällt daher schonmal raus, denn man kann mit vernünftigem 
Aufwand nicht absichern, dass wirklich alle möglichen Programmpfade beim 
Debugging durchlaufen werden. Auch wenn das halt on read natürlich 
optimal wäre ;)

Gleiches gilt für deinen grep-Vorschlag - schließlich gibt es Fälle, bei 
denen z.B. Zeigerzugriffe erst zur Laufzeit feststehen.
 pExample = &iExample + INPUT_PINS; 

Wenn die Belegung der Input-Pins halt zufällig so ist, dass pExample auf 
den zu untersuchenden Speicherbereich zeigt, hat man verloren. Gut, ob 
das nun praktisch wirklich relevant ist, sei mal dahingestellt...

Am liebsten wäre mir wirklich erstmal ein beim Compilieren generierter 
Outupt - klar wäre der auch nicht 100%ig sicher, aber der Aufwand wäre 
gleich Null und man könnte sich Gedanken machen, wie man damit 
weitermacht.

Doxygen schaue ich mir an.

Für alle anderen Vorschläge bin ich offen ;)

Autor: Bernhard R. (barnyhh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schnapphase schrieb:
> Am liebsten wäre mir wirklich erstmal ein beim Compilieren generierter
> Outupt - klar wäre der auch nicht 100%ig sicher, aber der Aufwand wäre
> gleich Null und man könnte sich Gedanken machen, wie man damit
> weitermacht.

gcc bietet eine Option, beim Compilieren ( Compile - ASM - LINK ) nach 
dem Compile Schluß zu machen und die entstandenen Assembler-Dateien zu 
analysieren. Der Name der Opßtion steht in der gcc Dokumentation.

Bernhard

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schnapphase schrieb:
> Gleiches gilt für deinen grep-Vorschlag - schließlich gibt es Fälle, bei
> denen z.B. Zeigerzugriffe erst zur Laufzeit feststehen.
>  pExample = &iExample + INPUT_PINS;

Und genau diesen Fall kannst du nie ausschließen. Dinge die erst zur 
Laufzeit feststehen kann man nunmal nicht zur Compilezeit prüfen.

Du kannst natürlich den erzeugten ASM Quelltext automatisiert 
untersuchen was etwas einfacher sein sollte als den C-Quelltext, aber 
auch dort sind Zugriffe mittels Pointer auf die Variable nicht wirklich 
einfach aufzudecken.

Kurz und gut:
Vermeide es die Adresse der Variable zu ermitteln (ist ja laut deiner 
Aussage generierter Code) und prüfe dann auf Schreibzugriffe mittels 
grep.

Matthias

Autor: Schnapphase (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> gcc bietet eine Option, beim Compilieren ( Compile - ASM - LINK ) nach
> dem Compile Schluß zu machen und die entstandenen Assembler-Dateien zu
> analysieren. Der Name der Opßtion steht in der gcc Dokumentation.

> Du kannst natürlich den erzeugten ASM Quelltext automatisiert
> untersuchen was etwas einfacher sein sollte als den C-Quelltext

Ja, das hab ich mir auch schon gedacht, die ASM files habe ich auch 
schon generieren können. Also wenn Codeparser, dann wohl mit dem 
Assemblercode.

Ich dachte halt nur, bevor ich mit nem Parser anfange, dass ich erstmal 
wegen den Compilergeschichten Infos einhole. Weil bei einem einfachen 
grep wirds nicht bleiben - Reicht ja schon, wenn die Variable als Zeiger 
einer Funktion übergeben wird, dann muss ja auch diese Funktion 
analytisiert werden, wobei die Variable dort anders benannt ist. Oder 
wenn ein Pointer auf die Variable gesetzt wird und dann halt damit 
zugewiesen bzw. gelesen wird. Und dann kann ja auch wieder ein Pointer 
auf den Pointer... und Arrays.... und ganz hässlich: Structs, die dann 
den Speicherbereich der Variable umschließen... usw usw usw. Ein 
einfaches grep wird da nicht reichen :/ Werde da wohl nicht drumrum 
kommen...

> Vermeide es die Adresse der Variable zu ermitteln

Wie meinst du das? Die Adresse steht bei mir nach dem linken ja schon 
fest.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schnapphase schrieb:
> Ja, das hab ich mir auch schon gedacht, die ASM files habe ich auch
> schon generieren können. Also wenn Codeparser, dann wohl mit dem
> Assemblercode.

Das ist aber nicht viel weniger spassig, als im C-Code. Die Adresse kann 
in Registern stehen, je nach Compiler wird da noch gepusht und 
"gepoppt". Ich kenne zwar jetzt den Tricore nicht, aber es würde mich 
wundern, wenn der keine indirekten oder indizierten Adressierungsarten 
kennt.

Das mit der 100%igen Sicherheit wird da auch schwierig.

Oliver

Autor: einfach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benenn einfach die Variable um, und schau dir die Fehler an, die der 
Compiler wirft !

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
einfach schrieb:
> Benenn einfach die Variable um, und schau dir die Fehler an, die der
> Compiler wirft !

geht leider nicht wenn irgendwo direkt auf den speicher der variable 
zugegriffen wird.

*((*int)0x1234) = 12;

Autor: Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich frage mich ja, in welcher Situation man sich die Frage stellen muss, 
ob eine bestimmte Variable gelesen wird. Sollte man als Autor nicht 
wissen, was sein Programm tut? - Und was ist daran so schlimm, wenn 
besagte Variable gelesen wird?

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schnapphase schrieb:
> Mein Problem ist, dass die Prüfung wirklich 100%ig korrekt sein muss.

Du hast verloren. Denn das Aliasing-Problem ist unentscheidbar.

Autor: Schnapphase (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht hierbei um ein Universitätsprojekt zur Entwicklung eines 
Codegenerators. Der vom Codegenerator erzeugte Quelltext soll bestimmten 
Prüfungen unterzogen werden, daher diese etwas 'weltfremde' 
Problemstellung.

Ist wohl alles ziemlich theoretisch, daher ist auch keine HW vorhanden, 
auf der man debuggen könnte.

Warum jetzt genau nur auf Lesezugriffe geachtet wird, weiß ich leider 
selbst nicht ;)

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im universitären Umfeld sollte man IMHO schon wissen, daß das 
prinzipiell nicht geht.

Aliasing ist nämlich eines der absoluten Standardprobleme in Compilerbau 
und Codeanalyse. Also setzt man Heuristiken ein und ignoriert die 
weltfremden Abweichungen (Codeanalyse) oder übersetzt konservativ 
(Compilerbau) oder schränkt die Programmiersprache ein (siehe C mit 
"strict aliasing").

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

wenn doch aber C-Code generiert wird könnte man den ja mit einem anderen 
Compiler übersetzen so das der Code auf debugfähiger Hardware (also im 
einfachsten Fall x86) lauffähig wird. Dann einen entsprechenden 
Datenbreakpoint erzeugen, das Programm mit Testdaten füttern und mit 
einem code coverage Werkzeug prüfen ob zumindest alle Zweige durchlaufen 
werden. Es kann natürlich auch nützlich sein den generierten Code in 
kleine Einheiten zu teilen und diese dann separat zu testen -> Unit 
Test.

Matthias

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Μαtthias W. schrieb:
> Dann einen entsprechenden
> Datenbreakpoint erzeugen, das Programm mit Testdaten füttern und mit
> einem code coverage Werkzeug prüfen ob zumindest alle Zweige durchlaufen
> werden.

Völlig unausreichend, denn dass aller Code durchlaufen wurde heißt noch 
lange nicht, dass jeder Pointer auch jeden möglichen Wert angenommen 
hat. Die gewünschte 100%-Lösung ist wie erwähnt schon theoretisch nicht 
machbar.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schnapphase schrieb:
> Es geht hierbei um ein Universitätsprojekt zur Entwicklung eines
> Codegenerators. Der vom Codegenerator erzeugte Quelltext soll bestimmten
> Prüfungen unterzogen werden, daher diese etwas 'weltfremde'
> Problemstellung.
>
> Ist wohl alles ziemlich theoretisch, daher ist auch keine HW vorhanden,
> auf der man debuggen könnte.

Um einen Codegenerator zu prüfen ist ein Compiler nicht das beste 
Werkzeug. Da schreibst besser einen Code-Generator-Prüfer ;-)

Um zu sehen, ob und wieviele Zugriffe (egal ob lesend und/oder 
schreibend) geschehen, kommst du nicht umhin, das Programm ablaufen zu 
lassen und per Profiling Informationen zu sammeln. Da man nicht weiß, 
wie lange das Programm läuft -- Halteproblem lässt grüssen -- muss die 
erzeugte Software schon bestimmte Eigenschaften sicherstellen, daß sie 
zB nach einer bestimmten Zeit oder bestimmter Anzahl Instruktionen 
terminiert. Andere Bedingung an den Generator wäre, daß der Code 
statisch analysierbar ist, aber selbst mit dieser starken Restriktion 
ist ein Compiler nicht das Werkzeug der Wahl. Dierzu gibt es Software 
zur statischen Analyse, die aber den Uni-Etat sprengen dürfte ;-)

Ebenso zu klären ist auch, ob die Anzahl der Zugriffe statisch zu 
bestimmen sind oder dynamisch. Beides erfordert komplett verschiedene 
Ansätze.

Auch andere Hardware ist keine Lösung, da auf dieser ein anderer 
Compiler den Code erzeugt. Daß der vielleicht "GCC" heisst tut da nix 
zur Sache. Ein anderes System ist also kein Modell für deinen TriCore + 
gcc.

Problem beim Profiling ist jedoch, daß es den Code verändert bzw. das 
Programm andere Ablaufeigenschaften hat; es ist also zunächst zu klären, 
was in dem Zusammenhang unter "Programm" zu verstehen ist: Es ist ja 
durchaus möglich, daß ein "foo=1" im C-Programm steht, sich aber nicht 
mehr im erzeugten Binary findet. Die Übersetzungsprozess sind die 
Nebenwirkung, die der Code hat, invariant. Mehr nicht. Jedenfalls wird 
der Code nicht Eins-zu-Eins übersetzt.

Am ehesten praktikabel ist die Verwendung eines Simulators und 
Compilererweiterungen wie Virtual Profiling -- unter der Voraussetzung, 
daß das Halteproblem-Dingens geklärt ist. Solche Erweiterungen gibt es 
zB für neuere Verionen des tricore-gcc von HighTec; und viele andere 
tricore-gccs dürften nicht unterwegs sein. Ergo: den Support fragen, was 
man dazu braucht. Die Analyse gilt dann allerdings nur für bestimmte 
Ablaufpfade.

Autor: Schnapphase (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstmal an dieser Stelle vielen Dank an alle für die zahlreichen 
Hinweise. Vor allem Johann, zu deinen Tipps werde ich mich mal belesen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.