Wie überprüfe ich den Stapelüberlauf in einer eingebetteten Anwendung?

Ich bin auf ein Problem gestoßen, bei dem ich glaube, dass mein Stack überläuft. Der Grund, warum ich dazu neige, so zu denken, liegt an folgendem:

1) Code kompilieren, in das Gerät ausgeben: - keine Aktivität vom Gerät (ich erwarte eine „Ich lebe“-Meldung)
2) In dieser Situation habe ich die Stapelgröße um 10 Bytes erhöht, neu kompiliert und auf das Gerät ausgegeben, und das Problem war weg.
3) Habe die beiden obigen Schritte 10 Mal hin und her probiert und kann das Problem zuverlässig reproduzieren und zuverlässig beheben.

Ich möchte sehen, wie der Stapel umfällt, wie mache ich das?

Ich verwende derzeit einen M16-Mikrocontroller mit 2 KB RAM (30 Bytes übrig), 256 Bytes Stapelgröße. Die IAR-Workbench, die ich verwende, verfügt nicht über das Call-Graph-Dienstprogramm.

Gibt es andere Möglichkeiten, dies zu tun - überprüfen Sie, ob der Stapel umfällt und wie viel Code?

Jede Hilfe wird wirklich geschätzt.

Vielen Dank!

Haben Sie einen Simulator für den Chip, in dem Sie den Code (schrittweise) ausführen können?

Antworten (3)

Eine gängige Methode zum Überprüfen der Speichernutzung besteht darin, den Speicher mit einem konstanten Wert vorab zu füllen, bevor Ihr Programm ausgeführt wird. Beispielsweise könnte eine Folge von 0xde 0xad durch Ihren Startcode in Ihren Stack-Bereich geschrieben werden. Während des Programmbetriebs wächst der Stack und überschreibt diese Sequenzen. Wenn Sie dann die Möglichkeit haben, den Speicher zu untersuchen, können Sie leicht die unberührten 0xde 0xad-Bytes im Speicher sehen und so feststellen, wie viel Stack verwendet wurde.

Es ist normalerweise schwierig, einen Überlauf zu erkennen, wenn er auftritt, da die Rücksprungadressen von Funktionsaufrufen auf dem Stack gespeichert werden und jede Funktionsrückkehr das Programm in den Abgrund schickt. Wenn in diesem Fall Ihr Watchdog aktiviert ist und Sie einen Haltepunkt am Reset-Vektor setzen können, können Sie möglicherweise immer noch den Speicher untersuchen und nach Ihren Prefill-Bytes suchen, um festzustellen, ob dies der Grund für einen Reset ist.

Wäre das nicht 'Danke Stapel'? ;)
hahaha! Stimmt, sehr wahr. :P

Erstellen Sie eine Variable, die sich oben (oder unten) in Ihrem Stapel befindet. Initialisieren Sie die Variable am Anfang von main. Sie können den Wert der Variablen in der Hauptschleife überprüfen, um im Nachhinein festzustellen, dass der Stack übergelaufen ist. Oder setzen Sie, wenn Ihr Debugger dies zulässt, einen Haltepunkt, wenn diese Variable geschrieben wird. Es sollte nur geschrieben werden, wenn es initialisiert wird.

Es gibt einige Programme, die statische Analysen durchführen können. Sie können einige Informationen mit Splint abrufen , da es mit Ihrem Quellcode nach Problemen sucht. Ich denke, es prüft nicht auf Stack-Probleme, kann Ihnen aber einige Einblicke in das Problem geben.