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?
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“.
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.
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.
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.....
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.
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.
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.
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....
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.
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.
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.
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).
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.
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?
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?
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.
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.
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
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.