Hallo, zusammen! Gestern Abend hat mich ein kleines Problem auf meinem STM32F4 fast in den Wahnsinn getrieben: nach dem Auslösen eines Supervisor-Calls mittels "svc 0" ermittelte der SVC-Handler stets die SVC-Nummer 0xbe -- anstatt der erwarteten 0. (Zur Ermittlung dieser Nummer wird die Stelle im Code ausgelesen, an der sich das Argument der betreffenden svc-Instruktion befindet -- in diesem Fall eben die 0.) Während der Memory-Dump der betreffenden Stelle mir den erwarteten Wert anzeigte, wurde vom Prozessor jedoch stets der Wert 0xbe ausgelesen -- der scheinbar aus dem Nichts auftauchte. Des Rätsels Lösung: ich hatte einen Breakpoint auf die svc-Anweisung gesetzt. Dieser hat das Auslesen der betreffenden Code-Stelle beeinflusst, so dass die falsche SVC-Nummer ermittelt wurde. Bleibt nur die Frage, warum der Memory-Dump davon nicht betroffen war. Hat jemand eine Ahnung, weshalb? Christian
Christian Gudrian schrieb: > Bleibt nur die Frage, warum der Memory-Dump davon nicht betroffen war. > Hat jemand eine Ahnung, weshalb? Was denkst du, wie der Debugger Breakpoints realisiert?
Karl Heinz Buchegger schrieb: > Was denkst du, wie der Debugger Breakpoints realisiert? Indem er zur Laufzeit den Code modifiziert? Christian
Christian Gudrian schrieb: > Karl Heinz Buchegger schrieb: > >> Was denkst du, wie der Debugger Breakpoints realisiert? > > Indem er zur Laufzeit den Code modifiziert? Genau! Er nimmt die Instruktion raus und ersetzt sie durch Code, der im Prinzip einen Jump in den Debugger macht, damit er wieder die Kontrolle kriegt, wenn der Code an diese Stelle aufläuft.
Karl Heinz Buchegger schrieb: > Er nimmt die Instruktion raus und ersetzt sie durch Code, der im Prinzip > einen Jump in den Debugger macht, damit er wieder die Kontrolle kriegt, > wenn der Code an diese Stelle aufläuft. Und genau deshalb habe ich mich gefragt, warum diese Änderung im Memory-Dump nicht zu sehen war. Da waren weiterhin die Opcodes für ein "svc 0" zu sehen -- sonst hätte ich nicht so lange gebraucht, um das zu bemerken. Aber da das Anfertigen eines Memory-Dumps ja auch der Mithilfe des Debuggers bedarf, wird dieser vermutlich seine am Code gemachten Änderungen vor den geneigten Augen des Debuggenden verbergen und diesem so das Leben unnötig schwer machen. Also merke: keine Breakpoints auf svc-Anweisungen. Christian
Christian Gudrian schrieb: > Karl Heinz Buchegger schrieb: > >> Er nimmt die Instruktion raus und ersetzt sie durch Code, der im Prinzip >> einen Jump in den Debugger macht, damit er wieder die Kontrolle kriegt, >> wenn der Code an diese Stelle aufläuft. > > Und genau deshalb habe ich mich gefragt, warum diese Änderung im > Memory-Dump nicht zu sehen war. So dämlich sind die Programmierer des Debuggers nun auch wieder nicht. Als Programmierer sollst du ja nicht sehen, dass der Code hier modifiziert wurde. Du sollst dich auf DEINEN Code konzentrieren und nicht auf die Magie, die der Debugger dahinter abziehen muss. > Aber da das Anfertigen eines Memory-Dumps ja auch der Mithilfe des > Debuggers bedarf, wird dieser vermutlich seine am Code gemachten > Änderungen vor den geneigten Augen des Debuggenden verbergen und diesem > so das Leben unnötig schwer machen. Nicht unnötig schwer. Du bist auf einen Sonderfall gelaufen, an den die Programmierer des Debuggers nicht gedacht haben. Könnte man so gesehen als Bug bezeichnen. Alle Instruktionen, die weitere Erkentnisse aus dem Code selbst nachladen, muss der Debugger mit der heißen Kneifzange anfassen.
Karl Heinz Buchegger schrieb: > So dämlich sind die Programmierer des Debuggers nun auch wieder nicht. Die Dämlichkeit habe ich ehrlich gesagt eher bei mir gesucht. > Du bist auf einen Sonderfall gelaufen, an den die Programmierer des > Debuggers nicht gedacht haben. Könnte man so gesehen als Bug bezeichnen. Weiß nicht. Wie sollte man da anders vorgehen? Soweit möglich Hardware-Breakpoints verwenden? Wie läuft es denn nach einer Unterbrechung normalerweise weiter? Die Instruktion, die durch die Injektion des Breakpoints entfernt wurde, muss ja irgendwann ausgeführt werden. Das wird aber vermutlich am eigentlich Code vorbei geschehen, da der Breakpoint ja im Code verbleibt. > Alle Instruktionen, die weitere Erkentnisse aus dem Code selbst > nachladen, muss der Debugger mit der heißen Kneifzange anfassen. Die Messung beeinflusst das Experiment. Klassischer Heisenbug. Ein konservativer Debugger sollte sich also weigern, einen Breakpoint auf eine svc-Anweisung zu setzen? Christian
Christian Gudrian schrieb: > Weiß nicht. Wie sollte man da anders vorgehen? Soweit möglich > Hardware-Breakpoints verwenden? Wieviele BPs hast Du denn aktiviert? Ein vernünftiger Debugger sollte doch sowieso zunächst die Hardware BPs des Prozessors verwenden. > Ein konservativer Debugger sollte sich also weigern, einen > Breakpoint auf eine svc-Anweisung zu setzen? Alternativ könnte man den Parameter der SVC Instruktion auch ignorieren und die SVC Nummer in einem normalen Register übergeben. Das spart einem diesen hässlichen Teil der Auswertung. Geht natürlich nur, wenn man Kontrolle über den Code hat. -- Marcus
Marcus Harnisch schrieb: > Wieviele BPs hast Du denn aktiviert? Das war der einzige. > Ein vernünftiger Debugger sollte > doch sowieso zunächst die Hardware BPs des Prozessors verwenden. Eclipse mit ARM-Plug-in. Eigentlich ganz brauchbar. > Alternativ könnte man den Parameter der SVC Instruktion auch > ignorieren und die SVC Nummer in einem normalen Register übergeben. Das macht doch keinen Spaß. :) > Das spart einem diesen hässlichen Teil der Auswertung. Geht natürlich > nur, wenn man Kontrolle über den Code hat. Die Auswertung ist in der Tat hässlich. Trotzdem muss man da mal durch, wenn man den Cortex kennenlernen will. Christian
Christian Gudrian schrieb: >> Das spart einem diesen hässlichen Teil der Auswertung. Geht natürlich >> nur, wenn man Kontrolle über den Code hat. > > Die Auswertung ist in der Tat hässlich. Trotzdem muss man da mal durch, > wenn man den Cortex kennenlernen will. Das sage ich den Kursteilnehmern auch immer. Und dann rate ich ihnen, dass ganz schnell wieder zu vergessen. Die Auswertung des Parameters ist der einzige Grund warum der SVC Handler (oder Teile desselben) in Assembler implementiert werden muss. Gruß Marcus
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.