Forum: Compiler & IDEs Hash aus __FILE__ und __LINE__


von Torsten (Gast)


Lesenswert?

Hallo,
ich suche nach einer Möglichkeit, aus _FILE__ und __LINE_ (oder etwas 
anderem) eine art hash-Wert zu bilden, den ich für sehr komprimierte 
Error logs verwenden möchte, um z.B. die Position eines `asserts` 
festzuhalten. _FILE_ möchte ich nur ungern direkt verwenden, weil ich 
dann sicherlich eine große Menge an Stringliteralen im Binary hätte. 
Folgende zwei Möglichkeiten sind mir bis jetzt eingefallen:

1) eigenen Preprozessor schreiben, der _FILE_ expandiert in einen hash 
eindampft:

  assert("Geht nicht")

macht der preprozessor

  assert_impl("Geht nicht", "test.cpp", 123)

danach müsste der eigene Preprozessor daraus:

  assert_impl("Geht nicht", 0x47110815, 123)

machen.

Das verkompliziert den build Prozess natürlich enorm.

2) lokale Funktion definieren und die Adresse nutzen um Code-Stelle fest 
zu halten:

   assert("Geht nicht")

wird zu:
   {
      struct foo { void bar() {} }
      assert_impl("Geht nicht", &foo::bar )
   }

dann müsste man aus den Debug Informationen von der Adresse von bar() 
auf die Datei schließen können.

Das sind jetzt nur Skizzen, prinzipiell sollten aber beide Verfahren 
funktionieren.

Hat jemand noch eine andere / bessere Idee, wie man eine Zeile im 
Quellcode mit einem hash identifizierbar machen kann? Ups, mir düngt 
gerade, dass ich wahrscheinlich nach dem Wert des Program Counters 
suche.

mfg Torsten

von Walter Tarpan (Gast)


Lesenswert?

Torsten schrieb:
> Ups, mir düngt
> gerade, dass ich wahrscheinlich nach dem Wert des Program Counters
> suche.

Oder nach einem unique Identifier.

von Walter Tarpan (Gast)


Lesenswert?


von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Torsten schrieb:
> FILE möchte ich nur ungern direkt verwenden, weil ich dann sicherlich
> eine große Menge an Stringliteralen im Binary hätte.

Pro Datei eins halt, ist das zu viel?

von Torsten (Gast)


Lesenswert?

Walter Tarpan schrieb:
> http://stackoverflow.com/questions/1132751/how-can...

Die Antworten zielen ja eher darauf, einen einmaligen compile time 
identifier zu erstellen. Ohne debug-Informationen im Binary, kann ich 
damit dann zur Laufzeit eigentlich nichts mehr anfangen. Oder habe ich 
da etwas falsch verstanden?

mfg Torsten

von Torsten (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Torsten schrieb:
>> FILE möchte ich nur ungern direkt verwenden, weil ich dann sicherlich
>> eine große Menge an Stringliteralen im Binary hätte.
>
> Pro Datei eins halt, ist das zu viel?

Könnte knapp werden, wenn die Pfade zu den Dateien recht lang werden 
(und das hängt davon ab, wo der Quelltest aufgecheckt und gebaut wurde), 
könnten dass schnell mal 100 Byte pro Datei werden.

mfg Torsten

von Torsten (Gast)


Lesenswert?

Walter Tarpan schrieb:
> http://stackoverflow.com/questions/1132751/how-can...

Ich gehe bei meiner 2. Lösung davon aus, dass der Compiler, weil ich die 
Adresse der Funktion nehme, irgend wo so eine kleine Funktion im Code 
ablegt (im Idealfall nur ein return) und dies für jedes expandiertes 
Makro macht. Die Identifikation der Quellcode-Zeile passiert dann über 
die Adresse dieser Funktion.

mfg Torsten

von Stephan (Gast)


Lesenswert?

um FILE kleiner zu machen:

Beitrag "Re: GCC Präprozessor macro '__FILE__' abkürzen"

nur ein Tip

von Torsten (Gast)


Lesenswert?

Stephan schrieb:
> um FILE kleiner zu machen:
>
> Beitrag "Re: GCC Präprozessor macro '__FILE__' abkürzen"

Danke für den Tipp. Das hat leider den Nachteil, dass das Makro immer 
nur den Namen der Übersetzungseinheit trägt und damit nicht für Code in 
hadern funktioniert.

Trotzdem Dankeschön an alle!

Mfg Torsten

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Im Code wie gewohnt assert() verwenden.

Compiler in den Modus versetzen, dass er nicht kompiliert, sondern nur 
alle Preprozessor-Expandierungen und Ersetzungen macht. Also nur den 
Preprozesser über das Compiler-Frontend nutzen. Beim GCC ist das -E. Das 
gibt .i Dateien

Den expandierten Code in den .i Dateien durch einen eigenen, weiteren 
Preprozessor jagen. Der sollte nach assert_impl() suchen (oder was auch 
immer der Compiler da einsetzt) und den Funktionsaufruf und alle 
Argumente durch was auch immer gewünscht ist ersetzen. Mit gängigen 
Skriptsprachen ist das in geschätzten 5 bis 20 Codezeilen möglich.

Die geänderten .i Dateien durch den Compiler jagen. Fertig.

Ein paar Zeilen Makefile halten das alles zusammen. Eine Regel um aus .c 
.i zu erzeugen und gleich zu patchen. Eine weitere um .i nach .o zu 
kompilieren. Die übliche eingebaute oder explizite Regel um alle .o's 
zusammenzulinken. Eventuell noch an .SUFFIXES: schrauben.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.