Debug- Problem
-
Liebe Forumsbesucher,
ich häng' an einem blöden Debug- Problem, wo ein Fehler nur extrem selten auftritt:
In einer Datei sind 3D- Vektoren (so 10k bis 50 k), die im Analyseteil sequentiell untersucht, zwischenzeitlich auf den Heap gestapelt und mit Zusatzinformationen versehen zurückgeschrieben werden.
Ein anderer Programmteil liest dann diese Datei und überprüft sie im separaten Durchlauf auf Plausibilität.
Seit ich die Analyse um eine Kleinigkeit erweitert habe, meckert die Plausibilitätskontrolle, völlig zu recht übrigens aus gut 16'000 Datensätzen drei als fehlerhaft an.
Das Problem ist nun, die Stelle zu finden, an der der Fehler produziert wird. Dabei ist hinderlich, daß redundante Vektoren aussortiert werden, d.h., im Output sind weniger Vektoren als im Input, ich kriege also nur ungefähr die Stelle in der Originaldatei, die falsch behandelt wird. Und um die Sache lustig zu machen, liegen an diesen ungefähren Stellen immer ein paar hundert Vektoren auf dem Heap- Stapel, also für den Debugger nicht so ohne weiteres auslesbar.Alle "Fallen", die ich bisher ausgelegt habe, um den Fehler beim Entstehen zu erwischen, haben nicht zugeschnappt.
Jetzt gibt's natürlich noch die "harte Tour", jedem Input- Vektor eine ID zu verpassen, die ich aber bei nahezu allen Funktionen bis hin zur Endkontrolle durchschleifen müßte, um den "bösen Buben" zu finden. Ist erstmal viel Schreibarbeit, eine prima Möglichkeit, neue Fehler einzubauen und müßte rückgebaut werden, um es wieder in das Produktivsystem einzupassen (ja, ich weiß, VCS und branching machen das leichter, müßte ich aber auch erstmal einrichten).Also, ich mach' mich erstmal ans Auslegen weiterer Fallen und wenn euch in der Zwischenzeit nichts Elegantes eingefallen ist, werd' ich wohl um die ID- Geschichte nicht herumkommen.
-
Ich habe Dein Problem aufgrund der Beschreibung vielleicht noch nicht so ganz durchdrungen, aber hast Du mal überlegt, im Falle eines Fehlers ein Laufzeit-Assert auszulösen? Daran kannst Du dann auch den Debugger aufhängen.
-
du könntest z.b. in der plausibilitätskontrolle einen breakpoint setzen und dir genau angucken warum sie gewisse werte nicht haben will, die eigentlich OK sind. wenn das ausfiltern der reduntanten einträge das debuggen erschwert, dann schmeiss den 'rausschmeisser' temporär raus. wenn dein code modular aufgebaut ist, wovon ich ausgehe, dann sollte das einfach zu machen sein.
-
~fricky schrieb:
du könntest z.b. in der plausibilitätskontrolle einen breakpoint setzen und dir genau angucken warum sie gewisse werte nicht haben will, die eigentlich OK sind.
Nein, die Werte sind ja wirklich falsch (s.o.), ist ja schon rausgetriggert, der 1109. Datensatz ist der erste Fall.
Wenn ich bei der Analyse auf den 1100 (edit: quatsch, der 1110). Datensatz triggere, liegen so knapp 400 Vektoren auf dem Heap. Ich werd' mal rausfinden müssen, wieviele Elemente der Rausschmeißer getilgt hat, um rauszufinden, ob da das "böse" Teil mit dabei ist.~fricky schrieb:
wenn das ausfiltern der reduntanten einträge das debuggen erschwert, dann schmeiss den 'rausschmeisser' temporär raus.
Ungünstig, denn ich errechne aus den Vektoren die Beträge, die für die Skalierung der Zusatzinformtion zuständig sind. Ein redundanter Vektor hat den skalaren Betrag 0, was an etlichen Stellen zur div-0- Exception führen würde. Ich darf den Analysator per Definition damit nicht füttern.
Bin jetzt am Schwanken, ob es schneller ist, mal einen Heapdump zu implementieren, weiter mit Fallenstellen zu experimentieren oder echt die ID durchzuziehen ...
-
Tachyon schrieb:
Ich habe Dein Problem aufgrund der Beschreibung vielleicht noch nicht so ganz durchdrungen, aber hast Du mal überlegt, im Falle eines Fehlers ein Laufzeit-Assert auszulösen? Daran kannst Du dann auch den Debugger aufhängen.
Was ist ein Laufzeit- Assert?
Das Problem ist, daß ich erst hinterher, wenn die Beziehung zum Input bereits gestört ist, den Fehler detektiere. Ich muß aber die Stelle finden, an der der Input falsch bearbeitet wurde, was ja vorher stattfand.Meine "Fallen" sind ja nur abgeänderte Prüfungen der Bedingung, die zuletzt moniert wurde. Ist halt mühselig, weil die Vektoren je nach Programmecke in unterschiedlichen Formaten vorliegen (relativ, absolut, Raumwinkel/Betrag usw.) ...
-
pointercrash() schrieb:
~fricky schrieb:
du könntest z.b. in der plausibilitätskontrolle einen breakpoint setzen und dir genau angucken warum sie gewisse werte nicht haben will, die eigentlich OK sind.
Nein, die Werte sind ja wirklich falsch (s.o.)
ach, dann hab ich das falsch verstanden.
du könntest z.b die quelltexte der fehlerhaften version mit der letzten, noch funktionierenden vergleichen. wenn nicht zu viele änderungen zwischenzeitlich passiert sind, reicht oft ein scharfer blick. ist vielleicht erstmal eine idee, bevor du unmengen an debug-code einbaust.
-
~fricky schrieb:
du könntest z.b die quelltexte der fehlerhaften version mit der letzten, noch funktionierenden vergleichen. wenn nicht zu viele änderungen zwischenzeitlich passiert sind, reicht oft ein scharfer blick.
Als naturfauler Mensch hatte ich das schon.
Ich kommentiere so sechzig Zeilen aus und das Ding rennt wie zuvor. Die 60 Zeilen unterscheiden nur einen geometrischen Fall und erzeugen optimistischere Zusatzinformationen. Rein logisch hätte die Macke ja auch früher auftreten müssen, weil ich mich im gleichen Wertebereich bewege.Wie auch immer, gerade ist eine Falle zugeschnappt und ich glaube, ich hab' jetzt das richtige Schweinchen (1111 Elemente eingelesen, das 1005. ist es wohl, d.h. der Rausschmeißer hat die restlichen gekillt). Mal sehen, ob der Blödsinn passiert, bevor ich den Vektor auf den Heap kippe oder erst, wenn ich's von da wieder runterziehe.
Zumindest mal ein Ansatzpunkt (dödel da schon ewig hin ...
)
-
Hmmm,
also ich hab' jetzt die Stelle, wo's schiefgeht, auch das warum, mich wundert jetzt nur noch, warum's vorher überhaupt (und immer) funktioniert hat
Allerdings bin ich jetzt so durch den Wind, daß ich mich ernsthaft ein paar Minuten lang gefragt habe, warum das hier bei jedem Durchlauf t_var dekrementiert:
if ((turnspeed == 97) && t_var); t_var--;
Jedem bemühten Mithelfer sei versichert, daß mir das nunmehr klar ist, genauso wie der Umstand, daß ich für heute mit 'ner Abschußhalben ins Land Matratzien umsiedeln sollte.
-
pointercrash() schrieb:
Allerdings bin ich jetzt so durch den Wind, daß ich mich ernsthaft ein paar Minuten lang gefragt habe, warum das hier bei jedem Durchlauf t_var dekrementiert:
if ((turnspeed == 97) && t_var); t_var--;
jag deinen code mal durch: http://www.splint.org/
der findet bestimmt noch mehr.