Hallo Leute ! Zunächst einmal ein frohes und gesundes neues Jahr an alle hier ! Dann zum Thema: Ich bastel gerade an einem Projekt mit nem atmega32. Darin kommen auch einige char-Arrays vor, welche zur Laufzeit (vermutlich) in dem SRAM geladen werden. Irgendwann habe ich mich gefragt, was wohl passieren wird, wenn mein Programm versucht, mehr SRAM des µC s zu belegen, als Dieser überhaupt hat. Merkt das der Compiler ( avr-gcc (GCC) 4.3.3 ) und warnt mich davor ?
Kommt darauf an, im Normalfall ja. Ingo
Ok , Danke. Compiler - Warnungen sind natürlich eingeschaltet :)
Giuseppe B. schrieb: > Compiler - Warnungen sind natürlich eingeschaltet :) Das wird in diesem Fall nichts nützen, es ist IMHO der Linker, der das merkt. MfG Klaus
Korrektur: im Normalfall nein [0]. Deswegen entsprechend aufpassen was man macht. [0] avr-size kann höchsten eine ziemlich einfache statische Analyse abliefern. für alles andere (und alles andere ist in der Regel das problematische, weil eben nicht so ohne weiteres statisch analysierbar) brauchts große Geschütze.
@ Giuseppe B. (brungi) >einige char-Arrays vor, welche zur Laufzeit (vermutlich) in dem SRAM >geladen werden. Das kann man vermutlich am Sourcecode erkennen,. >Irgendwann habe ich mich gefragt, was wohl passieren wird, wenn mein >Programm versucht, mehr SRAM des µC s zu belegen, als Dieser überhaupt >hat. Es wird komisch laufen oder abstürzen. >Merkt das der Compiler ( avr-gcc (GCC) 4.3.3 ) und warnt mich davor ? Meistens NICHT!. Denn der Compiler/Linker kann nur den statischen Speicherverbrauch ermitteln. Also alle globalen Variablen oder statische Variablen in Funktionen. Alle NICHT statischen Variablen in Funktionen kann er NICHT messen.
1 | void ausgabe (*char) { |
2 | static uint8_t zaehler; // statisch |
3 | char tmp[10000]; // dynamisch, Absturz |
4 | }
|
Was passiert eigentlich, der man den Index eines Arrays größer als Array selbst? Aus Erfahrung weiß ich das das Programm dann durchdreht bzw. Nicht weiter abgearbeitet wird. Aber was passiert intern im Speicher? Ingo
@ Ingo (Gast)
>Nicht weiter abgearbeitet wird. Aber was passiert intern im Speicher?
Dein Datenzugriff geht daneben!
Ich betrachte den Compiler hier jetzt mal als ganzes , damit meine ich C-code rein bis HexFile zum flashen raus., Inklusive LINKER, Postbuildsteps,... und was da sonst noch alles läuft. Den Speicherbedarf deiner statisch vorhandenen Variablen kennt der Compiler. Also alles was GLOBAL oder VOLATILE mit festen Größen angelegt ist. Anders sieht es bei lokalen Variablen aus, die in der Regel auf dem Stack liegen. Ebenfalls sobald du MALLOC , HEAP, ... verwendest, hast du eine dynamische Rambelegung. Diese dynamische Rambelegungm, die ja erst zur Laufzeit aktiv wird, kann dein Compiler nicht berechnen. Das heißt wenn du wissen willst ob dein Variablen Speicher ( GLOBALE und VOLATILE) ausreicht folgende Schritte. 1. Im LinkerCommand File den Rambereich für Stack und Varibalen sauber trennen durch eigene sections. 2. KEINE dynamische Variablen verwenden. ( Verbot von MALLOC,... ) ==> der Compiler kann dir nun eine verlässliche Warnung zum Variablen Rambedarf geben. ABER ob dein Stack ausreichend groß dimensioniert ist, kann dir kein Compiler sagen. Das geht nur zur Laufzeit. Möglichkeiten zur Erkennung: Die ersten und letzten Adressen des Stacks mit einem festen Muster befüllen zb 0xAA55AA55. Dann zyklisch alle x Msec prüfen ob das Muster noch da steht. Wenn das Muster nicht mehr dort steht ist dein Stack zu klein.
Ingo schrieb: > Was passiert eigentlich, der man den Index eines Arrays größer als Array > selbst? Aus Erfahrung weiß ich das das Programm dann durchdreht bzw. > Nicht weiter abgearbeitet wird. Aber was passiert intern im Speicher? Es gibt mehrere Möglichkeiten. 1. Du liest das was eine andere Variable an ihrem Speicherplatz enthält. 2. Du überscheibst eine andere Variable mit einem für diese Variable unsinnigen Wert. 3. Dein ArrayZeiger zeigt auf eine ungültige Addresse, das heiß Außerhalb des Rambereiches. Auswirkungen: 1. Kommt drauf an was deine Funktion mit dem wert macht, von "Es passiert nichts" bis Absturz ist alles möglich 2. Wie bei 1. allerdings kommt es nicht auf die Funktion an die den fehlerhaften Zugriff erzeugt, sonder die die betroffene Variable nutzt. 3. Das gibt bei den meisten ( ich wüsste jetzt keine Ausnahme ) µC einen nicht maskierbaren Interrupt (NMI) oder einen Reset. Es gibt da auch keinen Unterschied zwischen einem Variablen Array oder dem Stack. Verhalten und Auswirkungen sind die gleichen. Allgemein betrachtet ist ja auch der Stack nichts anderes als ein Array.
...habe mich übrigens gerade mit sowas in den A... gekniffen. Ein Programm lief erst ohne Probleme, habe dann ein Array vergrößert bis der Linker (oder ist es avr-size? Studio 6 gcc toolchain) ca. 90% des Speichers als genutzt ausgegeben hat und mich dann gewundert, dass mein Programm plötzlich merkwürdige Effekte zeigte. Kein Wunder, das Ende des Arrays hat dann Variablen auf dem Stack/Heap überschrieben :-( Da bin ich aber auch erst beim Debuggen drauf gekommen... Insbesondere wenn man auch Funktionen aus der avr c library nutzt, dürfte es mit dem Schätzen im Voraus schwert werden... Markus
Ralph schrieb: > Diese dynamische Rambelegungm, die ja erst zur Laufzeit aktiv wird, kann > dein Compiler nicht berechnen. Aber man kann Stack und Heap daraufhin überwachen, ob sie ineinanderlaufen (normalerweise wird ja der Heap von unten und der Stack von oben befüllt), dafür gibt es verschiedene Möglichkeiten. Das nützt bloss nicht übermässig viel, weil der Fehler ja nicht zu beheben ist, man kann höchstens versuchen, noch eine Fehlermeldung irgendwie abzusetzen und den Prozessor anhalten, ein sicheres Weitermachen ist nicht möglich. Viele Systeme machen das standardmässig so, i.A. kann man dann einen Schalter setzen, ob die Überwachung aktiviert wird - was natürlich Rechenzeit kostet. Gruss Reinhard PS in ähnlicher Weise kann man auch Strings oder andere Arrays auf Überlauf überwachen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.