Forum: Compiler & IDEs GCC 4.1.1 + -minit-stack


von Stefan (Gast)


Lesenswert?

Hallo!

Ich habe vor kurzem AVR GCC 4.1.1 installiert. seit dem wird meine 
Option

-minit-stack=0x800400

Ignoriert.

der Aufruf des Compilers der main.c in welcher sich die main funktion 
befindet ist:

avr-gcc -c -fmessage-length=0 -Wall -Wstrict-prototypes 
-Wa,-adhlns=../main.lst -mmcu=atmega128 -minit-stack=0x800400 -Os 
-fshort-enums -fpack-struct -funsigned-char -funsigned-bitfields 
-std=gnu99 -save-temps -dB -DUART_RX_BUFFER_SIZE=512 
-DUART_TX_BUFFER_SIZE=64 -o"main.o" "../main.c" && \
echo -n 'main.d' ./ > 'main.d' && \

Ich nutze Eclipse unter WinXP mit dem AVR Plugin aus dem Thread

Beitrag "Eclipse und WinAVR"

habe mir mal die Assamblerdatei main.s angeschaut. bei GCC version 3.4.6 
steht da

.global  main
  .type  main, @function
main:
/* prologue: frame size=5 */
  ldi r28,lo8(0x800400 - 5)
  ldi r29,hi8(0x800400 - 5)
  out _SP_H_,r29
  out _SP_L_,r28
/* prologue end (size=4) */

GCC 4.1.1 macht daraus

.global  main
  .type  main, @function
main:
/* prologue: frame size=5 */
  push r16
  push r17
  push r28
  push r29
  in r28,__SP_L__
  in r29,__SP_H__
  sbiw r28,5
  in _tmp_reg_,__SREG__
  cli
  out _SP_H_,r29
  out _SREG_,__tmp_reg__
  out _SP_L_,r28
/* prologue end (size=12) */

alles beim gleichen aufruf des compilers

als erstes würde ich sagen, das der Prolog für die main funktion zu 
aufgeblasen ist, scheit als würde der compiler denken, er könne aus ihr 
zurückspringen.

weiterhin habe ich festgestellt, das bei GCC 3.4.6 der Stack 2 mal 
initialiesiert wurde. einmal auf 0x10FF und dann in der main funktion 
auf 0x0400 wie gewünscht.

habt ihr Eine idee wie ich GCC 4.1.1 dazu bringen kann, das er den Stack 
wert übernimmt??


Vielen Dank im Vorraus

Stefan

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


Lesenswert?

Stefan wrote:

> -minit-stack=0x800400

> Ignoriert.

Aus dem Bauch raus würde ich sagen, diese Option hat mittlerweile
keinen Sinn mehr.

> als erstes würde ich sagen, das der Prolog für die main funktion zu
> aufgeblasen ist, scheit als würde der compiler denken, er könne aus
> ihr zurückspringen.

Ja, main() ist eine normale Funktion geworden.

Deklariere sie als

int __attribute__((noreturn))
main(void)
{
  ...
}

Eigentlich sollte es wohl besser noch ein __attribute__((c_task)) oder
sowas geben, das wie noreturn wirkt, aber trotzdem noch einen
return-Wert gestattet.  Der Unterschied hat aber nahezu nur
akademischen Wert.

> weiterhin habe ich festgestellt, das bei GCC 3.4.6 der Stack 2 mal
> initialiesiert wurde. einmal auf 0x10FF und dann in der main
> funktion auf 0x0400 wie gewünscht.

Richtig.  Die zweite Initialisierung (das ist die, die man mit
-minit-stack beeinflussen konnte) ist aber schon lange Kokolorus
gewesen.  Der Stack muss deutlich vor main() initialisiert werden, da
sonst insbesondere die C++-Konstruktoren keinen Stack haben.

Unabhängig davon, ob man nun main() wirklich als normale Funktion
behandelt werden sollte oder nicht (das hat uns in der jetzigen Form
ein wenig kommentarlos der ATmega256x-Patch mitgebracht), die
Geschichte mit der Stack-Initialisierung in main() (und damit auch die
-minit-stack Option) gehört auf den Müllhaufen der AVR-GCC-Geschichte
entsorgt.

> habt ihr Eine idee wie ich GCC 4.1.1 dazu bringen kann, das er den
> Stack wert übernimmt??

Ja, so wie auch schon die früheren Compiler, vermutlich mehrere Jahre
lang bereits:

-Wl,--defsym=__stack=0x800400

von Stefan (Gast)


Lesenswert?

Hallo Jörg!

Vielen Dank für die Promte Antwort!

Funktioniert!

Habe auch das mit dem

int __attribute__((noreturn))
main(void)
{
  ...
}

Versucht, ändert aber nicht viel an dem Prolog der main funktion. auser 
das 2 push weniger sind. wenn mir mal die paar bytes fehelen, kann ich 
mich ja daran nochmalmachen.



Danke Stefan

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


Lesenswert?

Stefan wrote:

> Habe auch das mit dem
>
> int __attribute__((noreturn))
> main(void)
> {
>   ...
> }
>
> Versucht, ändert aber nicht viel an dem Prolog der main funktion. auser
> das 2 push weniger sind.

Sorry, ja, das muss auch
1
int __attribute__((noreturn, naked)) main(void) ...

sein.

Ich weiß, der GCC klagt dann darüber dass eine noreturn-Funktion
einen return-Wert hätte bzw. bei Deklaration mit void umgekehrt,
dass main() nicht vom Typ int ist.  Damit muss man bis zu einer
,,richtigen'' Reparatur wohl erstmal leben.

von Stefan (Gast)


Lesenswert?

Hallo Jörg!

wenn ich das naked dazu nehme, dann wirds ganz wild, und der Compiler 
jammert:

../main.c:31: internal compiler error: in start_function, at 
c-decl.c:6014
Please submit a full bug report,
with preprocessed source if appropriate.


wers bei no return belassen, vielleicht klappts bei der nächsten GCC 
version. ich werds mir merken.


Gruß Stefan

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


Lesenswert?

Stefan wrote:

> ../main.c:31: internal compiler error: in start_function, at
> c-decl.c:6014
> Please submit a full bug report,
> with preprocessed source if appropriate.

Dann bitte tu genau das.  Streich dein Programm so weit zusammen, dass
der ICE (internal compiler error) reproduzierbar ist, und reiche einen
Bugreport bei gcc.gnu.org ein.

> vielleicht klappts bei der nächsten GCC version.

Wenn es keiner als Bug berichtet, warum sollte sich was ändern?

von Stefan (Gast)


Lesenswert?

Hallo Jörg!

Wollte den Bug gerade posten, ist aber schon von jemand anders gemacht 
worden.

http://sourceforge.net/tracker/index.php?func=detail&aid=1687025&group_id=68108&atid=520074


Gruß Stefan

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


Lesenswert?

Hmm, als WinAVR-Bugreport kommt er nicht zu den GCC-Entwicklern.

Anyway, ich kann das für meinen Compiler nicht reproduzieren.  Wenn du
einen Sourcecode hast, mit dem es reproduzierbar ist, dann würde ich
mich weiter drum kümmern wollen.  Bitte häng' das einfach an den
WinAVR-Bugreport dran.

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


Lesenswert?

Ich hab's hier mit verschiedenen Projekten probiert, ich bekomme den
Bug nicht getriggert.

von Oliver (Gast)


Lesenswert?

1
int __attribute__((noreturn, naked)) main(void)
2
{
3
    return 0; // for the compiler...
4
}
1
../Main.c:4: internal compiler error: in start_function, at c-decl.c:6014
2
Please submit a full bug report,
3
with preprocessed source if appropriate.
4
See <URL:http://sourceforge.net/tracker/?atid=520074&group_id=68108&func=browse> for instructions.
5
make: *** [Main.o] Error 1
6
Build failed with 1 errors and 0 warnings...

gcc 4.1.1


Oliver

von Oliver (Gast)


Angehängte Dateien:

Lesenswert?

Hier nochmal mit makefile.

Oliver

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


Lesenswert?

Tja, ich habe das mittlerweile auch schon mit Eric Weddington
diskutiert, irgendwas scheint beim WinAVR-Compiler anders zu sein
als bei meinem.  Ist auch ein GCC 4.1.1, aber ich bekomme diesen
Bug nicht getriggert, egal womit.  Es gibt zwar minimale Differenzen
in den Patches zwischen WinAVR und FreeBSD, aber ich habe die
Patches seinerzeit verglichen und hätte nicht gedacht, dass bei
WinAVR einer dabei ist, der zu solchen Effekten führen könnte...

Wir haben auch nochmal die formale Syntaxbeschreibung der
Attribute im GCC-Handbuch nachgelesen, ich bin mittlerweile der
Meinung, dass aus GCC-Sicht folgendes technisch exakter wäre:
1
__attribute__((noreturn, naked)) int main(void) {
2
   ...
3
}

also die Attribute vor der Funktion.  Kannst du mal probieren, ob
das ein Unterschied ist für dich?

Ansonsten, was offenbar auf jeden Fall funktioniert ist, dass man
die Attribute nur in eine Prototypdeklaration steckt:
1
int main(void) __attribute__((noreturn, naked));
2
int
3
main(void) {
4
  ...
5
}

Idealerweise sollte man auch schreiben können
1
int
2
main(void) __attribute__((noreturn, naked))
3
{
4
  ...
5
}

aber dafür sagt das GCC-Handbuch ausdrücklich ``not yet implemented''.

von Oliver (Gast)


Lesenswert?

1
__attribute__((noreturn, naked)) int main(void) {
2
   ...
3
}
ergibt den selben Fehler wie oben.
1
int main(void) __attribute__((noreturn, naked));
2
int
3
main(void) {
4
  ...
5
}
funktioniert, ist aber auch nur 2 bytes kleiner als ein normales int 
main().
1
int
2
main(void) __attribute__((noreturn, naked))
3
{
4
  ...
5
}
bringt
>../Main.c:3: error: expected ',' or ';' before '{' token


Oliver

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


Lesenswert?

Oliver wrote:

>
1
__attribute__((noreturn, naked)) int main(void) {
2
>    ...
3
> }
> ergibt den selben Fehler wie oben.

OK.

> ..., ist aber auch nur 2 bytes kleiner als ein normales int
> main().

Naja, mehr scheint's dann nicht zu sparen zu geben.  Ich habe
damit jedenfalls (wie gewünscht) keinen Prolog mehr in main().

naked allein genügt eigentlich auch.

>>../Main.c:3: error: expected ',' or ';' before '{' token

Ja, ``currently not supported'' eben.

von Jörg (Gast)


Lesenswert?

Ich kann den Crash von WinAVR gcc 4.1.1 bestätigen, ich bekomme das auch 
wenn ich
1
__attribute__((noreturn, naked)) int main(void)
2
{
3
}
verwende.
Alternativ auch bei meiner Hauptschleife (Unterfunktion von main), die 
habe ich wahlweise auch so dekoriert.

Wenn ich hingegen nur den Prototypen dekoriere, also
1
__attribute__((noreturn, naked)) int main(void);
2
int main(void)
3
{
4
}
dann klappts. Spart bei bei main() nur 2 Bytes, hingegen bei der 
Hauptschleife 18 Bytes! Anscheinend hat er bei main() schon was erkannt. 
Ich habe noch nicht ins Disassembly geguckt.

von Stefan (Gast)


Lesenswert?

Hallo!

Mit dem Prototype

int main(void) __attribute__((noreturn, naked));

und dann:

int main(void) {

}

funktioniert es bei mir, und der Prolog wird auf 0 Byte 
zusammengestrichen, jedoch wie schon befürchtet mit der Warnung:

../main.c: In function 'main':
../main.c:102: warning: function declared 'noreturn' has a 'return' 
statement
Finished building: ../main.c

ansonnsten hast du ja deine Informationen die du brauchst, oder Jörg.


Gruß Stefan

von Veit W. (veitwehner)


Lesenswert?

ich hab die haessliche warning: `noreturn' function does return so 
wegbekommen, allerdings in einer beliebigen Fkt, nicht unbedingt main. 
Der Compiler meckert sonst, wenn er nicht eine Funktion erkennt, von der 
er weiss, dass sie nie zurueckkommt (wie zB exit)

#if !defined(_lint_)
#define _NORETURN_    for (;;) continue
#else
#define _NORETURN_
#endif

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.