www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMEGA32 Stackauslastung im AVR Studio anzeigen


Autor: Bernhard N. (bernieserver)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe mal eine ganz allgemeine Frage:

Wann weiß ich, dass beim Programmieren der Stack des Atmels überläuft? 
Lässt sich das überhaupt vorhersehen oder muss ich der RAM 
Nutzungsangabe des Compilers vertrauen? Gibt es eine Maximalgrenze, wo 
der Atmel aussteigt oder "crasht" der Stack dann einfach in dem 
Datenbereich hinein und manipuliert darin herum?

Den Heap (malloc... ) nutze ich nicht.

Ich nutze AVR Studio zum Debuggen und nutze einen "MK2" - Debuggerclon.



Gruß
Bernhard

Autor: Ben ___ (burning_silicon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
im prinzip kannst du jederzeit den stackpointer auslesen, dann weißt du 
auch wieviel auf dem stack liegt.

bei PCs kann man das so machen, daß man den speicherbereich mit einem 
bestimmten bitmuster füllt, das zu prüfende programm dann etliche tage 
und/oder unter den fraglichen bedingungen testet und dann schaut bis 
wohin das vorher gelegte bitmuster zerstört wurde. damit weiß man auch 
wie voll der stack war.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ben _ schrieb:
> bei PCs kann man das so machen, daß man den speicherbereich mit einem
> bestimmten bitmuster füllt

Bei PCs kann man das mittlerweile eher nicht mehr so machen, weil
der Stack dank virtual memory dynamisch nach Bedarf immer weiter
wächst. ;-)  Aber bei einem Controller kann man das auf jeden Fall
so machen.

Autor: Bernhard N. (bernieserver)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke,

nur hört sich das alles etwas kompliziert an. Wird der Stackpointer 
nirgends mitgeloggt? Oder ist die Wahrscheinlichkeit einfach so gering 
dass das nicht auftritt?
Wie siehts mit der Stacksize aus?

Gruß


Bernhard

Autor: aaaa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wahrscheinlichkeit dass es auftritt? Die ist bei jedem Programm anders. 
Grundsätzlich sollte man es aber als potentiell möglich ansehen, dass es 
unter bestimmten Bedingungen mal vorkommen kann.
Wenn du viele verschachtelte Funktionsaufrufe hast die jedes mal viele 
Register sichern müssen bekommst du schneller Probleme.

Eine Idee für dich: Nimm nen Counter und lese bei jedem Counterüberlauf 
den Wert des SPs aus. Den geringsten(!) Wert speicherst du dann irgendwo 
hin.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> Bei PCs kann man das mittlerweile eher nicht mehr so machen, weil
> der Stack dank virtual memory dynamisch nach Bedarf immer weiter
> wächst. ;-)  Aber bei einem Controller kann man das auf jeden Fall
> so machen.

scheinbar doch

http://www.pro-linux.de/news/1/16058/alte-sicherhe...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:

> scheinbar doch
>
> 
http://www.pro-linux.de/news/1/16058/alte-sicherhe...

Das ist (abgesehen davon, dass es ein Bug war -- sowas sollte
natürlich nicht passieren) doch aber was komplett anderes
als der Versuch, den "ganzen" Stack vorab mit einem Muster zu
beschreiben um danach festzustellen, wie viel davon wirklich
genutzt worden ist.  (Davon abgesehen werden die stack pages dort
vom OS vermutlich wirklich mit Nullen vorbelegt als Maßnahme dagegen,
dass möglicherweise sensitive Informationen eines anderen Prozesses,
dem dieser Speicher früher mal gehört hat, plötzlich zugänglich
werden.)

Normalerweise gibt's beim Versuch, den "ganzen" Stack zu belegen,
irgendwann ein SIGSEGV:
$ cat foo.c
int recurse(int i)
{
  return recurse(i * 2);
}

int
main(void)
{
  return recurse(42);
}
$ cc -O -o foo foo.c
$ ./foo
Segmentation fault

Autor: Ben ___ (burning_silicon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja ist ne alte technik. gaaanz früher zu DOS-zeiten (das hieß auch mal 
was anderes als denial of service) war der stack maximal 64kbyte groß 
(ein 16bit segment) und man war bestrebt möglichst wenig speicher zu 
reservieren. es macht keinen sinn speicher zu reservieren, den man nicht 
braucht - vor allem bei der TSR- (terminate and stay resident) oder 
virenprogrammierung (im grunde technisch nichts anderes als ein TSR). 
TSR-programme nutzen nach dem start z.b. den stack anderer programme. 
deshalb stack nur so groß wie nötig, und da war das eine beliebte 
methode um festzustellen ob man den reservierten stack wirklich braucht 
oder ob man noch weniger speicher für ihn reservieren kann.

klar, heute gibts bei PCs speicher für den stack im überfluss, und dank 
flat-speichermodell kümmert sich auch niemand mehr um die segmentierung.

trotzdem find ich das verfahren bei µCs vielleicht noch brauchbar, 
obwohl man dort den stack wohl immer ganz ans ende des RAM packt und ihm 
somit sämtlicher ungenutzter speicher zur verfügung steht. die größe 
spielt also eine untergeordnete rolle, wohl aber wenn ich in einer 
beliebigen umgebung rausfinden will wie groß der stack wird. dann würde 
ich das genau so machen weil ich die umgebung dafür nicht zu kennen 
brauche. beim start RAM komplett mit z.b. 88h füllen und irgendwann 
abzählen wo das letzte 88h im RAM steht. RAM-größe minus diese position 
ergibt die maximale stackgröße (wenn nicht gerade wer eine 88h auf den 
stack geschmissen hat, deswegen noch ein paar byte sicherheit lassen).

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ben _ schrieb:
> naja ist ne alte technik. gaaanz früher zu DOS-zeiten (das hieß auch mal
> was anderes als denial of service)

[OT]

Nö, hieß es damals schon. ;-)
   char *cp = NULL;

   [...]
   *cp = mychar;

...und der "denial of service" war perfekt.  Dann half nur noch der
Resetknopf.

Autor: sudo (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Um zum Thema zurückzukommen, hier zwei Files die das gewünschte 
nachrüsten.

Einfach mitcompilieren, im Programm kann man sich dann per 
get_mem_unused() den "unberührten" Teil des Stacks ausgeben lassen.

Weis leider nicht mehr von wen der Code ursprünglich stammt, vermute die 
Codesammlung hier.

Autor: Ben ___ (burning_silicon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja kaputt bekommt man alles wenn man will. zur not das erste kbyte des 
RAM schrotten, damit war die interrupttabelle weg und ende. und es gab 
auch irgendeinen befehl mit dem sich die console nach null umleiten 
ließ, das war's dann auch.

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.