Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Unerklärbare Zugriffsverletzung (https://www.delphipraxis.net/179588-unerklaerbare-zugriffsverletzung.html)

jaenicke 18. Mär 2014 22:24

AW: Unerklärbare Zugriffsverletzung
 
Zitat:

Zitat von ByTheTime (Beitrag 1252430)
Ich glaube ich mache ein Debug Projekt, das ist nicht so viel Code, da mach ich mir die "Mühe" :)

Wie schon erwähnt wurde reicht es auch, wenn du Delphi mit Adminrechten startest. Dann kannst du dich einfach mit dem Dienst verbinden...

Wenn es direkt beim Starten passiert, kannst du folgendes nutzen, damit der Dienst wartet bis du den Debugger verbunden hast:
Delphi-Quellcode:
while not IsDebuggerPresent do
  Sleep(100);
Und danach direkt einen Haltepunkt setzen z.B.

ByTheTime 18. Mär 2014 22:36

AW: Unerklärbare Zugriffsverletzung
 
@Sir_Rufo: Okay, habe mir gedacht das er darauf hinauswill. Merke ich mir für die Zukunft...
@jaenicke: Ja stimmt... Habe ich irgendwie dran vorbei gedacht... Und danke für den Tipp mit dem "IsDebuggerPresent" :thumb:

Noch eine Anmerkung: Eben beim experimentieren ist mir folgendes aufgefallen (man betrachte die for-Schleife welche für das Senden verantwortlich ist):
Delphi-Quellcode:
            for i := 0 to High(Jobs) do
            begin
              { ... }

              if EventCount > 0 then
              begin
                Log(False, 'All Events: ' + IntToStr(Length(Events))); // Geht! 

                SendMail(i);
              end;
            end;
Und hier die "andere" Version;

Delphi-Quellcode:
            for i := 0 to High(Jobs) do
            begin
              { ... }

              if EventCount > 0 then
              begin
                Log(False, IntToStr(Length(Events))); // GEHT NICHT!!! 

                SendMail(i);
              end;
            end;
Ich debug mich da jetzt durch und dann bin ich mal gespannt, was da genau passiert :twisted: Denn der Code von oben hat mich nur nochmehr verwirrt :(

ByTheTime 18. Mär 2014 23:23

AW: Unerklärbare Zugriffsverletzung
 
Achso, hier nochmal meine Profi Log-Funktion :)

Delphi-Quellcode:
procedure Log(ShowDateTime: Boolean; s: String);
var
  LList: TStringList;
  i: Integer;
begin
  FLogCritSect.Enter;

  try
    LList := TStringList.Create;

    if not IsFileInUse(AppDataPath + 'Jobs.jlf') then
    begin
      try
        if FileExists(AppDataPath + 'Log.txt') then
          LList.LoadFromFile(AppDataPath + 'Log.txt');

        for i := 0 to Puffer.Count - 1 do
          LList.Add(Puffer[i]);

        if ShowDateTime then
          LList.Add('[' + DateTimeToStr(Now) + ']: ' + s)
        else
          LList.Add(s);

        LList.SaveToFile(AppDataPath + 'Log.txt');
      finally
        LList.Free;
        Puffer.Text := EmptyStr;
      end;
    end
    else if ShowDateTime then
      Puffer.Add('[' + DateTimeToStr(Now) + ']: ' + s)
    else
      Puffer.Add(s);
  finally
    FLogCritSect.Leave;
  end;
end;
Wenn man in der SendMail-Prozedur eine Zeile hinzufügt funktioniert alles:
Delphi-Quellcode:
{ ... }

Log(False, ''); // Löst alle Probleme

for i := 0 to High(Events) do
  if Events[i].Mail = Jobs[JobID].Mail then
  begin
    { ... }
  end;

{ ... }
Allerdings soll das nicht die Lösung sein... Ich melde mich nochmal! :)

Gruß

himitsu 18. Mär 2014 23:55

AW: Unerklärbare Zugriffsverletzung
 
Zitat:

Delphi-Quellcode:
    LList := TStringList.Create;
    if not IsFileInUse(AppDataPath + 'Jobs.jlf') then
    begin
      try
        ...
      finally
        LList.Free;
        ...
      end;
    end;

Was wohl passiert, wenn die Datei "in use" ist. :roll:

Delphi-Quellcode:
    if not IsFileInUse(AppDataPath + 'Jobs.jlf') then
    begin
      LList := TStringList.Create;
      try
        ...
PS:
Delphi-Quellcode:
        //for i := 0 to Puffer.Count - 1 do
        //  LList.Add(Puffer[i]);
        LList.AddStrings(Puffer);

        //Puffer.Text := EmptyStr;
        Puffer.Clear;
Aber ich würde da eher zu AssignFile+Append+WriteLn raten, oder zumindestens einem FileStream, welcher die Daten direkt anhängt, da muß nicht ständig die ganze Logdatei jedes Mal neu eingelesen werden, sondern man hängt nur die neuen Zeilen an.
Du willst lieber nicht wissen, was seit D2009 beim Laden oder Speichern einer TStringList passiert. (z.B. bis über das 5-Fache des Speicherverbrauchs der Dateigröße)

Blup 19. Mär 2014 10:25

AW: Unerklärbare Zugriffsverletzung
 
Zitat:

Zitat von ByTheTime (Beitrag 1252421)
Also es gibt 3 Threads, den ServiceThread, welcher ja immer aktiv ist, jedoch bei mir keine relevanten Aufgaben hat. Dann gibt es noch einen Überwachungs-Thread, welcher auf Events wartet und diese bearbeitet, und den Mail-Thread. Dieser bekommt von dem Überwachungs-Thread immer die Events zugeschoben. Allerdings ist hier alles schön synchronisiert und ich hatte hier noch nie Probleme. Jobs und Events sind je 2 Arrays. Allerdings nicht ineinander verschachtelt. Sie dienen eigentlich nur zum speichern von den Aufträgen und eben den Ergenissen/Events

Der Überwachungs-Thread fügt neue Elemente dem Array Events hinzu. ("schön sychronisiert" sollte bedeuten, er tut das innerhalb einer Criticalsection.)
Der Mail-Thread liest die Elemente aus Events und löscht diese sogar. ("schön sychronisiert" sollte bedeuten, er tut das ebenfalls innerhalb der selben Criticalsection.)
Ich habe keine einzige Zeile in dieser Hinsicht gesehen.
Hoffentlich bedeuted das, der gesamte Code läuft innerhalb der Criticalsection...

ByTheTime 19. Mär 2014 16:12

AW: Unerklärbare Zugriffsverletzung
 
@himitsu: Oh :lol: Danke für den Hinweiß. Das ist ein altes Projekt von mir, was ich etwas umgestellt habe. Hat immer gut funktioniert und mir ist der Fehler nie aufgefallen :roll:
Ja, man könnte es auch mit AssignFile+Append+WriteLn... War einfach zufaul das mal in Angriff zu nehmen :mrgreen:

@Blup: Habe nur das wichtigste gezeigt. Es läuft alles in CriticalSections :thumb:

Und ich habe erste Ergebnisse beim Debugging (hatte erst heute Mittag Zeit - jaja, das Schüler sein :roll:):

Delphi-Quellcode:
procedure TMailThread.SendMail(JobID: Integer);
var
  i: Integer;
  MMail: TStringList;
  ID: String;
begin
  { ... }

  Log(False, ''); { Wenn diese Zeile "aktive" ist, läuft alles reibungslos. Ist die Zeile nicht gesetzt, kommt in der unten makierten Zeile ein Fehler beim 2. Durchlauf (6. Durchlauf der for-Schleife, 2. Durchlauf der SendMail-Prozedur ;) ) }

  for i := 0 to High(Events) do
    if Events[i].Mail = Jobs[JobID].Mail then
    begin
      MMail.Add('---');
      MMail.Add(Events[i].Course + ' | ' + Events[i].Span + ' | ' +
        Events[i].Status + ' | ' + Events[i].Date + ' | ' + Events[i].Note); // Fehler hier!
      MMail.Add('---');
      MMail.Add('');
    end;

  { ... }
end;
Ich könnte mir vorstellen, warum der Fehler auftritt. Das letzte Event (i=5) hat für das Feld "Status" nur Matsch im Wert. Aber ich weiß noch nicht, wo der herkommt :glaskugel: Aufjedenfall eine sehr lange Zeichenkette. Vllt. haut es deshalb nicht hin. Aber warum sollte die eine Log-Zeile das Problem lösen? :glaskugel:

ByTheTime 19. Mär 2014 17:17

AW: Unerklärbare Zugriffsverletzung
 
Okay, also das Problem ist ziemlich merkwürdig.

Das ist der Anfang der SendMail-Prozedur:
Delphi-Quellcode:
procedure TMailThread.SendMail(JobID: Integer);
var
  i: Integer;
  MMail: TStringList;
  ID: String;
begin
  MMail := TStringList.Create;

  MMail.Add('Es wurden ' + IntToStr(EventCount) + ' Meldungen für den Auftrag "'
    + Jobs[JobID].Mail + '" gefunden:'); // Hier! 1.
  MMail.Add('');

  MMail.Add('------------------------------------------------------------');
  MMail.Add('Kurs | Zeitraum (Schulstd.) | Art | Tag, Datum | Bemerkung');
  MMail.Add('------------------------------------------------------------');
  MMail.Add('');

  // Log(False, ''); // Test!

  for i := 0 to High(Events) do
    if Events[i].Mail = Jobs[JobID].Mail then
    begin
      MMail.Add('---'); // Hier! 2.
      MMail.Add(Events[i].Course + ' | ' + Events[i].Span + ' | ' +
        Events[i].Status + ' | ' + Events[i].Date + ' | ' + Events[i].Note);
      MMail.Add('---');
      MMail.Add('');
    end;
Ich kann mir nicht erklären warum, allerdings wird beim Aufrufen der makierten Zeilen der Text "zermatscht". Beim Aufruf der ersten markierten Zeile wird im Event-Array der letze/höchste Eintrag, in meinem Fall Events[5], im Elemten "Status" verändert. Dort steht z.B. 'Entfall' *. Nach dem aufrufen der ersten markierten Zeile steht dort soetwas wie '#0#0#0#0#0#0#0#0#0#0#0#3#465###0#0#0#0#0#5###5### #y###9#0#0#' mit ~300+ Zeichen. Beim Aufruf der zweiten markiertn Zeile wird in einem anderen Eintrag (Events[2]) ein Element mit dem Namen "Course" im Wert geändert. Statt 'Sport2' steht dort jetzt '---'. Wo das '---' herkommt ist ja offensichtlich, aber warum verstehe ich nicht... Das ergibt einfach keinen Sinn...

Wenn ich die Log Zeile übrigens einbinde, werden die besagten Einträge (Events[6] + Events[2]) erst geleert, und beim ersten Durchlauf der darauffolgenden Schleife wieder gefüllt, allerdings mit völligem Käse. Statt dem Zeichensalat steht dann dort 'C:\ProgramData\', das ist der Pfad, unter welchem auch das Log gespeichert wird (es folgt noch ein Unterordner). Also irgendetwas wird hier ganz gewaltig durcheinandergeworfen.

Ich habe leider garkeine Vermutung, was das Problem sein könnte :cry:

Gruß

*Wie man unschwer erkennen kann, arbeite ich an einem Programm, was den Vertretungsplan unserer Schule herrunterläd und per Mail verschickt. Man kann seine Kurse und seine Mail in eine Liste eintragen, das Programm Filtert dann den Vertretungsplan und schickt einen individuell angepassten Report. Das hat bisher immer Fehlerfrei geklappt. Der Fehler ist mir jetzt erst untergekommen, als ich versucht habe, mehrere Jobs anzulegen (Also für mehrere Schüler; In meinem Fall warne es 2 Jobs/Schüler, da hat es schon gekracht).

ByTheTime 19. Mär 2014 23:40

AW: Unerklärbare Zugriffsverletzung
 
Okay, ich habe jetzt den ganzen Tag nichts anderes gemacht... Ich habe alles auf den Kopf gestellt, den EventThread rausgenommen und, und, und... Aber ich finde den Fehler nicht! :wall: :evil: :cry:

Ich weiß nur, dass - aus welchen Gründen auch immer - das EventArray urplötzlich verändert wird. Ich habe aus der Anwendung sogar eine Single-Thread Anwendung gemacht und trotzdem tritt dieser komsiche Fehler auf.
Vllt. hat ja jemand einen Geistesblitz, aber im Moment sieht es übel aus :/

himitsu 20. Mär 2014 01:45

AW: Unerklärbare Zugriffsverletzung
 
Eine TStringList selber ist eigentlich sehr robust und fehlerunanfällig.

Wenn da was kapput geht, dann liegt das fast immer an jemand Anderem.
- nicht threadsichere Zugriffe (würde ich hier ausschließen, da ja nur in dem einem Thread drauf zugegriffen wird)
- Buffer-Overflows, welche die Daten der Stringliste überschreiben und dabei zerstören


Oder die StringListe ist eigentlich ganz, aber der Debugger zeigt einfach nur Mist an, weil er z.B. diese Klasse/Variablen nicht richtig auflöst.
Aber dieses läßt sich prüfen, indem man den Inhalt der Stringliste z.B. loggt, oder in öfters mal in eine Debug-Datei ausgiebt, welche man sich während der Haltepunkte ansieht, oder mehrere fortlaufende Dateien, wo man sich nachher ansieht, ob und ab wann es kaputt ging.

jaenicke 20. Mär 2014 06:06

AW: Unerklärbare Zugriffsverletzung
 
Du könntest einmal FastMM einbinden, vielleicht findet das ja etwas, wenn du den FullDebugMode in der mitgelieferten Include-Datei aktivierst.

Wie wäre es denn, wenn du das Programm einfach einmal komplett anhängst, bzw. ein Projekt, das den Teil mit dem Fehler enthält?
Wenn das jemand selbst ausprobieren und debuggen kann, wird der Fehler sicher schnell gefunden. ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:48 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz