mikrocontroller.net

Forum: Compiler & IDEs gcc Problem mit wrap und lto


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
Es scheint ein Problem mit Wrapperfunktionen und der LTO zu geben:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88643

Kennt hier jemand einen Workaround? Mit Bugzilla kenne ich mit nicht 
aus, wann könnte sowas gefixt werden? Der Fehler ist für 9.0 gemeldet, 
aktuell gibt es 9.2.1, da sehe ich das Problem immer noch.

von Oliver S. (oliverso)


Bewertung
0 lesenswert
nicht lesenswert
Johannes S. schrieb:
> Kennt hier jemand einen Workaround?

Steht doch da drin : nimm clang. Damit gehts.

Oliver

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
der Compiler ist vorgegeben und nicht so einfach auszutauschen (Mbed), 
da stehen Aufwand und Nutzen in keinem guten Verhältnis.

von DPA (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Genau wegen solchen Problemen verwende ich generell kein LTO.

In manchen Situationen könnte man ansonsten das weak attribut verwenden.

foo.h:
int cook(void);

bar.c:
#include "foo.h"
__attribute__((weak)) int cook(void){ return -1; }

foo.c:
#include "foo.h"
// Strong symbol, überschreibt das weak symbol cook
int cook(void){ return 0; }

main.c:
#include "foo.h"
int main(){
  if (cook () == -1)
    __builtin_abort ();
}

von Oliver S. (oliverso)


Bewertung
0 lesenswert
nicht lesenswert
Johannes S. schrieb:
> der Compiler ist vorgegeben und nicht so einfach auszutauschen (Mbed),
> da stehen Aufwand und Nutzen in keinem guten Verhältnis.

Je nun, wer hat denn dann gcc 9 für euer Projekt freigegeben? Wobei gcc 
8.3.1 das Problem auch schon hat.

Oliver

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
das ist nicht mein Project, Mbed ist ARM. Die unterstüzen schon drei 
toolchains: ARMCC, GCC und IAR. Als OS geht das sehr in die Tiefe und 
schon für die drei Compiler sind viele Fallunterscheidungen nötig.
LTO funktioniert da schon, nur mit den neuen wrappern nicht zusammen. An 
anderen Stellen wurden da schon Workarounds gebaut, für das 
printf/vsnprintf hat das aber noch nicht geklappt. Auch mit WEAK gibts 
die gleiche Mecker.
https://github.com/ARMmbed/mbed-os/issues/12542
Mbed5 ist massig gewachsen, mit bare-metal und LTO passt es jetzt wieder 
in kleine Controller. Dazu gibt es jetzt noch ein skalierbares printf, 
nur alles zusammen geht (noch) nicht.

von DPA (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Johannes S. schrieb:
> Auch mit WEAK gibts die gleiche Mecker.

Bei mir hat's funktioniert, aber mit dem älteren gcc 5.4.0 (der wrap bug 
war bei dem auch da). Hast du es mit dem Beispielcode oben probiert?

von DPA (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ansonsten, eventuell kannst du es mit einem Macro ersetzen?
void foo_a(int x);
void foo_b(int x);

#ifndef ALT_FOO
#define foo(...) foo_a(__VA_ARGS__)
#else
#define foo(...) foo_ ## ALT_FOO(__VA_ARGS__)
#endif
gcc -DALT_FOO=b

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
sieht irgendwie kompliziert aus, es soll ja eine Funktion aus der c-lib 
überschrieben werden. Die ist nicht weak definiert und nachträglich geht 
das auch nicht, dafür wird ja das __wrap_printf anstelle von printf 
gelinkt.

z.B:
https://github.com/ARMmbed/mbed-os/blob/c2c6d251fd6d6d7f5f8d5a920b3ad6ce4df0f8ba/platform/source/minimal-printf/mbed_printf_wrapper.c#L33-L41

: Bearbeitet durch User
von DPA (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Johannes S. schrieb:
> es soll ja eine Funktion aus der c-lib
> überschrieben werden.

Ach so. Eventuell kann man da mit der #include_next extension was 
machen:

stdio.h
#ifndef MYSTDIO_H
#define MYSTDIO_H

#define printf(...) my_printf(__VA_ARGS__)
#define puts(...)   my_puts(__VA_ARGS__)
// ...

#include_next "stdio.h"

#endif

Wenn man den include path so einrichtet, dass die eigene stdio.h zuerst 
gefunden wird, müsste das dann eigentlich alles auf die eigene umleiten. 
Es sei denn, diese sind bereits macros, dann müsste man die dann nach 
dem #include_next undefinen.

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
DPA schrieb:
> Ach so. Eventuell kann man da mit der #include_next extension was
> machen:

Danke für deine Ideen und Tipps.
Mit der include Reihenfolge wird es auch schwierig, die wird vom 
Buildsystem zusammengesucht. Könnte man beeinflussen, ist aber sehr 
aufwändig.
Das printf und die Varianten werden ja auch von anderen units benutzt, 
das ist das grössere Problem. Durch die Wrapper beim Linken erwischt man 
automatisch alle units die diese Funktionen benutzen und lenkt alle auf 
die wrapper um. Wenn in dem ganzen Programm auch nur einer die org stdio 
benutzt hätte man den Code beider Funktionen und genau das will man mit 
der Option ja nicht.

Der ARMC6 benutzt clang, mal sehen ob ich das damit testen kann. Den 
habe ich aber nur in der Form vom MbedStudio, und da ist vieles fix 
vorkonfiguriert und der lässt sich nicht aus der cmd starten.
Beim gcc gibt es die Linkeroption -fuse-ld=lld um clang als Linker zu 
benutzen, das hat auch nicht geklappt. Clang habe ich installiert und im 
Suchpfad, lld kann ich starten. Braucht man da eine Crosscompiler 
Version für ARM?

Dann habe ich noch die -u Option zum 'undefine Symbol' probiert. So wird 
z.B. auch main undefined und so der Linker gezwungen die zu suchen. 
Klappt mit -u printf aber auch nicht.

Wenn es nicht geht dann auf den nächsten gcc warten :) Das LTO scheint 
sehr komplex zu sein, da hatte ich vorher auch schon viel mit 
rumprobiert und viele Fehler bekommen.

Edit:
mit -u klappt es doch, es wurde __wrap_vsnprintf angemeckert und ich 
hatte die falsche Funktion angegeben. Irgendwann sollte man Pause 
machen...
Mit "-u main -u printf -u vsnprintf" linkt es, jetzt müsste ich mal die 
Codegrössen vergleichen.
ok, es compiliert, aber der Code mit -lto ist grösser, das printf ist da 
noch aus lib_a_nano drin. Also vertragen sich wrap und lto nicht 
wirklich.

: Bearbeitet durch User

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.

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