2017-08-18 2 views
0

Ich habe einige Probleme beim Debuggen von etwas sehr merkwürdigem Verhalten. Zum Beispiel haben wir:Debugging von Speicherproblemen ARM7

static const char* LOG_FORMAT = "0x%02x,%.5f,"; 

und der Zeiger ändert sich ohne ersichtlichen Grund. Manchmal zu Müll, manchmal zu anderen konstanten Strings (oder Teilen davon), die an anderer Stelle im Code definiert sind. Wir sehen auch gelegentlich, dass der Code zu einem anderen Abschnitt springt, der nicht ausgeführt werden sollte (die Statusvariable scheint sich ohne Aufforderung zu ändern). Es gibt 2 oder 3 allgemeine Fehlermodi, und sie scheinen zufällig zu passieren. Es ist eine relativ große Codebasis und das Hinzufügen oder Entfernen einiger Abschnitte ändert das Fehlerverhalten (oder entfernt es vollständig), obwohl auf diese Abschnitte NIE verwiesen wird. Die beste Theorie im Moment ist, dass es sich um ein Gedächtnisproblem handelt, da wir alle neuen Änderungen mit einem feinen Zahnkamm durchgeführt haben und der einfache Vorgang des Einfügens von Codeabschnitten, um Dinge zu verschieben, sich zu ändern scheint oder entfernen Sie das Verhalten.

Was sind die besten Möglichkeiten zum Debuggen dieses Problems oder ähnlicher Probleme? Habe den Debugger manchmal nützlich gefunden, und nicht bei anderen (aber das könnte ein Benutzerfehler sein).

Weitere Hinweise. ARM7, mit Keil μVision 4 und dem Armcc v4.1 Compiler.

+0

Es ist eine Weile her, seit ich mit ARM7 gearbeitet habe, aber ich glaube, es hatte ein paar Hardware Breakpoints zur Verfügung. Setzen Sie einen Wert, um nach einer Schreiboperation auf die Zeigervariable 'LOG_FORMAT' zu sehen, und sehen Sie, was sie verändert. –

+1

sicher klingt wie UB zu mir, aber Sie wussten das wahrscheinlich schon. Selbes merkwürdiges Verhalten auf unterschiedlicher aber identischer Hardware? – yano

+0

Anstatt direkt auf die Zeichenfolge zu verweisen, weisen Sie LOG_FORMAT Speicher zu und kopieren Sie die Zeichenfolge in LOG_FORMAT. – Rajeshkumar

Antwort

1

Dies bedeutet, dass Sie Zeiger Bugs/Speicher Korruption irgendwo im Programm haben ..., die durch eine Menge verschiedener Dinge verursacht werden können.

Der einfachste Weg, dies zu erkennen, besteht darin, das Programm bis zum Start von main auszuführen und dann "write" Breakpoints zur Variable hinzuzufügen. Dies sollte direkt auf den fehlerhaften Code hinweisen.

Eine wahrscheinliche Ursache ist ein Stapelüberlauf, bei dem der Stapel an einem fehlerhaften Speicherort abgelegt wird, so dass beim Überlauf .data oder .bss überschrieben wird. Siehe this article.

Sie können Stack-Überläufe debuggen, indem Sie den Stack-Speicher beim Start auf einen bekannten Wert setzen (z. B. 0xAA), das Programm eine Weile laufen lassen und versuchen, es so vielen Anwendungsfällen wie möglich zugänglich zu machen. Dann breche und überprüfe den Speicher des Stacks, um zu sehen, wie tief die bekannten Werte noch erhalten sind. Wenn dies nahe am Ende des Stapels ist, haben Sie sehr wahrscheinlich einen Stapelüberlauf.

0

Dies sieht aus wie ein Stack-Fehlausrichtungsproblem. Ihr Stack ist wahrscheinlich auf eine Einwortgrenze (vier Byte) anstatt auf ein Doppelwort (acht Byte) ausgerichtet.

Aus diesem Grund verursacht das Entfernen und Hinzufügen nicht verwandter Abschnitte ein unterschiedliches Verhalten. Je nachdem, wie viele Daten ihm vorangestellt sind, wird der Stapel nicht mehr ausgerichtet.

Der beschädigte Formatbezeichner ist ein weiterer Hinweis. Ein falsch ausgerichteter Stapel kann oft keine Probleme verursachen, bis eine variadische Funktion aufgerufen wird - insbesondere eine, die an einen Wert übergeben wird, der mit einem Doppelwort ausgerichtet werden muss.

Um dies zu debuggen, sollten Sie beim Aufruf von printf (oder welcher Funktion auch immer der Formatbezeichner verwendet wird) einen Haltepunkt setzen und den Stapelzeiger betrachten. Wenn SP nicht an einer Acht-Byte-Grenze ausgerichtet ist, haben Sie das Problem gefunden.