Forum: Mikrocontroller und Digitale Elektronik AVR Debugger zeigt falsche Werte


von Dennis K. (scarfaceno1)


Lesenswert?

Guten Tag,

ich debugge auf einem Atmega128A mit externem Ram und Flash.
In den defines habe ich stehen:
1
#define Ein                     1  /* Definition für Bit-Variablen */
2
#define Aus                     0  /* Definition für Bit-Variablen */

Die Variable Meldung wird gesetzt
1
char Meldung, Meldung2;
2
3
Meldung = Aus;
4
Meldung2 = Aus;
5
if (((Zeichenkette[0] == 'D') && (Zeichenkette[1] == 'a') && (Zeichenkette[2] == 't')) ||
6
((Zeichenkette[0] == 'E') && (Zeichenkette[1] == 'r') && (Zeichenkette[2] == 'r')) ||
7
((Zeichenkette[0] == 'S') && (Zeichenkette[1] == 'e') && (Zeichenkette[2] == 'r') && (Zeichenkette[3] == 'v')))
8
Meldung = Ein;
9
10
if ((Meldung == Ein) && (!((Zeichenkette[0] == 'E') && (Zeichenkette[1] == 'r') && (Zeichenkette[2] == 'r')))) Meldung2= Ein;

Beim durchsteppen ist mir zunächst aufgefallen, dass Variable Meldung 
gar nicht den Wert 0 annimmt, wenn sie auf Aus gesetzt wird, sondern sie 
steht bei -11.
Ist eine der if Bedingungen erfüllt, dann ändert sich der Wert in der 
Variablen auch gar nicht. Ich beobachte im Debugger (Atmel Studio 7) den 
gleichen Wert, obwohl die Codezeile "Meldung = Ein" aufgerufen und 
anscheinend ausgeführt wird...

Woran kann das liegen?


Achso. Es ist die höchste Optimierungsstufe des Compilers ausgewählt. 
Kann es damit zusammenhängen?
Wird das einfach falsch dargestellt?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis K. schrieb:
> Woran kann das liegen?

Daran, dass der Compiler schon drei Schritte weiterdenkt als du.

Wenn du partout pessimieren möchtest und dem Compiler nicht übern
Weg traust, dann setz' die Variablen (vorübergehend) „volatile“.

von Dennis K. (scarfaceno1)


Lesenswert?

Ok... Danke.

Gesagt, getan.

Keine Änderung...

von Stefan F. (Gast)


Lesenswert?

Benutze die Compiler-Option -O0 (Minus Oh Null), damit reduzierst du die 
Optimierungen auf ein Minimum. Der erzeugte Maschinencode entspricht 
dann eher dem, was du geschrieben hast.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Benutze die Compiler-Option -O0 (Minus Oh Null), damit reduzierst du die
> Optimierungen auf ein Minimum.

Dümmster Ratschlag.

Was genau bringt das, persönliche Beruhigung?  Fehler vertuschst du
damit eher, als dass du sie aufdeckst, und im schlimmsten Fall passt
der Code dann gar nicht mehr in den Flash oder wird zu langsam.

„Immer, wenn ich hier aufs Gas trete, fährt das Auto ganz schnell
los!“ – „Dann fahr doch mit angezogener Handbremse.“

Ohne ein Stück mehr (compilierbaren!) Code kann man nicht viel dazu
sagen, was da abläuft.  Die Wahrscheinlichkeit, dass sich der Debugger
irrt, dürfte viel größer sein als die, dass sich der Compiler irrt.

von U. C. (Gast)


Lesenswert?

Jörg W. schrieb:
> Dümmster Ratschlag.
>
> Was genau bringt das, persönliche Beruhigung?


Darum ist das kein dummer Ratschlag!
Aus dem Handbuch:
> -O0
> ..... and make debugging
> produce the expected results.....

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

U. C. schrieb:
> Darum ist das kein dummer Ratschlag!

Was bitte hilft das dem TE genau?

Dass er beruhigt sein kann, weil sich der Compiler doch nicht geirrt
hat?  Das kann er dann auch mit Optimierung.

Wenn jedoch wirklich was daran liegt zu ergründen, was da passiert,
dann wird nichts umhin führen, den Code anzugucken.

von Freshman goes on air (Gast)


Lesenswert?

1 ist kein char '1' dagegen schon.

von U. C. (Gast)


Lesenswert?

Jörg W. schrieb:
> Was bitte hilft das dem TE genau?

Ich fasse die Eingangsfrage mal extra für dich zusammen:
> Meine Variablen zeigen im Debugger Mist!
> Woran kann das liegen?


> Es ist die höchste Optimierungsstufe des Compilers ausgewählt.
> Kann es damit zusammenhängen?
Eindeutig: Ja!

Man kann sich mit dem Debugger stundenlang irgendwelche Variablen 
anschauen. Und, da steht Mist drin. Denn der Compiler wird oft die 
Entscheidung treffen, die Werte möglichst lange in Registern zu halten.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

U. C. schrieb:
> Eindeutig: Ja!

Keineswegs so eindeutig.

Wenn es so eindeutig gewesen wäre, dann hätte das lokale Deaktivieren
der Optimierung (per "volatile") genauso helfen müssen.  Hat es aber
laut TE nicht, und seither haben wir von ihm nichts mehr gehört.

von U. C. (Gast)


Lesenswert?

Mich interessiert nicht, ob da Fehler im Code sind. Wenn da keine wären, 
brauchte man da nicht mit dem Debugger ran.
Dein Vorschlag läuft darauf hinaus, sich das Debuggen unnötig schwer zu 
machen.
Und die Hürde kann man sich einsparen.

Wenn ein Code mit -O0 nicht läuft, wird er es mit -Os und -O3 vermutlich 
auch nicht tun.

Für mich ist das Compilerhandbuch die Bibel. Und solange es keine 
Gegenanzeigen gibt glaube ich ihr. Insbesondere, weil sich schon einiges 
davon bestätigt hat.


Was mich wirklich verblüfft, ist:
Dass du eine Handbuchkonforme, empfohlene und oftmals in der Praxis 
bewährte Methode, so runter machst.




Jörg W. schrieb:
> Keineswegs so eindeutig.
Natülich KANN es an der Compilereinstellug liegen, dass der Debugger 
Mist zeigt!
Ich habe KA, wie du das anzweifeln kannst....

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

U. C. schrieb:

> Wenn ein Code mit -O0 nicht läuft, wird er es mit -Os und -O3 vermutlich
> auch nicht tun.

Trugschluss.

Wenn er dann zu langsam ist, läuft er eben nicht mehr.

Vermutlich habe ich in den Jahren meiner Controllerprogrammierung
zu viele zeitrkritische Dinge bearbeiten müssen. ;-)

> Was mich wirklich verblüfft, ist:
> Dass du eine Handbuchkonforme, empfohlene und oftmals in der Praxis
> bewährte Methode, so runter machst.

Ich habe diese Holzhammer-Methode schon immer für Unfug gehalten und
daraus nie einen Hehl gemacht.

Wenn schon, kann man lokal die Optimierung ein wenig ausbremsen, das
führt viel schneller zum Ziel (das genannte "volatile" beispielsweise,
oder mal einen NOP, auf den man einen Breakpoint setzen kann und sich
dann die Register ansehen).

Alle Fehler, die ich in den letzten 10 Jahren wirklich ernsthaft
suchen musste, waren keine, die ich auch mit global abgeschalteter
Optimierung noch hätte finden können.  Wenn man die Sprache selbst
erstmal einigermaßen gut genug beherrscht, macht man die Klasse von
Fehlern, bei denen sowas hilft, nur noch extrem selten.  Die Bugs,
die dann noch auftauchen, sind viel subtiler.

Aber siehe oben, solange der TE sich nicht mehr meldet, ist ihm nicht
viel zu helfen.

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

U. C. schrieb:
> Ich habe KA, wie du das anzweifeln kannst....

Weil dann das "volatile" genauso hätte helfen müssen, denn es schaltet
effektiv die Optimierung für genau diese Variablen ab.  Da der TE
schreibt, dass das Bild danach unverändert war, ist entweder was ganz
anderes daneben, oder der Debugger spinnt einfach.

von U. C. (Gast)


Lesenswert?

Jörg W. schrieb:
> Aber siehe oben, solange der TE sich nicht mehr meldet, ist ihm nicht
> viel zu helfen.
Vertrieben?

Jörg W. schrieb:
> ist entweder was ganz
> anderes daneben
Durchaus....
Ich kann mir solche IF Monster kaum anschauen...
Sehen ein bisschen wie gebrauchte Unterhosen aus. In diesem Fall auch 
noch "fremder" Leute Unterhosen.

Da solche IF Monster auch gerne in Rudeln vorkommen, könne man da evtl. 
schon ansetzen um die Sache übersichtlicher zu machen. Z.B. benannte 
Zustände einführen.

von Bernd K. (prof7bit)


Lesenswert?

Jörg W. schrieb:
> Wenn jedoch wirklich was daran liegt zu ergründen, was da passiert,
> dann wird nichts umhin führen, den Code anzugucken.

oder mit -Og im Debugger durchzusteppen wenn mans beim Durchsteppen im 
Kopf partout nicht sieht (man sieht es nicht weil man dabei den selben 
Denkfehler macht den man bereits beim Schreiben gemacht hat).

von Dennis K. (scarfaceno1)


Lesenswert?

Guten Morgen,

ich war übers Wochenende nicht am PC und demnach sehe ich auch eben erst 
die vielen Antworten.

Erstmal vielen Dank dafür.

@ Stefan Us
Die Optimierung einzuschalten ist für mich keine Option, da der Code 
dann absolut nicht mehr in den Controller passt.

@Freshman goes on air
Das ist ein interessanter Ansatz, allerdings erklärt das nicht den 
Zustand, dass die Variable bei " = Aus" und " = Ein" im Debugger den 
selben Wert hat.

Jörg W. schrieb:
> U. C. schrieb:
>> Eindeutig: Ja!
>
> Keineswegs so eindeutig.
>
> Wenn es so eindeutig gewesen wäre, dann hätte das lokale Deaktivieren
> der Optimierung (per "volatile") genauso helfen müssen.  Hat es aber
> laut TE nicht, und seither haben wir von ihm nichts mehr gehört.

Dann lass ich mal was von mir hören. Das Problem für mein Verständnis 
ist, dass die Variable Meldung2 genau das richtige Verhalten aufweist 
und bei Aus auf 0 geht, bei Ein auf 1. Dieses Verhalten hätte ich eben 
von der Variablen Meldung auch erwartet.

U. C. schrieb:
> Jörg W. schrieb:
>> Aber siehe oben, solange der TE sich nicht mehr meldet, ist ihm nicht
>> viel zu helfen.
> Vertrieben?

Mich vertreibt man nicht so schnell.. Bin hier im Forum schon unsanfter 
behandelt worden. ;-)

U. C. schrieb:
> Da solche IF Monster auch gerne in Rudeln vorkommen, könne man da evtl.
> schon ansetzen um die Sache übersichtlicher zu machen. Z.B. benannte
> Zustände einführen.

Der Code ist wirklich riesig. Und viele der if-Abfragen sind schon 
zusammengefasste Zustände.Ich habe den Code von meinem Vorgänger 
übernommen und kaue mich hier Stück für Stück durch...

Ich werde zunächst die Sache mit dem '1' testen.

Danke nochmal.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis K. schrieb:
> Dieses Verhalten hätte ich eben von der Variablen Meldung auch erwartet.

Kannst du denn eine einzelne Funktion compilierfähig extrahieren,
damit man sich mal den vom Compiler generierten Code selbst ansehen
kann?

von Dennis K. (scarfaceno1)


Lesenswert?

Die einzelne Funktion umfasst knapp 600 Zeilen Code.

Soll ich das mal probieren?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Dennis K. schrieb:
> Beim durchsteppen ist mir zunächst aufgefallen, dass Variable Meldung
> gar nicht den Wert 0 annimmt, wenn sie auf Aus gesetzt wird, sondern sie
> steht bei -11.
Ein amoklaufender Pointer also...
Was ist denn vor und nach diesen Variablen deklariert?

Dennis K. schrieb:
> Der Code ist wirklich riesig.
Und wenn dann alle Variabeln so nichtssagende Namen wie "Zeichenkette" 
haben, dann macht das die Sache nicht einfacher...

> Ich werde zunächst die Sache mit dem '1' testen.
Warum? Was versprichst du dir davon?
Wenn du unbedingt was probieren willst, dann "probier" eher mal sowas:
int Meldung, Meldung2;
Oder sowas:
#define Ein                  ((char)1)
#define Aus                  ((char)0)


Dennis K. schrieb:
> Wird das einfach falsch dargestellt?
Drehen wir den Spieß mal um: Warum interessiert dich diese Variable?
Welchen Fehler suchst du denn?

von W.A. (Gast)


Lesenswert?

Freshman goes on air schrieb:
> 1 ist kein char '1' dagegen schon.

Beides sind Integer-Typen. Warum sollte
1
Meldung = 1
 irgendetwas mit '1' (i.e. 0x31) zu tun haben?

von Dennis K. (scarfaceno1)


Lesenswert?

Lothar M. schrieb:
>> Beim durchsteppen ist mir zunächst aufgefallen, dass Variable Meldung
>> gar nicht den Wert 0 annimmt, wenn sie auf Aus gesetzt wird, sondern sie
>> steht bei -11.
> Ein amoklaufender Pointer also...
> Was ist denn vor und nach diesen Variablen deklariert?

Davor ist nichts. Es werden eine Reihe von char Variablen deklariert. 
Die Variable, die spinnt steht an 6ter Stelle. Danach noch eine weitere 
char Variable.
Gefolgt von 2 int, 2 float und einer union.

Danach kommen einige if-Abfragen.

Lothar M. schrieb:
>> Der Code ist wirklich riesig.
> Und wenn dann alle Variabeln so nichtssagende Namen wie "Zeichenkette"
> haben, dann macht das die Sache nicht einfacher...

Die heißen in Wahrheit schon anders und sind aussagekräftiger. Der Code, 
der das Problem verursacht ist halt echt groß.
Ich habe es umbenannt, da es mir einfacher erschien.

Lothar M. schrieb:
>> Wird das einfach falsch dargestellt?
> Drehen wir den Spieß mal um: Warum interessiert dich diese Variable?
> Welchen Fehler suchst du denn?

Ich versuche es mal...

Die Funktion nimmt einen Datenatrom auf, der vom Bus kommt. In ASCII 
kommt vom Bus die Zeichenkette DateT und ein Zahlenwert. Die Nachricht 
kommt auch richtig an, jedoch funktioniert die Verarbeitung irgendwie 
nicht richtig. Und ich hatte diese Stelle als Fehlerquelle ausgemacht, 
da mir die sich nicht ändernde Variable vor und nach den beiden Werten 
die hineingeschrieben wurden irgendwie seltsam vorkommt.
Es sollte aufgrund dieser Variable ein Alarm ausgelöst werden. Dieser 
bleibt aber aus.

von Dennis K. (scarfaceno1)


Lesenswert?

So, ich hab den Fehler selbst gefunden.

Die Variable wurde richtig gesetzt.
Auch wenn der Debugger sie falsch angezeigt.
Es war eine Unterfunktion, deren Inhalt auskommentiert wurde.

Es geht. Vielen Dank für eure Mühe.

von dfIas (Gast)


Lesenswert?

Moin,
kenne mich mit AVR speziell zwar nicht aus, aber in allen moderneren 
IDEs gibt es mindestens zwei Schienen zur Code-Erzeugung. Eine zum 
Debuggen mit i. d. R. abgeschalteter Optimierung, damit der Debugger 
seinen Bezug zu Variablen und Sprungzielen, Source-Zeilen etc. behält. 
Für auszuliefernden Code wird dann das an Optimierung eingeschaltet, was 
gewünscht wird (Size, Speed etc.). Debuggen ist zwar meist noch möglich, 
aber u. U. entstehen merkwürdige Darstellungen oder Reaktionen. 
(Funktionen können scheinbar verschwinden, Schleifen linearisiert werden 
u. s. w.)
Das Einfügen eines "volatile" forciert zwar den Erhalt und die 
sukzessive Behandlung einer Variablen, der Code kann durch Optimierungen 
aber dennoch so umgestellt sein, dass dem Debugger der Bezug zwischen 
Instruction-Pointer und Source-Code fehlt, man ggf. "vorbeistept". Aus 
diesem Grunde gehören Optimierungen in so einem Fall schon 
ausgeschaltet! (Was einen aber auf keinen Fall vom genauso gründlichen 
Testen eines Release entbindet.)
Nebenbei halte ich die Einzelabfrage von Elementen der "Zeichenkette" 
für nicht gerade gut lesbar. Dafür gibt es eigentlich strncmp() u. ä.
73

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis K. schrieb:
> Auch wenn der Debugger sie falsch angezeigt.

Klingt dann doch eher nach Bug im Debugger.

Schön, dass du's gefunden hast.

von Bernd K. (prof7bit)


Lesenswert?

Lothar M. schrieb:
> Was ist denn vor und nach diesen Variablen deklariert?

Davor, Danach, danach kannst Du nicht gehen. Der Compiler (bzw. der 
Linker) kann das umsortieren wie er lustig ist.

: Bearbeitet durch User
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.