Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,
ich hab seit 3 Tagen einen Bug gesucht und ihn endlich gefunden. Nur kann ich mir das nich wirklich erklären. Ich hab n Baum in dem zeichenbare Objekte abgelegt sind, jeder Knoten hat ne eigene Matrix für Transformationen (also n ganz normaler Szenegrapgh). Das Problem war nun, das mir beim Aufruf von glDrawElements wilde SIGSEVs um die Ohren geschmissen wurden. Am Ende hat sich herausgestellt, dass ich die Matrix der Knoten nicht initalisiert hatte und diese komplett mit 0en gefüllt war. Normalerweise dürfte bei sowas doch keine SIGSEV kommen, oder irre ich mich da? Ich hab das auch auf nem anderen Rechner mit ner NVIDIA ich hab ne ATI) getestet, da passiert das gleiche, also würd ich ausschließen, das es n Bug in meinem Treiber is. Aber wie lässt sich das sonst erklären?
Registriert: So Aug 08, 2010 08:37 Beiträge: 460
Programmiersprache: C / C++ / Lua
wenn irgendwas in delphi/lazarus nicht initialisiert wurde und man auch nur *versucht* darauf zuzugreifen kriegt man eine access violation = SIGSEV.
Allerdings passiert das nur, wenn man irgendwie versucht auf einen Speicherbereich zuzugreifen, der noch nicht reserviert wurde. Also wenn die Matrix eine normale Variable ist, wundert es mich, da der Speicher dann normalerweise automatisch zugewiesen wird, wenn sie hingegen einen Klasse ist (also im Prinzip ein Pointer), dann wundert es mich nicht ^^.
_________________ offizieller DGL Compliance Beauftragter Never run a changing system! (oder so)
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,
die matrix is ein ganz normales 4x4 arrray of GLfloat. Und das wird beim erstellen des Objekts, welches die Matrix besitzt mit 0en gefüllt. Also kein Objekt. Und genau deshalb bin ja auch etwas verwirt^^
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Sicher dass es aus dem Treiber kam? Wurde in dem SIGSEV explizit die DLLs der OpenGL-Implementation erwähnt? Also bei ATI in der atioglxx.dll. Wenn dein SIGSEV nämlich unabhängig vom Treiber geschieht (also NVidia und ATI), dann liegts eher weniger am Treiber selbst.
Bei solchen Sachen evtl. mal prüfen ob hinter den übergebenen Zeigern auch wirklich steht was erwartet wird, also ob z.B. ein Stride zwischen den Elementen sein muss, oder ob man statt 4x4xDouble 4x4xSingle übergeben hat, etc.
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Also es steh nich 100%tig da, dass es die ati.dll is, aber er bleibt in der Funktion atio6xx!atiPPHSN stehen, also geh ich schon davon aus, das es in der ati.dll ist. Es is definitiv ein 4x4-Arrray of GLfloat und ich hab auch glMultMatrixf benutzt. Wenn ich mir die Werte vom Zeiger ausgeben lass, dann stimmen die auch mit den erwarteten Werten überein, also alles 0 und wenn ich es mit der Einheitsmatrix initialisiere, dann steht die Einheitsmatrix drin.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Mal so ne Frage am Rande : Meinst du wirklich glDrawElements? Das bekommt ja garkeine Matrizen rein, sondern Indizes. Oder sprichst du von einer anderen Funktion?
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Nene ich mein glDrawElements. Da knallts, wenn ich vorher ne 0-Matrix mit glMultMatrix geladen hab. Hier mal der Code, is zwar jetzt bisl aus'm Zusammenhang rausgerissen, aber ich denke es is alles Wichtige dabei. Wenn nich einfach fragen, dann schieb ich den noch nach...
Code:
function TgeoModelNode.GetPosPtr: PgluMatrix4f;
begin
result :=@fPosition[0,0];//TgluMatrix4f = array[0..3] of TGLVectorf4
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Unabhängig davon habe ich schon die lustigsten Effekte gesehen (inklusive random crashes) wenn man uninitialisierte Daten an die Grafikkarte gibt. So abwegig finde ich das jetzt nicht . Wobei es bei matrizen wirklich schräg ist, da würde ich eher eine SIGFPE erwarten, weil die w-Komponente 0 wird.
grüße
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,
@Sascha Willems: das PosPtr ist ein Property. Das hab ich so gemacht, weil ich den Zeiger auch außerhalb des Objekts benötige. Ich hab das natürlich auch direkt mit @fPosition[0,0] probiert, da passiert aber nix anderes. Eig sollte nix anderes sein, wenn ich das über das Property mach, is ja am Ende der gleiche Zeiger. Den Cast hab ich nur drin, das weil der Kompiler da ein Pointer erwartet, aber das Property ein PgluMatrix4f ist.
@Lord Horazont: nen ähnlichen Gedankengang hatte ich auch. Ne SIGPEV wäre ja wenigstens noch halbwegs sinnvoll^^
Registriert: Mi Jan 31, 2007 18:32 Beiträge: 150
Programmiersprache: Pascal
Habe was ähnliches schon bei Shadern festellen können wenn man dort Konstanten hat, die soweit meine Vermutung zutrifft zu einer Division durch 0 bei der Optimierung führen liefert das ganze ein SIGSEV. PS: FPC hat probleme exceptions aus dlls in der Host Anwendung richtig wieder zu geben wenn FPC die Exception nicht richtig verarbeiten kann wird das ganze einfach als SIGSEV weiter gegeben. (zumindest im aktuellen repo stand 2.7.1)
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2622 Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich hab da auch mal ne Frage. Benutzt du mehr als 1 Thread ? Wenn ja, was passiert, wenn du in die loops sleep(0) einbaust. Was ich in der Vergangenheit beobachten konnte, waren Signals, die mein Programm zum crashen brachten und es an stellen stehen blieb, wo es einfach kein Sinn gemacht hat. Als ich dann mein Code mit zwangs unterbrechung versehen hab, z.b. sleep, waitobject, HeapAlloc und einige andere Funktionen, dann crashte es an ganz anderer Stelle und das war dann ein Anzeichen, dass in meinem Code ein FPU oder Speicherfehler programmiert war, der durch Mutlithreading auf tritt und gleichzeitig verschleiert.
Wie kann das passieren ? Wenn ein Thread arbeitet und dann mist baut, dann kommt das Signal nicht direkt sondern zieht sich. Ein Beispiel wäre folgendes. ThreadA erzeugt eine Matrix und übergibt sie an ThreadB zur nutzung, ThreadB greift auf die Daten zu und ruft nun ein OpenGL call auf, während ThreadA nun die Matrix weg räumt, weil der Scopeende erreicht ist. Nun wird der OpenGL Treiber mit SIGSEV reagieren, denn der Kernel verbietet den Zugriff auf den gerade gesäuberten Speicher. Es sieht also so aus, als ob der Treiber nen ding an der Klatsche hat aber eigentlisch war es ThreadA und da der Code sich mit seinen Exit-Points nicht ändert, wird in der Regel immer das gleiche resultat kommen, bis mal die CPU völlig ausgelastet ist oder man mal ein neuen Exit-Point rein bringt(sleep(random(0,100));).
Ein noch fieserer Fall wäre, wenn durch async. Funktion sogar falsche Orte angezeigt werden. Der OpenGL treiber sammelt die Befehle vom Client und arbeitet sie im Hintergrund ab und irgendwann kommt er zur gesäuberten Matrix, crashed und beim nächsten call wird dieser dann SIGSEV durch reichen, obwohl der aktuelle Call garnicht das Problem war. Hier spielt dann das Signal handling und die Sichtbarkeit von Ring0 priviligierten Treibern eine Rolle.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,
der Fehler is wieder da -.-
@TAK: das Rendern selbst läuft komplett im MainThread. Ich hab hier und da nen Thread um die Daten von der Platte zu lesen, da kommt dann ein Resourcen-Objekt raus, das im MainThread initialisiert wird (Textur generieren, VBO Daten auf die Graka packen, ...). An ein MemLeak hab ich auch schon gedacht, aber mir fällt grad keine sinnvolle Stelle ein wo man da Suchen könnte. Die von dir beschriebenen Szenarien treffen auf mein Programm eig. nicht zu. Ich hab aber noch was seltsames rausgefunden. Es arbeitet alles ohne Probleme (also zumindest schmiert es nich ab) solange ich keine Punkte render?! Ich hab die Zeilen 29-44 (Code siehe oben) mal folgendermaßen geändert:
Code:
glPushAttrib(
GL_COLOR_BUFFER_BIT or
GL_CURRENT_BIT or
GL_DEPTH_BUFFER_BIT or
GL_ENABLE_BIT or
GL_FOG_BIT or
GL_LIGHTING_BIT or
GL_LINE_BIT or
GL_POINT_BIT or
GL_POLYGON_BIT or
GL_TEXTURE_BIT or
GL_TRANSFORM_BIT);
//Surface.Bind(aRenderArgs);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glPolygonMode(GL_FRONT, GL_POINTS);
Mesh.Render;//crash bei glDrawElements (Zeile 72, siehe oben)
glUseProgram(0);
glPopAttrib();
ein anderer Versuch:
Code:
glPushAttrib(
GL_COLOR_BUFFER_BIT or
GL_CURRENT_BIT or
GL_DEPTH_BUFFER_BIT or
GL_ENABLE_BIT or
GL_FOG_BIT or
GL_LIGHTING_BIT or
GL_LINE_BIT or
GL_POINT_BIT or
GL_POLYGON_BIT or
GL_TEXTURE_BIT or
GL_TRANSFORM_BIT);
glBegin(GL_POINTS);
glVertex3f(1,1,1);
glVertex3f(1,1,-1);
glVertex3f(1,-1,1);
glVertex3f(-1,1,1);
glEnd;
glUseProgram(0);//crasht hier
glPopAttrib();
noch ein Versuch:
Code:
//crasht nicht, aber zeichnet auch keine Punkte, sondern FILL?!
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glPolygonMode(GL_FRONT, GL_POINTS);
glPointSize(1);
Mesh.Render;
irgendwas is hier mächtig fault
€: wenn ich das Projekt als 32bit exe kompiliere gehts... Is das vlt irgendwo ein Datentyp zu groß? Aber eig sollten die Typen aus der dglOpenGL doch stimmen, oder? Und selbst wenn nicht, der einzige Datentypen die Architekturabhängig sind, sind Pointer, PtrInt und PtrUint (zumindest soweit ich weiß).
Mitglieder in diesem Forum: 0 Mitglieder und 15 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.