Forum: Mikrocontroller und Digitale Elektronik Nach Funktionsrückgabe: Variabeln verändert?!


von Buffer (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich brauche mal wieder eure Hilfe. Ich bin bald am Verzweifeln:
Ich habe einen Ringbuffer implementiert. Dieser besteht aus einer 
struct, welche ein int-Array für die Daten und zwei ints (welche Start 
und Ende der Daten beschreiben) enthält.
Diese Strukt übergebe ich als Pointer an eine Funktion. Diese Funktion 
liest nur aus dem Buffer, ändert nichts daran (auch am Pointer nichts). 
Nur zeigt sie ein ganz komisches Verhalten: wenn ich mit dem Debugger 
Schritt für Schritt durch die Funktion gehe, dann kann ich immer schön 
sehen, dass der Buffer noch in Ordnung ist. Am Ende der Funktion (beim 
return) drücke ich noch einmal F11 für einen Einzelschritt. Und was 
kommt raus: Nur Müll. Es sind auch andere Speicherstellen völlig 
verändert. Das Programm arbeitet aber normal weiter...

Ich benutze HiTOP5 als IDE und einen ARM STR9. Wenn das eine Rolle 
spielen könnte.
Eigentlich könnte es ja der Stack sein, der beschädigt wird, aber das 
kommt eigentlich nur ganz selten in meinen ASM Projekten vor. Bei C 
hatte ich noch nie sowas...

Also ihr dürft raten, an was könnte es liegen? Am Code selber scheint es 
tatsächlich nicht zu liegen, hab mal eine Version auf dem PC mit erfolg 
laufen gelassen...

Im Anhang ein Bild mit den beiden Zuständen vorher (oberes Bild 
(Pointer)) unteres Bild ein Einzelschritt weiter.

Vielen Dank für eure Kreativität und Hilfe

von holger (Gast)


Lesenswert?

>Also ihr dürft raten, an was könnte es liegen?

Nö, tun wir nicht.

> Am Code selber scheint es
>tatsächlich nicht zu liegen, hab mal eine Version auf dem PC mit erfolg
>laufen gelassen.

Dann lass das Proggi doch einfach auf dem PC laufen.

von Matthias L. (Gast)


Lesenswert?

Der Fehler ist, wie immer bei COdeproblemen ohne geposteten Code, in 
Zeile 42.

von Buffer (Gast)


Lesenswert?

Hallo!

Auf dem PC habe ich wie oben geschrieben das Ding erfolgreich 
getestet...
Dass es am Code liegt ist unwahrscheinlich. Zumal beim beschriebenen 
Rücksprung nichts mit dem Pointer gemacht wird! Ich krieg die Krise. 
Nach einem Einzelschritt, welcher nichts mit dem Buffer zu tun hat ist 
alles verändert. Sogar Variablen, die dar nichts mit der aufgerufenen 
Funktion zu tun haben...

von marvin m. (Gast)


Lesenswert?

Schon mal darüber nachgedacht, dass der Speicher auf einem µC 
wesentlich kleiner ist, als auf einem PC? Für mich sieht das nach 
einem Stack-Problem aus. Dazu passt auch, dass es beim Aufruf einer 
Funktion passiert. Hast Du viele lokale Variablen in der Funktion 
benutzt?

von Kai G. (runtimeterror)


Lesenswert?

Code, code, code, code, code ... was ist daran so schwierig?

Wie Matthias schon sagte, Zeile 42!
http://de.wikipedia.org/wiki/42_%28Antwort%29

>Eigentlich könnte es ja der Stack sein, der beschädigt wird, aber das
>kommt eigentlich nur ganz selten in meinen ASM Projekten vor.
selten ist immer noch mehr als nie

>Ich benutze HiTOP5 als IDE und einen ARM STR9. Wenn das eine Rolle
>spielen könnte.
Könnte - da der Stack auf dem PC um ein paar Kubikbytes größer ist.

von Buffer (Gast)


Lesenswert?

Hallo!

Das mit dem Stack könnte sein, ich verwende nicht viele Lokale Variablen 
in der Funktion. Aber müsset wenn es sich um ein Stackproblem handelt 
nicht eher beim Aufruf der Funktion ein Problem auftauchen?

von Buffer (Gast)


Lesenswert?

Ich bins nochmal. Hab festgestellt, dass in der Funktion welche Probleme 
macht zei weitere Funktionen aufgerufen werden, welche schon ein 
"bisschen" Speicher benötigen. Es sind jeweils ca. 1.6 kBytes. Also 
eigentlich weit entfernt von den knapp 100kByte, aber wäre es möglich, 
dass er die irgendwie ungeschickt alloziert und so anderen Speicher 
überschreibt?
Der Gesamtspeicherbedarf des Programms beläuft sich auf ca. 50 kBytes, 
also auch noch weit von der Grenze entfernt (OK, der Stack braucht auch 
noch, aber wohl nicht den ganzen Rest). Der Speicherbedarf kann nicht 
(erheblich) gesenkt werden.
Wie kann ich die RAM organisation anschauen? Oder beeinflussen? Wäre 
eine Möglichkeit, den verwendeten Speicher statisch oder global oder so 
zu definieren, dass schon zu kompilierzeiten bekannt ist, welcher 
Speicher gebraucht wird?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ad nauseam:

> Code, code, code, code, code ... was ist daran so schwierig?

von Buffer (Gast)


Lesenswert?

Sorry, den Code kann ich hier nicht reinstellen. Dies aus zwei Gründen:
1. Er erstreckt sich über ca. 4 Files (die zeit reicht leider auch 
nnicht mehr für ein Minimalbeispiel zu destillieren)
2. Studienarbeit

Aber wie kann ich herausfinden ob es denn an der Speicherverwaltung 
liegt. Wie kann ich zum Beispiel die Stackgrösse herausfinden? Oder wie 
kann ich sehen wo er welche Daten bei einem Funktionsaufruf anlegt?

von ozo (Gast)


Lesenswert?

jetzt folgt unqualifiziertes Geblubber:

Du könntest dir testweise vor jedem Funktionsaufruf mal den aktuellen 
Stackpointer ausgeben lassen und vielleicht auch ein paar Bytes "über" 
dem Stackpointer - "über" in Richtung des Stackwachstums.
Und dann halt händisch oder per Debugger angucken, ob da vielleicht was 
wichtiges dem Stack im Weg liegt.
Eventuell könnte es auch erfolgversprechend sein, dir den Moment des 
returns aus der Funktion mal anzugucken und z.B. die Rücksprungadresse 
mit der auf dem Stack vergleichen.

von Kai G. (runtimeterror)


Lesenswert?

- Speicherverbrauch testweise reduzieren (Variablen in global Scope, 
Buffer verkleinern)

- Speicherverbrauch testweise erhöhen und schauen, ob/wie sich das 
Fehlerbild ändert

Damit kann man das schonmal ein wenig eingrenzen.

>Sorry, den Code kann ich hier nicht reinstellen. Dies aus zwei Gründen:
>1. Er erstreckt sich über ca. 4 Files (die zeit reicht leider auch
>nnicht mehr für ein Minimalbeispiel zu destillieren)
>2. Studienarbeit
Diese Information zu Beginn wäre nicht schlecht gewesen.

von Wetterer (Gast)


Lesenswert?

Einen Ringbuffer sollte man im Simulator laufen lassen koennen.

von Buffer (Gast)


Lesenswert?

So, habe nochmals ein bisschen getestet. Folgende interessante 
Beobachtung:
Nach dem die Funktion zurückgegeben hat und die Variablen scheinbar alle 
verändert sind kann ich einen Reset durchführen (ohne 
Spannungsversorgung zu trennen). Dann sind in die Inhalte wieder so wie 
vor dem Funktionsaufruf. Den Ringbuffer konnte ich nun mal im Speicher 
finden (im Debugger kann man das ganze Ram anschauen) Dort wird nichts 
verändert nach der Rückgabe. Es ist also irgendwie nur der Pointer der 
verändert wird.

Das Fehlerbild ändert sich tatsächlich ein wenig wenn ich die 
Speichergrösse des Ringbuffers ändere, allerdings nicht so, dass ich 
daraus schlüsse ziehen kann. Variablen die Nichts mit der Funktion zu 
tuna haben sind nach dem Funktionsaufruf manchmal alle 0, manchmal nur 
einige...
Komischkomisch

Der Ringbuffer funktioniert übrigens, den habe ich auch unter anderen 
Bedingungen schon erfolgreich im Einsatz....

von marvin m. (Gast)


Lesenswert?

Ich setze mal voraus, dass solche Konstrukte wie "goto" nicht in Deinem 
Code vorkommen...

Am Stack-Pointer oder an sonstigen System-Pointern schraubst Du nicht 
herum?

Interrupts?

Sieht ziemlich übel aus. Wie schonmal von Kai Giebeler vorgeschlagen: 
Wirf alles in global definierte Variablen (nicht schön, aber hilft bei 
der Fehlersuche). Idealerweise außerhalb der main() definiert.

von marvin m. (Gast)


Lesenswert?

Noch ne Idee: Benutzt Du Rekursionen? Die können einem auch sehr schnell 
den Stack voll machen...

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Du könntest wenigstens mal die betreffende Funktion posten...

von Buffer (Gast)


Lesenswert?

So, ich möchte nochmal berichten:
In der betreffenden Funktion hatte ich ein Array zu kurz initialisiert, 
weil ich in der Konstante welche die länge des Array angibt einen 
Tippfehler drin hatte. Dann kan es vor, dass es in diesem Array über das 
Ende hinaus geschrieben hat, wahrscheinlich genau in die Variablen bzw. 
Pointer, welche dann ein merkwürdiges Verhalten gezeigt haben.
Was ich daraus gelernt habe:
- Konstanten und Variablen sollten sich in der Namensgebung deutlicher 
unterscheiden
- Glaube nie einem Debugger (der hat wie bereits beschrieben die 
betreffenden Variablen erst nach dem Funktionsrücksprung aktualisiert, 
so dass ich natürlich am falschen Ort gesucht habe)

Vielen Dank für eure Tipps und Geduld!
Schönes Wochenende

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
Noch kein Account? Hier anmelden.