[Cortex-M4] Breakpoint auf svc-Anweisung

OP #2539526
Lesenswert?

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
OP #2539544
Lesenswert?

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
#2539566
Lesenswert?

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.
OP #2539600
Lesenswert?

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
Persönliche Seite #2540204
Lesenswert?

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
OP #2540248
Lesenswert?

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
Persönliche Seite #2541105
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren