AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!
Thema durchsuchen
Ansicht
Themen-Optionen

Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

Ein Thema von berens · begonnen am 19. Aug 2013 · letzter Beitrag vom 20. Aug 2013
Antwort Antwort
Seite 1 von 3  1 23      
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#1

Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 19. Aug 2013, 16:38
Delphi-Version: 2007
Hallo mal wieder.

Ich bin mit meinem Latei mal wieder komplett am Ende, und selbst die SuFu oder Google liefern mir hier noch nicht mal mehr Ansätze.

Ich habe hier (m)ein Programm, das aus einer Datenbank über einen Thread Werte lädt, diese mittels Synchronize() an eine Komponente aus dem Hauptformular übergibt und dann weiterverarbeitet wird. Das klappt alles 100% zuverlässig und störungsfrei.

Nun ergibt sich aber das Problem, dass, sobald ich/der Benutzer etwas in ein TEdit oder TMemo eingibt, und (nach wilden rumtippseln auf der Tastatur) dann Leertaste drücke, eine Exception kommt. Alle TEdit/TMemo Objekte haben kein On-Ereignis hinterlegt. Alle Formulare haben KeyPreview auf "False". Es scheint so, als ob beim Drücken der Leertaste Delphi/Windows intern "Application.ProcessMessages" aufruft (siehe Stack weiter unten) und dann irgendwas im Hintergrund schafft.

Ich vermute ja fast, dass Delphi alle Nachfahren von TObject, die momentan als Variable in meinem Programm/Speicher vorhanden sind benachrichtigt, dass der Hotkey "Leertaste" gedrückt wurde. Interessiert zwar keine einzige Komponente, aber egal. Während die Liste (wo nimmt er die her?) mit allen Komponenten durchgeht, wird wohl eine Komponente aus der Liste gelöscht, und es kommt zu der Exception. Meine Vermutung.

Der Thread löscht keine Komponenten aus dem Hauptprogramm. Beim Debuggen wird mir beim Anklicken aller Threads nacheinander bei "Thread-Status" auch kein Thread angezeigt, in dem aktuell mein Quelltext läuft oder sonst irgendwie etwas gelöscht wird (es gibt ja immer mehrere "leere" Threads beim Debuggen wo nur "WaitForSingleObject" o.ä. als einziger Stackbefehl zu sehen ist). Der VCL/Main Thread ist idle und durchläuft zu diesem Zeitpunkt keine Prozeduren von mir.

Ich verwende außer meinen Objekten und den Standard-Komponenten nur ein paar LMD-Panels etc., aber die werden nur bei Programmstart erzeugt. Keine weiteren Threads oder Fremdkomponenten.

Wie bekomme ich denn raus, bei welcher TList der .Get-Befehl fehlgeschlagen ist? Was kann man machen? Kann ich der TApplication die Reaktionen auf Tastatur-Anschläge verbieten (MessageHandler überschreiben, ...)?


Anbei das Log:
Code:
EurekaLog 7.0.6.0 

Exception:
-------------------------------------------------------------
  2.2 Address: 00436D20
  2.5 Type  : EListError
  2.6 Message: Listenindex überschreitet das Maximum (21116).
  2.7 ID    : 60500000
  2.11 Sent : 0

User:
-----------------
  3.2 Name : name
  3.3 Email:

Steps to reproduce:
------------
  8.1 Text:


Call Stack Information:
-------------------------------------------------------------------------------------------------------------------------------------------------
|Methods |Details|Stack  |Address |Module     |Offset |Unit            |Class         |Procedure/Method                        |Line     |
-------------------------------------------------------------------------------------------------------------------------------------------------
|*Exception Thread: ID=4024; Parent=0; Priority=0                                                                                               |
|Class=; Name=MAIN                                                                                                                             |
|DeadLock=0; Wait Chain=                                                                                                                       |
|Comment=                                                                                                                                      |
|-----------------------------------------------------------------------------------------------------------------------------------------------|
|7FFFFFFE|04     |00000000|00436D20|pCRM7.exe  |00036D20|Classes         |TList         |Get                                     |2992[2]  |
|00000020|04     |0018FBA8|00440ABB|pCRM7.exe  |00040ABB|Classes         |TComponent    |GetComponent                            |10673[2] |
|00000020|04     |0018FBB4|005034BF|pCRM7.exe  |001034BF|Forms           |               |DispatchShortCut                        |5997[5]  |
|00000020|04     |0018FBD0|0050356D|pCRM7.exe  |0010356D|Forms           |TCustomForm   |IsShortCut                              |6018[3]  |
|00000020|03     |0018FEB8|75BE6175|USER32.dll |00026175|USER32           |               |SendMessageA                            |          |
|00000020|04     |0018FEDC|005067EB|pCRM7.exe  |001067EB|Forms           |TApplication  |IsKeyMsg                                |8022[24] |
|00000020|04     |0018FF08|00506A49|pCRM7.exe  |00106A49|Forms           |TApplication  |ProcessMessage                          |8097[15] |
|00000020|04     |0018FF20|00506AAE|pCRM7.exe  |00106AAE|Forms           |TApplication  |HandleMessage                           |8124[1]  |
|00000020|04     |0018FF44|00506DA3|pCRM7.exe  |00106DA3|Forms           |TApplication  |Run                                     |8223[20] |
|00000020|04     |0018FF74|006B05B5|pCRM7.exe  |002B05B5|pCRM7            |               |Initialization                          |39[8]    |
|00000020|03     |0018FFD8|77BD9F40|ntdll.dll  |00039F40|ntdll           |               |(possible RtlInitializeExceptionChain+49)|          |
|-----------------------------------------------------------------------------------------------------------------------------------------------|
|                                                                                                                                               |
|Running Thread: ID=5216; Parent=4024; Priority=0                                                                                               |
|Class=TLoadSaveThread; Name= (uLoadSave.TLoadSaveThread.Execute)                                                                              |
|DeadLock=0; Wait Chain=thread: [ 1460 / 5216 ] is blocked                                                                                     |
|Comment=                                                                                                                                      |
|-----------------------------------------------------------------------------------------------------------------------------------------------|
|7FFFFFFE|03     |00000000|77BBF8D1|ntdll.dll  |0001F8D1|ntdll           |               |ZwWaitForSingleObject                   |          |
|00000020|03     |03F3F984|766F118F|kernel32.dll|0001118F|kernel32         |               |WaitForSingleObjectEx                   |          |
|00000020|03     |03F3F99C|766F1143|kernel32.dll|00011143|kernel32         |               |WaitForSingleObject                     |          |
|00000020|04     |03F3F9B0|0044028F|pCRM7.exe  |0004028F|Classes         |TThread       |Synchronize                             |10168[34] |
|00000020|04     |03F3FA00|00440336|pCRM7.exe  |00040336|Classes         |TThread       |Synchronize                             |10196[4] |
|00000020|04     |03F3FA08|006942DE|pCRM7.exe  |002942DE|uLoadSave       |TLoadSaveThread|Execute                                 |1157[644] |
|00000020|04     |03F3FE64|004DE045|pCRM7.exe  |000DE045|EAppMultiThreaded|               |ThreadExecuteSafeWrapper                |64[11]   |
|00000020|04     |03F3FEA8|0043FE10|pCRM7.exe  |0003FE10|Classes         |               |ThreadProc                              |9877[7]  |
|00000020|04     |03F3FED8|00405334|pCRM7.exe  |00005334|System          |               |ThreadWrapper                           |12110[33] |
|00000020|04     |03F3FEEC|004DE21E|pCRM7.exe  |000DE21E|EAppMultiThreaded|               |ThreadProcHandler                       |137[13]  |
|00000020|04     |03F3FF34|004C2607|pCRM7.exe  |000C2607|EExceptionManager|               |DefaultThreadHandleException            |2850[3]  |
|00000020|04     |03F3FF78|0049D8C3|pCRM7.exe  |0009D8C3|EThreadsManager |               |ThreadWrapper                           |611[11]  |
|00000020|03     |03F3FF8C|766F33A8|kernel32.dll|000133A8|kernel32         |               |BaseThreadInitThunk                     |          |
|7FFFFFFE|04     |00000000|0069135B|pCRM7.exe  |0029135B|uLoadSave       |TLoadSaveThread|Create                                  |121[3]   |
-------------------------------------------------------------------------------------------------------------------------------------------------

Processes Information:
----------------------


Assembler Information:
-----------------------------------------------------------
; Classes.TList.Get (Line=2991 - Offset=9)
; ----------------------------------------
00436D15  add    eax, +$7C08733B
;
; Line=2991 - Offset=14
; ---------------------
00436D1A jnp    +$6C414415
;
; Line=2992 - Offset=20
; ---------------------
00436D20  add    [ebx+$E8038BCE], cl      ; <-- EXCEPTION
;
; Line=2992 - Offset=26
; ---------------------
00436D26  push   ds
;
; Line=2992 - Offset=27
; ---------------------
00436D27  DB     $FF, $FF //     
;
; Line=2992 - Offset=29
; ---------------------
00436D29  dec    dword ptr [ebx+$48B0443]
;
; Line=2993 - Offset=35
; ---------------------
00436D2F mov    al, $5E
;
; Line=2994 - Offset=37
; ---------------------
00436D31  pop    ebx
;
; Line=2994 - Offset=38
; ---------------------
00436D32  ret

Registers:
-----------------------------
EAX: 0018FAC4   EDI: 00000001
EBX: 00000000   ESI: 0EEDFADE
ECX: 00000007   EBP: 0018FB14
EDX: 00000000   ESP: 0018FAC4
EIP: 7583C41F  FLG: 00000212
EXP: 00436D20   STK: 0018FB9C

Stack:              Memory Dump:
------------------   ---------------------------------------------------------------------------
0018FBD8: 00000000   00436D20: 00 8B CE 8B 03 E8 1E FF FF FF 8B 43 04 8B 04 B0  ...........C....
0018FBD4: 0018FBEC  00436D30: 5E 5B C3 90 8B 50 0C 83 FA 40 7E 0E 8B CA 85 C9  ^[...P...@~.....
0018FBD0: 00503572   00436D40: 79 03 83 C1 03 C1 F9 02 EB 11 83 FA 08 7E 07 B9  y............~..
0018FBCC: 0018FBEC  00436D50: 10 00 00 00 EB 05 B9 04 00 00 00 03 CA 8B D1 E8  ................
0018FBC8: 02742020   00436D60: 64 01 00 00 C3 8D 40 00 53 33 C9 EB 01 41 3B 48  d.....@.S3...A;H
0018FBC4: 00000018   00436D70: 08 7D 08 8B 58 04 3B 14 8B 75 F2 3B 48 08 75 03  .}..X.;..u.;H.u.
0018FBC0: 02742020   00436D80: 83 C9 FF 8B C1 5B C3 90 53 56 57 8B F9 8B F2 8B .....[..SVW.....
0018FBBC: 00503514   00436D90: D8 85 F6 7C 05 3B 73 08 7E 0F 8B 15 44 41 6C 00  ...|.;s.~...DAl.
0018FBB8: 00000000   00436DA0: 8B CE 8B 03 E8 9F FE FF FF 8B 43 08 3B 43 0C 75  ..........C.;C.u
0018FBB4: 005034C4   00436DB0: 06 8B C3 8B 10 FF 12 8B 43 08 3B F0 7D 1A 2B C6  ........C.;.}.+.
0018FBB0: 0ABF0580   00436DC0: 8B C8 03 C9 03 C9 8B 43 04 8D 54 B0 04 8B 43 04  .......C..T...C.
0018FBAC: 00000001   00436DD0: 8D 04 B0 E8 A4 C6 FC FF 8B 43 04 89 3C B0 FF 43  .........C..<..C
0018FBA8: 00440AC0   00436DE0: 08 85 FF 74 0B 33 C9 8B D7 8B C3 8B 18 FF 53 04  ...t.3........S.
0018FBA4: 02742020   00436DF0: 5F 5E 5B C3 8B 50 08 4A E8 0F FF FF FF C3 8B C0  _^[..P.J........
0018FBA0: 0000527C  00436E00: 53 56 57 55 8B F1 8B FA 8B D8 3B F7 74 45 85 F6  SVWU......;.tE..
0018FB9C: 00436D2A  00436E10: 7C 05 3B 73 08 7C 0F 8B 15 44 41 6C 00 8B CE 8B |.;s.|...DAl....
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#2

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 19. Aug 2013, 17:58
Was machst Du denn im Execute des Threads ausserhalb der Synchronize-Aufrufe?
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 19. Aug 2013, 22:10
Was machst Du denn im Execute des Threads ausserhalb der Synchronize-Aufrufe?
Dadurch, dass ich leider auf eine Access-Datenbank über Netzlaufwerk über <2MBit VPN angewiesen bin, lade ich alle Datensätze über einen Thread direkt in Objekte. Die Objekte werden dann von den Main-Thread kopiert (neu erzeugen und .Assign)


Beispiel:
Laden der Daten aus Datenbank
Delphi-Quellcode:
  TProjekt = class(TLoadSaveItem)
  public
    txtProjektName: string;
    dtEndDatum: TDateTime;
    dtStartDatum: TDateTime;
    blAusblenden: Boolean;
    function Equals(_CompareTo: TProjekt): Boolean;
    procedure Assign(_Source: TPersistent); override;
    constructor Create(_Owner: TComponent); override;
  end;


            while (not q.Eof) and (not FblStop) and (ToDo = 0) do begin
              inc(intCounter);
// OutputDebugString(pchar('LoadSave.Laden.Projekte.Counter: ' + inttostr(intCounter)));

              tmpProjekt := TProjekt.Create(NIL);
              with tmpProjekt do begin
                ID := q.FieldByName('ID').AsInteger;
                dtEndDatum := floor(q.FieldByName('dtEndDatum').AsDateTime);
                dtStartDatum := floor(q.FieldByName('dtStartDatum').AsDateTime);
                txtProjektName := q.FieldByName('txtProjektName').AsString;
                blAusblenden := q.FieldByName('blAusblenden').AsBoolean;
                LastUpdate := CurrentTick;
              end;

              // Genau dieses Projekt in der Liste der bereits geladenen Projekte suchen
              blGefunden := False;
              for i := 0 to FclProjekte.Count - 1 do begin
                if FclProjekte.Items[i].InheritsFrom(TProjekt) then begin
                  ListenProjekt := TProjekt(FclProjekte.Items[i]);
                  // Projekt gefunden
                  if ListenProjekt.ID = tmpProjekt.ID then begin
                    ListenProjekt.Assign(tmpProjekt);
                    blGefunden := True;
                    Break;
                  end;
                end;
              end;

              if blGefunden then begin
                FreeAndNil(tmpProjekt);
              end else begin
                Synchronize(SyncNewDataset);
                FclProjekte.Add(tmpProjekt);
              end;

              q.Next;
              Synchronize(SyncSaveAndDelete); // damit auch beim Laden abgebrochen werden kann

              if (intCounter mod 10 = 0) then begin
                FProgressText := Format('%s von %s Projekten geladen', [IntToStr(intCounter), IntToStr(q.RecordCount)]);
                Synchronize(SyncProgress);
              end;
            end;

            q.Close;
            q.SQL.Clear;

            try
              i := 0;
              // Alle Einträge durchgehen
              while i < FclProjekte.Count do begin

                // Wenn Eintrag in der Liste nicht beim aktuellen Neu-Lade Zyklus mit dabei war
                tmpLS := TLoadSaveItem(FclProjekte.Items[i]);
                if tmpLS.LastUpdate <> CurrentTick then begin
                  FclProjekte.Delete(i);
                end else begin
                  inc(i);
                end;
              end;
            except end;

            Synchronize(SyncProjekte);
            FProgressText := Format('%s Projekte geladen', [IntToStr(intCounter)]);
            Synchronize(SyncProgress);
          end;
Und dann mit Synchronize die in Objekte aus der THREAD-Componentliste (FclProjekte) in die VCL (Main-Thread)-Componentenliste (clProjekte) kopieren mittels assign.

Sollte ja nix ausmachen, dass die clProjekte ein Objekt des Threads ist? Schließlich wird ja mit .Execute NIE direkt darauf zugegriffen...
Delphi-Quellcode:
{$Region 'procedure TLoadSaveThread.SyncProjekte;'}
procedure TLoadSaveThread.SyncProjekte;
var
  i, j: integer;
  blGeloescht, blGefunden: Boolean;
  tmpProjekt: TProjekt;
begin
  SyncStop;
  try
    if FblStop then Exit;
    if FclProjekte.Count = 0 then Exit;

    while clProjekte.Count > 0 do begin
      tmpProjekt := TProjekt(clProjekte.Extract(clProjekte.Items[0]));
      FreeAndNil(tmpProjekt);
    end;
    if FblStop then Exit;
  except end;

  {$Region 'Alle Projekte aus dem Thread durchgehen'}
  try
    for i := 0 to FclProjekte.Count - 1 do begin
      if TLoadSaveItem(FclProjekte.Items[i]).InheritsFrom(TProjekt) then begin
        tmpProjekt := TProjekt.Create(NIL);
        tmpProjekt.Assign(TProjekt(FclProjekte.Items[i]));

        // Wurde das aktuelle Projekt zwischenzeitlich gelöscht?
        blGeloescht := False;
        for j := 0 to FclDelete_Outbox.Count - 1 do begin
          if TLoadSaveItem(FclDelete_Outbox.Items[j]).InheritsFrom(TProjekt) then begin
            if TLoadSaveItem(FclDelete_Outbox.Items[j]).ID = tmpProjekt.ID then begin
              blGeloescht := True;
              Break;
            end;
          end;
        end;

        // Falls gelöscht, nicht in die VCL-Liste übernehmen
        if blGeloescht then begin
          FreeAndNil(tmpProjekt);
        end else begin
          // Falls nicht gelöscht, nachsehen
          // ob dieser Eintrag zwischenzeitlich bearbeitet und gespeichert wurde.
          // Dann diesen Wert bevorzugen, denn das Abspeichern in der Datenbank ist noch nicht beendet.

          j := 0;
          while j < FclSave_Outbox.Count do begin
            if TLoadSaveItem(FclSave_Outbox.Items[j]).InheritsFrom(TProjekt) then begin
              if TLoadSaveItem(FclSave_Outbox.Items[j]).ID = tmpProjekt.ID then begin
                // falls das Objekt aus dem Datenbankthread identisch ist mit dem, was gespeichert werden soll,
                // war das speichern und anschließende Neu-Laden wohl erfolgreich.
                if TProjekt(FclSave_Outbox.Items[j]).Equals(tmpProjekt) then begin
                  FclSave_Outbox.Delete(j);
                end else begin
                  // Abspeichern noch nicht beendet, deswegen Daten aus der Datenbank mit denen aus dem Zwischenspeicher ersetzen
                  tmpProjekt.Assign(FclSave_Outbox.Items[j]);
                  inc(j);
                end;
              end else inc(j);
            end else inc(j);
          end;

          clProjekte.Add(tmpProjekt);

        end;

      end; // inheritsfrom TProjekt
    end; // Alle Projekte
  except end;
  {$EndRegion 'Alle Projekte aus dem Thread durchgehen'}

  {$Region '"Zu speichernde" -also neue- Projekte laden'}
  try
    i := 0;
    while i < FclSave_Outbox.Count do begin

      // Ist das "zu speichernde" Projekt (in Save_Outbox) denn "schon" in clProjekte enthalten?
      blGefunden := False;
      for j := 0 to clProjekte.Count - 1 do begin
        if TLoadSaveItem(clProjekte.Items[j]).ClassType = TLoadSaveItem(FclSave_Outbox.Items[i]).ClassType then begin
          if TLoadSaveItem(clProjekte.Items[j]).ID = TLoadSaveItem(FclSave_Outbox.Items[i]).ID then begin
            blGefunden := True;
          end;
        end;
      end;

      // Falls noch nicht in clProjekte vorhanden
      if not blGefunden then begin
        if FclSave_Outbox.Items[i].InheritsFrom(TProjekt) then begin
          tmpProjekt := TProjekt.Create(NIL);
          tmpProjekt.Assign(TProjekt(FclSave_Outbox.Items[i]));
          clProjekte.Add(tmpProjekt);
        end;
      end;

      inc(i);
    end;
  except end;
  {$EndRegion '"Zu speichernde" -also neue- Projekte laden'}

  {$Region 'Wurde das zu löschende Projekt nicht mehr erneut aus der Datenbank geladen?'}
  try
    i := 0;
    // Liste der zu löschenden Objekte durchgehen
    while i < FclDelete_Outbox.Count do begin

      blGefunden := False;
      // vergleichen mit dem, was eben geladen wurde
      for j := 0 to FclProjekte.Count - 1 do begin
        if TLoadSaveItem(FclProjekte.Items[j]).ClassType = TLoadSaveItem(FclDelete_Outbox.Items[i]).ClassType then begin
          // Falls das zu löschende Objekt immer noch in der Liste gefunden wird, abbrechen
          if TLoadSaveItem(FclProjekte.Items[j]).ID = TLoadSaveItem(FclDelete_Outbox.Items[i]).ID then begin
            blGefunden := True;
            Break;
          end;
        end;
      end;

      // Wenn das zu löschende Objekt nicht mehr aus der Datenbank geladen wird, wurde es erfolgreich gelöscht
      if blGefunden then begin
        inc(i);
      end else begin
        // Nachverfolgung erfolgreich, da der zu löschende Datensatz nicht erneut aus der Datenbank geladen wurde!
        FclDelete_Outbox.Delete(i);
      end;
    end;
  except end;
  {$EndRegion 'Wurde das zu löschende Projekt nicht mehr erneut aus der Datenbank geladen?'}

end;
{$EndRegion}
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#4

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 19. Aug 2013, 22:40
Und Du bist sicher dass Deine Datenbank-Connection bzw. der dort verwendete Treiber Threadsafe ist? Da dann der Fehler nämlich in einer externen dll ausgelöst wird, ergibt sich auch kein ordentlicher Callstack.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 00:29
Über TAdoQuery und TAdoConnection via Ole/Jet auf eine .mdb Datei. Nicht das was eine professionelle Lösung ist, aber das, womit ich arbeiten muss. Außer in dem Thread selbst verwende ich die Ado-Komponenten nirgendwo, falls das irgendwas zur Sache tut...
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#6

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 01:35
Über TAdoQuery und TAdoConnection via Ole/Jet auf eine .mdb Datei. Nicht das was eine professionelle Lösung ist, aber das, womit ich arbeiten muss. Außer in dem Thread selbst verwende ich die Ado-Komponenten nirgendwo, falls das irgendwas zur Sache tut...
Womöglich liegt es gar nicht vordergründig an deinem Code oder an den Ado-Komponenten, sondern an einer instabilen Verbindung. Wenn du mal Google nach Verbindung+Netzlaufwerk+Switch+stabil fragst, kommst du der Sache vielleicht näher. Zumindest ich hatte ähnliche Probleme beim Einrichten einer Terminverwaltung für drei Arbeitsplätze ohne Datenbank-Server. Die Daten der drei Arbeits-PCs sollten eigentlich immer auf ein via Switch angeschlossenes Netzlaufwerk gespeichert werden. Daß die Verbindung zur Access-DB, die auf dem von allen dreien erreichbaren Netzlaufwerk lag, ständig abriß, zog jedesmal einen Programmabsturz nach sich. Nach dem Austausch des Switch-Controllers war die Verbindung stabil genug, um keine Programm-Abstürze mehr zu verzeichnen. Leider weiß ich heute nicht mehr, von welcher Marke alter und neuer Switch waren ...

Testen könntest du das außer mit Pings, indem du mal probierst, mit eingeschaltetem Cache zu arbeiten: Alle Daten werden erstmal lokal auf dem Rechner gespeichert, danach wird die Verbindung wieder getrennt. Und immer schön Try-Except-Blöcke verwenden, das vermindert die Absturzhäufigkeit im Fehlerfalle

Geändert von Perlsau (20. Aug 2013 um 01:43 Uhr)
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#7

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 07:47
Ich werfe auch noch kurz 3 Aspekte in die Runde...

Bei ADO/dbGo muss jeder Thread, der auf die DB zugreift eine eigene TADOConnection haben.
Sonst funktioniert das Connection Pooling nicht.

Jeder Thread der ADO nutzt muss sein eigenes CoInitialize aufrufen.

Je nach Anwendung würde ich abwägen, ob ich COM ggf. als MULTITHREADED initialisiere.
Das läuft oft runder, wenn dein Programm nicht auf OLE, Clipboard oder Shell Dialoge zugreift.
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#8

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 08:05
Ursächlich für diese obskuren Fehler ist der Programmierstil. Er verstößt so ziemlich gegen jedes Gebot der robusten Programmierung: Die Routinen sind zu lang, es werden etwaige auftretende Fehler mit leeren Except-Blöcken einfach unter den Tisch gekehrt (Motto: "Habe keine Ahnung, was hier passiert"). Es wird zwar die Möglichkeit eines Abbruchs kommentiert, aber nirgens umgesetzt (if terminated then exit )

Im Code sehe ich 'FclProjekte'. Sag nicht, das das eine Listbox ist. Wenn ja => garantierte Fehlerquelle. Verwende *nie niemals nicht* ein VCL-Control als Datenstruktur. die VCL-Controls dienen *nur* zum Darstellen von Daten.
Delphi-Quellcode:
 
if blGefunden then begin
  FreeAndNil(tmpProjekt);
end else begin
  Synchronize(SyncNewDataset); // <--- was wird denn hier synchronisiert?
  FclProjekte.Add(tmpProjekt);
end;
Weiterhin erzeugst Du erst ein TProjekt, füllst es, suchst dann in der Liste nach, ob es schon da ist, schmeisst es wieder weg, wenn ja usw.

Das Suchkriterium ist die ID. Verwende eine Dictionary / Hashmap, um zu prüfen, ob Du die ID schon geladen hast. Wenn ja, gehe zum nächsten Record. Nur wenn die ID noch nicht geladene wurde, instantiierst du ein TProjekt, füllst die Eigenschaften und übergibst das an dein Formular. Weniger Klimmzüge => weniger Fehlerquellen.

Unterteile deine Methode in einzelne Methoden, die genau eine Aufgabe erledigen. Verwende *nie niemals nicht* leere Except-Blöcke, sondern logge alle Exceptions.

Zum Eingrenzen des Fehlers:

1. Kommentiere alles aus. Läuft es? => Weiter mit 2.
2. Aktiviere nur die ADO-routinen, d.h. instantiiere dein TProjekt, fülle es, schmeiss es weg. Läuft es? Weiter mit 3.
3. Aktiviere die Listenlogik (nur, wenn es keine Listbox ist). D.h. suche in der Liste usw. Läuft es? Weiter mit 4.
4. Aktiviere die Synchronize-Methoden eines nach dem anderen.
5. Tja, Keine Ahnung, wenn du hier gelandet bist.

Geändert von Furtbichler (20. Aug 2013 um 08:08 Uhr)
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#9

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 09:27
Im Code sehe ich 'FclProjekte'. Sag nicht, das das eine Listbox ist. Wenn ja => garantierte Fehlerquelle. Verwende *nie niemals nicht* ein VCL-Control als Datenstruktur. die VCL-Controls dienen *nur* zum Darstellen von Daten.
Der Call Stack lässt dies als Ursache vermuten.
Insbesondere der Zugriff aus einem Thread auf eine VCL-Komponente ist ein sicherer Absturzkandidat.
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 09:35
Alle cl* Komponenten bei mit sind TComponentList. Von allen Datentypen aus der Datenbank jeweils eine, die NUR im Thread benutzt wird (Fcl*) und eine, die NUR außerhalb des Threads benutzt wird (cl*). Bei SyncNewDataset beispielsweise werden alle neu hinzugekommenen Einträge über Synchronize von Fcl* an cl* Übergeben.

Im Thread verwende ich keine VCL-Komponenten, ADO wurde mit CoInitialize etc. entsprechend vorbereitet.

Nochmal: Das komplette Programm läuft zuverlässig und einwandfrei. Das einzige was "stört" ist die Exception-Meldung ansich. Deshalb die leeren try..except Blöcke rund um allen Quelltext, den ich für den Bösewicht halte. Trotzdem kommt die Meldung weiterhin.

Wie kann ich denn von der Pointer-Adresse aus dem Fehlerlogbuch auf einen Variablennamen (z.B. FclProjekte) kommen, um zumindestens die schuldige Komponente benennen zu können? Ich sehe zwar, dass irgend eine Liste Probleme macht. Aber welche??

Danke schonmal für die Antworten. Ich hoffe wir finden was.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz