Wie ist euer Fehlersystem aufgebaut?
-
Es ist jetzt viel gesagt worden über alle möglichen Fehler und wie man als Programmentwickler damit umgehen soll. Es zeigen sich dabei auch unterschiedliche Programmierstile. Alle diese Programmierstile sind gerechtfertigt, wenn sie dem Ziel 'stabiles Programm' dienen.
Grundsätzlich: Der Anwender hat damit nichts zu tun - er schreit wenn etwas nicht läuft wie er erwartet, fragt dann den Programmentwickler und fordert Abhilfe. Das ist sein gutes Recht, wenn er für die Software bezahlt hat oder für die Programmpflege weiter bezahlt.
Also ist in jedem Fall der Programmentwickler gefragt. ER muss wissen, wie man Fehler möglichst vermeidet und wenn sie auftreten geeignete Methoden haben, wie man sie findet und schnell behebt. Das gehört zu jeder professionellen Programmierung notwendig dazu. Fehler können schliesslich Geld kosten!
Ich denke z.B. an die Software für ein Walzwerk, wo Stahlbleche mit vorgeschriebener Dicke gefordert sind. Weicht diese Dicke vom Kundenauftrag ab, so ist die Produktion der Stahlbleche mit erheblichen Folgekosten im Eimer. In anderen Branchen gibt es ähnliches.
Das Thema ist und bleibt in der Softwarentwicklung aktuell. Da kommt niemand drum herum!
-
Bitte ein Bit schrieb:
Deswegen ziehe ich eher das Konzept des Exception Handling vor. Man kann dann im Fehlerfall immer noch entscheiden ob man das Program sauber (!!!) terminieren/herunterfahren will oder ob man mit dem Fehler (mit Hilfe einer Fehlerkorrektur) leben kann.
Zu versuchen ein Programm sauber zu beenden, wenn man nicht sicher sein kann welche Invarianten alle schon verletzt sind, ist ein Glücksspiel. Und mMn. der ganz falsche Weg.
Log-Eintrag schreiben, Crash-Dump schreiben, Prozess killen.
-
hustbaer schrieb:
Zu versuchen ein Programm sauber zu beenden, wenn man nicht sicher sein kann welche Invarianten alle schon verletzt sind, ist ein Glücksspiel. Und mMn. der ganz falsche Weg.
Log-Eintrag schreiben, Crash-Dump schreiben, Prozess killen.ACK!
-
*hustbaer den Begriff Korrektheit zuspielen*
-
Zeus schrieb:
*hustbaer den Begriff Korrektheit zuspielen*
JA!
Es fehlt aber noch eine weitere schwer zu findende Fehlermöglichkeit: Das Programm läuft anstandslos durch ohne irgendwelche Verletzungen und ohne Crash, nur es erzeugt falsche Ergebnisse. Irgendwo in der vorher durchlaufenen Kette von Bearbeitungsschritten ist vielleicht mit einem falschen - aber zulässigen - Index etwas anderes als erwartet zugewiesen worden. Gerade diese Fehler sind äusserst schwer aufzudecken. Klingt banal, doch kann verhehrende Wirkung haben. So hat einmal ein von mir entwickeltes Programm zur Trassierung von Eisenbahn-Neubaustrecken in einer besonderen Situation 10 cm zu wenig Schotter unter einem Gleis berechnet. Erst der Mann auf der Schottermaschine auf der Neubaustrecke hat diesen Fehler bemerkt und Alarm geschlagen. Im Programm war nur eine Zeile falsch.
Ich ergänze diesen Hinweis, um zu zeigen dass ein Programmentwickler mit einer Vielzahl von Fehlermöglichkeiten rechnen und darauf eingestellt sein muss, auch mit solchen die hier noch nicht genannt worden sind.
-
Alles klar.
Ich glaube das jeder, der nicht einen probabilistischen Algorithmus programmmiert, und auf indeterministischen Daten arbeitet, seinen Sachen packen und von der Informatik einen Bogen machen sollte.
@Martin:
Ich glaube wir reden hier gewaltig aneinander vorbei.Ich verstehe einfach deinen Spruch "Lieber deine Software crashen lassen als eine Fehlermeldung!" nicht. Denn meines Erachtens kommt es immer auf den Fehlertyp an.
Ich probiere es daher nochmal mit Code-Beispielen mit unterschiedlichen Fehlerbehandlungen:
Beispiel 1:
// Annahme: Kein Name ist länger als 256 Zeichen void DoSomething(const CHAR* Name) { CHAR MyName[256] = {0}; ... sprintf(MyName, Name); }
Beispiel 2:
// Annahme: Kein Name ist länger als 256 Zeichen bool DoSomething(const CHAR* Name) { CHAR MyName[256] = {0}; ... if ((strlen(Name) + 1) > sizeof(MyName)) { MessageBox(NULL, "Fehler 100: Namen mit mehr als 256 Zeichen werden nicht unterstützt!", "ABC", MB_OK); // throw MyOverflowException(...) return false; } sprintf(MyName, Name); }
Beispiel 3:
// Annahme: Kein Name ist länger als 256 Zeichen void DoSomething(const CHAR* Name) { CHAR MyName[256] = {0}; ... _snprintf(MyName, sizeof(MyName), Name); }
Was ist deines Erachtens die bessere Lösung ?
Beispiel 1 stürzt im Spezialfall ab und stellt unter Umständen ein Sicherheitloch da. Die anderen Beispiele stürzen nicht ab, können aber trotzdem ein Fehlverhalten erzeugen wenn beispielsweise der Speicher MyName nur 16 Zeichen groß ist.
Interresanterweise ist bei gewissen Regelungen über Abrechnungen (vom Bundesamt bzw. von der DIN Stelle) nur Codebeispiel 2 (vielleicht auch noch 3) korrekt. Dort wird klar definiert: Ein Name ist exakt 8 Zeichen groß. Peng ! Und wenn ein Benutzer einen längeren Namen hat, hat er Pech gehabt.
Etwas möchte ich aber noch festhalten. Wenn bei meinem Programmen ein "harter" Fehler auftaucht, dann stürzt auch meine Software ab. Und ja, ich gebe es jat zu, bei einigen Befehle der WinAPI schaue ich nicht auf den Rückgabewert. Die Befehle erwiesen sich, bitte alle Windows-Trolle mal weghören, als (einigermaßen) stabil und fehlerfrei.
Ansonsten gebe ich berniebutt Recht:
Es ist jetzt viel gesagt worden über alle möglichen Fehler und wie man als Programmentwickler damit umgehen soll. Es zeigen sich dabei auch unterschiedliche Programmierstile. Alle diese Programmierstile sind gerechtfertigt, wenn sie dem Ziel 'stabiles Programm' dienen.@berniebutt:
Ich lernte erst den Begriff Testreihe auf der Arbeit schätzen weil man damit einigermaßen sicherstellen kann das vorgenommene Änderungen am Program keine anderen Ergebnisse liefern.
-
Bitte ein Bit schrieb:
Alles klar.
Ich glaube das jeder, der nicht einen probabilistischen Algorithmus programmmiert, und auf indeterministischen Daten arbeitet, seinen Sachen packen und von der Informatik einen Bogen machen sollte.
Kannst du das ganze nochmal so schreiben dass ich verstehen kann was du mir damit sagen willst?
-
hustbaer schrieb:
Bitte ein Bit schrieb:
Alles klar.
Ich glaube das jeder, der nicht einen probabilistischen Algorithmus programmmiert, und auf indeterministischen Daten arbeitet, seinen Sachen packen und von der Informatik einen Bogen machen sollte.
Kannst du das ganze nochmal so schreiben dass ich verstehen kann was du mir damit sagen willst?
Ist doch egal, ob du oder ich das verstehen. Er ist oder wird als Informatiker Chefentwickler und macht dann seine Vorgaben für andere, die das umsetzen sollen!
Sobald er in dieser Position angelangt ist, deckelt er einfach seine Programmierer.
-
hustbaer schrieb:
Bitte ein Bit schrieb:
Alles klar.
Ich glaube das jeder, der nicht einen probabilistischen Algorithmus programmmiert, und auf indeterministischen Daten arbeitet, seinen Sachen packen und von der Informatik einen Bogen machen sollte.
Kannst du das ganze nochmal so schreiben dass ich verstehen kann was du mir damit sagen willst?
Du weist nicht was du hast + Du weisst nicht wie du etwas tun willst = Was ist das Ergebnis? berniebutt sowas programmierst du - Du muss viel Spaß haben!!
-
@berniebutt und hustbaer
Tut mir leid, ich wollte hier nicht arrogant erscheinen.Bloß was mich ein wenig störte war, das es mir so rüber kommt als es gibt nur eine Art von Fehlerbehandlung: Log-Eintrag schreiben, Crash-Dump schreiben, Prozess killen und sonst nix. Und als ich dann eine Alternative aufbot, da wurde mir unterstellt, da müsse man ja auf korrupten Daten arbeiten. Und das empfand ich als leicht beleidigend.
Denn da suchte man wieder in den Krümeln nach Fehlern und schoss mit Spatzen auf Kanonen.
Und genau deswegen reagierte ich auch so mit dem Spruch das Leute welche mit zerschossenen Daten arbeiten eigentlich nix in der Informatik zu suchen hätten. Es macht doch Null Sinn etwas Zerschossenes retten wollen und dementsprechend fand ich auch den Kommentar dazu sinnlos. Aber in vielen Fällen kann man diesen Fall schon vorher abfangen und dementsprechend darauf reagieren so wie es ein Exe Kompilat schon automatisch tut, wenn es eine benötigte DLL nicht findet. Aber ich fürchte das will hier keiner sehen.
So ich beende jetzt die Diskussion bevor das Ganze noch in einem Flamewar endet.
-
Bitte ein Bit schrieb:
Beispiel 2:
// Annahme: Kein Name ist länger als 256 Zeichen bool DoSomething(const CHAR* Name) { CHAR MyName[256] = {0}; ... if ((strlen(Name) + 1) > sizeof(MyName)) { MessageBox(NULL, "Fehler 100: Namen mit mehr als 256 Zeichen werden nicht unterstützt!", "ABC", MB_OK); // throw MyOverflowException(...) return false; } sprintf(MyName, Name); }
Interresanterweise ist bei gewissen Regelungen über Abrechnungen (vom Bundesamt bzw. von der DIN Stelle) nur Codebeispiel 2 (vielleicht auch noch 3) korrekt.
strlen,... sucht das nicht auch nach einer nullterminierung?